001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Mananagement System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com) 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * For further information about Alkacon Software GmbH & Co. KG, please see the 018 * company website: http://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: http://www.opencms.org 022 * 023 * You should have received a copy of the GNU Lesser General Public 024 * License along with this library; if not, write to the Free Software 025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 026 */ 027 028package org.opencms.workplace.editors; 029 030import org.opencms.file.CmsFile; 031import org.opencms.file.CmsObject; 032import org.opencms.file.CmsResourceFilter; 033import org.opencms.i18n.CmsLocaleManager; 034import org.opencms.jsp.CmsJspActionElement; 035import org.opencms.main.CmsException; 036import org.opencms.main.CmsLog; 037import org.opencms.main.OpenCms; 038import org.opencms.util.CmsUUID; 039import org.opencms.workplace.CmsDialog; 040import org.opencms.workplace.CmsWorkplaceSettings; 041import org.opencms.xml.content.CmsXmlContent; 042import org.opencms.xml.content.CmsXmlContentFactory; 043 044import java.io.UnsupportedEncodingException; 045import java.util.ArrayList; 046import java.util.HashSet; 047import java.util.Iterator; 048import java.util.List; 049import java.util.Locale; 050import java.util.Set; 051 052import javax.servlet.http.HttpServletRequest; 053import javax.servlet.http.HttpServletResponse; 054import javax.servlet.jsp.JspException; 055import javax.servlet.jsp.PageContext; 056 057import org.apache.commons.logging.Log; 058 059/** 060 * Provides methods for the editor copy language dialog.<p> 061 * 062 * The following files use this class: 063 * <ul> 064 * <li>/jsp/editors/dialogs/copylanguage.html 065 * </ul> 066 * <p> 067 * 068 * @since 6.5.6 069 */ 070public class CmsDialogCopyLanguage extends CmsDialog { 071 072 /** Value for the action: update languages of the page. */ 073 public static final int ACTION_UPDATE_LANGUAGES = 310; 074 075 /** The dialog type. */ 076 public static final String DIALOG_TYPE = "copylanguages"; 077 078 /** Request parameter value for the action: update the elements of the page. */ 079 public static final String DIALOG_UPDATE_LANGUAGES = "updatelanguages"; 080 081 /** Param name for the html checkbox field for the language. */ 082 public static final String PARAM_LANGUAGE = "language"; 083 084 /** The log object for this class. */ 085 private static final Log LOG = CmsLog.getLog(CmsDialogCopyLanguage.class); 086 087 /** The element locale. */ 088 private Locale m_elementLocale; 089 090 /** Element language parameter. */ 091 private String m_paramElementlanguage; 092 093 /** The selected languages. */ 094 private Set<String> m_paramSelectedLanguages; 095 096 /** Temporary file parameter. */ 097 private String m_paramTempFile; 098 099 /** 100 * Public constructor.<p> 101 * 102 * @param jsp an initialized JSP action element 103 */ 104 public CmsDialogCopyLanguage(CmsJspActionElement jsp) { 105 106 super(jsp); 107 } 108 109 /** 110 * Public constructor with JSP variables.<p> 111 * 112 * @param context the JSP page context 113 * @param req the JSP request 114 * @param res the JSP response 115 */ 116 public CmsDialogCopyLanguage(PageContext context, HttpServletRequest req, HttpServletResponse res) { 117 118 this(new CmsJspActionElement(context, req, res)); 119 } 120 121 /** 122 * Updates the languages of the current xmlcontent by copying from the current language.<p> 123 * 124 * @throws JspException if there is an error including the error page 125 */ 126 public void actionUpdateLanguages() throws JspException { 127 128 if ((m_paramSelectedLanguages != null) && !m_paramSelectedLanguages.isEmpty()) { 129 try { 130 CmsFile file = getCms().readFile(getParamTempfile(), CmsResourceFilter.IGNORE_EXPIRATION); 131 CmsXmlContent content = CmsXmlContentFactory.unmarshal(getCms(), file); 132 133 List<Locale> toLocales = new ArrayList<Locale>(); 134 for (Iterator<String> i = m_paramSelectedLanguages.iterator(); i.hasNext();) { 135 String language = i.next(); 136 toLocales.add(CmsLocaleManager.getLocale(language)); 137 } 138 139 // now transfer the contents 140 transferContents(content, getElementLocale(), toLocales); 141 142 // write the temporary file 143 String decodedContent = content.toString(); 144 try { 145 file.setContents(decodedContent.getBytes(content.getEncoding())); 146 } catch (UnsupportedEncodingException e) { 147 throw new CmsException( 148 Messages.get().container(Messages.ERR_INVALID_CONTENT_ENC_1, getParamResource()), 149 e); 150 } 151 // the file content might have been modified during the write operation 152 CmsObject cloneCms = OpenCms.initCmsObject(getCms()); 153 CmsUUID tempProjectId = OpenCms.getWorkplaceManager().getTempFileProjectId(); 154 cloneCms.getRequestContext().setCurrentProject(getCms().readProject(tempProjectId)); 155 cloneCms.writeFile(file); 156 157 } catch (Throwable e) { 158 // show error dialog 159 setParamMessage(Messages.get().getBundle(getLocale()).key(Messages.ERR_UPDATE_LANGUAGES_0)); 160 includeErrorpage(this, e); 161 } 162 } 163 } 164 165 /** 166 * Builds the html String for a form list of all possible page elements.<p> 167 * 168 * @return the html String for a form list 169 */ 170 public String buildLanguageList() { 171 172 try { 173 StringBuffer retValue = new StringBuffer(512); 174 retValue.append("<table border=\"0\">\n"); 175 176 // get locale for current element 177 Locale elLocale = getElementLocale(); 178 179 // get locale names based on properties and global settings 180 List<Locale> localeList = OpenCms.getLocaleManager().getAvailableLocales(getCms(), getParamTempfile()); 181 182 // read xml content for checking locale availability 183 CmsFile file = getCms().readFile(getParamTempfile(), CmsResourceFilter.IGNORE_EXPIRATION); 184 CmsXmlContent content = CmsXmlContentFactory.unmarshal(getCms(), file); 185 186 // show all possible elements 187 Iterator<Locale> i = localeList.iterator(); 188 while (i.hasNext()) { 189 // get the current list element 190 Locale curLocale = i.next(); 191 192 // skip locale of current element 193 if (elLocale.equals(curLocale)) { 194 continue; 195 } 196 197 // build an element row 198 retValue.append("<tr>\n"); 199 retValue.append("\t<td class=\"textcenter\" unselectable=\"on\"><input type=\"checkbox\" name=\""); 200 retValue.append(PARAM_LANGUAGE); 201 retValue.append("\" value=\""); 202 retValue.append(curLocale.toString()); 203 retValue.append("\">"); 204 retValue.append("</td>\n"); 205 retValue.append("\t<td style=\"white-space: nowrap;\" unselectable=\"on\">"); 206 retValue.append(curLocale.getDisplayName(getLocale())); 207 retValue.append(!content.hasLocale(curLocale) ? " [-]" : ""); 208 retValue.append("</td>\n"); 209 retValue.append("\t<td style=\"white-space: nowrap;\" unselectable=\"on\">"); 210 retValue.append( 211 !content.hasLocale(curLocale) 212 ? Messages.get().getBundle(getLocale()).key(Messages.GUI_EDITOR_DIALOG_COPYLANGUAGE_NEW_0) 213 : ""); 214 retValue.append("</td>\n"); 215 216 retValue.append("</tr>\n"); 217 } 218 219 retValue.append("</table>\n"); 220 return retValue.toString(); 221 222 } catch (Throwable e) { 223 // should usually never happen 224 if (LOG.isInfoEnabled()) { 225 LOG.info(e.getLocalizedMessage(), e); 226 } 227 return ""; 228 } 229 } 230 231 /** 232 * Returns the current element locale.<p> 233 * 234 * @return the current element locale 235 */ 236 public Locale getElementLocale() { 237 238 if (m_elementLocale == null) { 239 m_elementLocale = CmsLocaleManager.getLocale(getParamElementLanguage()); 240 } 241 return m_elementLocale; 242 } 243 244 /** 245 * Returns the current element language.<p> 246 * 247 * @return the current element language 248 */ 249 public String getParamElementLanguage() { 250 251 return m_paramElementlanguage; 252 } 253 254 /** 255 * Returns the name of the temporary file.<p> 256 * 257 * @return the name of the temporary file 258 */ 259 public String getParamTempfile() { 260 261 return m_paramTempFile; 262 } 263 264 /** 265 * Sets the current language.<p> 266 * 267 * @param elementLanguage the current element language 268 */ 269 public void setParamElementLanguage(String elementLanguage) { 270 271 m_paramElementlanguage = elementLanguage; 272 } 273 274 /** 275 * Sets the list of selected languages.<p> 276 * 277 * @param language a selected language 278 */ 279 public void setParamLanguage(String language) { 280 281 if (language != null) { 282 if (m_paramSelectedLanguages == null) { 283 m_paramSelectedLanguages = new HashSet<String>(); 284 } 285 // add all available values here 286 String[] values = getParameterMap().get(PARAM_LANGUAGE); 287 for (int i = 0; i < values.length; i++) { 288 m_paramSelectedLanguages.add(decodeParamValue(PARAM_LANGUAGE, values[i])); 289 } 290 } 291 } 292 293 /** 294 * Sets the name of the temporary file.<p> 295 * 296 * @param fileName the name of the temporary file 297 */ 298 public void setParamTempfile(String fileName) { 299 300 m_paramTempFile = fileName; 301 } 302 303 /** 304 * @see org.opencms.workplace.CmsWorkplace#initWorkplaceRequestValues(org.opencms.workplace.CmsWorkplaceSettings, javax.servlet.http.HttpServletRequest) 305 */ 306 @Override 307 protected void initWorkplaceRequestValues(CmsWorkplaceSettings settings, HttpServletRequest request) { 308 309 // fill the parameter values in the get/set methods 310 fillParamValues(request); 311 // set the dialog type 312 setParamDialogtype(DIALOG_TYPE); 313 // set the action for the JSP switch 314 if (DIALOG_UPDATE_LANGUAGES.equals(getParamAction())) { 315 setAction(ACTION_UPDATE_LANGUAGES); 316 } else { 317 setAction(ACTION_DEFAULT); 318 // build title for delete dialog 319 setParamTitle(key(Messages.GUI_EDITOR_DIALOG_COPYLANGUAGE_TITLE_0)); 320 } 321 } 322 323 /** 324 * Copies the contents from a source locale to a number of destination locales by overwriting them.<p> 325 * 326 * @param content the xml content 327 * @param sourceLocale the source locale 328 * @param destLocales a list of destination locales 329 * @throws CmsException if something goes wrong 330 */ 331 protected void transferContents(CmsXmlContent content, Locale sourceLocale, List<Locale> destLocales) 332 throws CmsException { 333 334 for (Iterator<Locale> i = destLocales.iterator(); i.hasNext();) { 335 Locale to = i.next(); 336 if (content.hasLocale(to)) { 337 content.removeLocale(to); 338 } 339 content.copyLocale(sourceLocale, to); 340 } 341 } 342}