001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management 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.xml.types; 029 030import org.opencms.file.CmsObject; 031import org.opencms.i18n.CmsEncoder; 032import org.opencms.loader.CmsImageScaler; 033import org.opencms.main.CmsIllegalArgumentException; 034import org.opencms.util.CmsRequestUtil; 035import org.opencms.util.CmsStringUtil; 036import org.opencms.xml.I_CmsXmlDocument; 037 038import java.util.HashMap; 039import java.util.Locale; 040import java.util.Map; 041 042import org.dom4j.Element; 043 044/** 045 * Describes the XML content type "OpenCmsVfsImage".<p> 046 * 047 * This type allows links to internal VFS images only.<p> 048 * 049 * @since 7.5.0 050 */ 051public class CmsXmlVfsImageValue extends CmsXmlVfsFileValue { 052 053 /** Node name for the scale element. */ 054 public static final String NODE_SCALE = "scale"; 055 056 /** Request parameter name for the description parameter. */ 057 public static final String PARAM_DESCRIPTION = "description"; 058 059 /** Request parameter name for the format parameter. */ 060 public static final String PARAM_FORMAT = "format"; 061 062 /** The name of this type as used in the XML schema. */ 063 public static final String TYPE_NAME_IMAGE = "OpenCmsVfsImage"; 064 065 /** The schema definition String is located in a text for easier editing. */ 066 private static String m_schemaDefinition; 067 068 /** The description text of the image. */ 069 private String m_description; 070 071 /** The selected image format. */ 072 private String m_format; 073 074 /** Holds the parameters of the URL. */ 075 private Map<String, String[]> m_parameters; 076 077 /** The scale options of the image. */ 078 private String m_scaleOptions; 079 080 /** 081 * Creates a new, empty schema type descriptor of type "OpenCmsVfsImage".<p> 082 */ 083 public CmsXmlVfsImageValue() { 084 085 // empty constructor is required for class registration 086 } 087 088 /** 089 * Creates a new XML content value of type "OpenCmsVfsImage".<p> 090 * 091 * @param document the XML content instance this value belongs to 092 * @param element the XML element that contains this value 093 * @param locale the locale this value is created for 094 * @param type the type instance to create the value for 095 */ 096 public CmsXmlVfsImageValue(I_CmsXmlDocument document, Element element, Locale locale, I_CmsXmlSchemaType type) { 097 098 super(document, element, locale, type); 099 } 100 101 /** 102 * Creates a new schema type descriptor for the type "OpenCmsVfsImage".<p> 103 * 104 * @param name the name of the XML node containing the value according to the XML schema 105 * @param minOccurs minimum number of occurrences of this type according to the XML schema 106 * @param maxOccurs maximum number of occurrences of this type according to the XML schema 107 */ 108 public CmsXmlVfsImageValue(String name, String minOccurs, String maxOccurs) { 109 110 super(name, minOccurs, maxOccurs); 111 } 112 113 /** 114 * @see org.opencms.xml.types.A_CmsXmlContentValue#createValue(I_CmsXmlDocument, org.dom4j.Element, Locale) 115 */ 116 @Override 117 public I_CmsXmlContentValue createValue(I_CmsXmlDocument document, Element element, Locale locale) { 118 119 return new CmsXmlVfsImageValue(document, element, locale, this); 120 } 121 122 /** 123 * Returns the description of the image.<p> 124 * 125 * @param cms the current users context 126 * @return the description of the image or an empty String 127 */ 128 public String getDescription(CmsObject cms) { 129 130 if (m_description == null) { 131 if (m_element.element(PARAM_DESCRIPTION) != null) { 132 m_description = m_element.element(PARAM_DESCRIPTION).getText(); 133 } 134 if (CmsStringUtil.isEmptyOrWhitespaceOnly(m_description)) { 135 m_description = getParameterValue(cms, PARAM_DESCRIPTION); 136 m_description = CmsEncoder.unescape(m_description, CmsEncoder.ENCODING_UTF_8); 137 } 138 } 139 return m_description; 140 } 141 142 /** 143 * Returns the format information of the image.<p> 144 * 145 * @param cms the current users context 146 * @return the format information of the image or an empty String 147 */ 148 public String getFormat(CmsObject cms) { 149 150 if (m_format == null) { 151 if (m_element.element(PARAM_FORMAT) != null) { 152 m_format = m_element.element(PARAM_FORMAT).getText(); 153 } 154 if (CmsStringUtil.isEmptyOrWhitespaceOnly(m_format)) { 155 m_format = getParameterValue(cms, PARAM_FORMAT); 156 } 157 } 158 return m_format; 159 } 160 161 /** 162 * Returns the link without parameters from the string value.<p> 163 * 164 * @param cms the current users context 165 * @return the link without parameters 166 */ 167 public String getRequestLink(CmsObject cms) { 168 169 return CmsRequestUtil.getRequestLink(getStringValue(cms)); 170 } 171 172 /** 173 * Returns the scale options of the image.<p> 174 * 175 * @param cms the current users context 176 * @return the scale options of the image or an empty String 177 */ 178 public String getScaleOptions(CmsObject cms) { 179 180 if (m_scaleOptions == null) { 181 if (m_element.element(NODE_SCALE) != null) { 182 m_scaleOptions = m_element.element(NODE_SCALE).getText(); 183 } 184 if (CmsStringUtil.isEmptyOrWhitespaceOnly(m_scaleOptions)) { 185 m_scaleOptions = getParameterValue(cms, CmsImageScaler.PARAM_SCALE); 186 } 187 } 188 return m_scaleOptions; 189 } 190 191 /** 192 * @see org.opencms.xml.types.I_CmsXmlSchemaType#getSchemaDefinition() 193 */ 194 @Override 195 public String getSchemaDefinition() { 196 197 // the schema definition is located in a separate file for easier editing 198 if (m_schemaDefinition == null) { 199 m_schemaDefinition = readSchemaDefinition("org/opencms/xml/types/XmlVfsImageValue.xsd"); 200 } 201 return m_schemaDefinition; 202 } 203 204 /** 205 * @see org.opencms.xml.types.A_CmsXmlContentValue#getTypeName() 206 */ 207 @Override 208 public String getTypeName() { 209 210 return TYPE_NAME_IMAGE; 211 } 212 213 /** 214 * @see org.opencms.xml.types.A_CmsXmlContentValue#newInstance(java.lang.String, java.lang.String, java.lang.String) 215 */ 216 @Override 217 public I_CmsXmlSchemaType newInstance(String name, String minOccurs, String maxOccurs) { 218 219 return new CmsXmlVfsImageValue(name, minOccurs, maxOccurs); 220 } 221 222 /** 223 * Sets the description of the image.<p> 224 * 225 * @param cms the current users context 226 * @param description the description of the image 227 */ 228 public void setDescription(CmsObject cms, String description) { 229 230 if (CmsStringUtil.isEmptyOrWhitespaceOnly(description)) { 231 m_description = ""; 232 if (m_element.element(PARAM_DESCRIPTION) != null) { 233 m_element.remove(m_element.element(PARAM_DESCRIPTION)); 234 } 235 } else { 236 m_description = description; 237 description = CmsEncoder.escapeWBlanks(description, CmsEncoder.ENCODING_UTF_8); 238 } 239 setParameterValue(cms, PARAM_DESCRIPTION, description); 240 } 241 242 /** 243 * Sets the format information of the image.<p> 244 * 245 * @param cms the current users contexts 246 * @param format the format information of the image 247 */ 248 public void setFormat(CmsObject cms, String format) { 249 250 if (CmsStringUtil.isEmptyOrWhitespaceOnly(format)) { 251 m_format = ""; 252 if (m_element.element(PARAM_FORMAT) != null) { 253 m_element.remove(m_element.element(PARAM_FORMAT)); 254 } 255 } else { 256 m_format = format; 257 } 258 setParameterValue(cms, PARAM_FORMAT, format); 259 } 260 261 /** 262 * Sets the scale options of the image.<p> 263 * 264 * @param cms the current users context 265 * @param scaleOptions the scale options of the image 266 */ 267 public void setScaleOptions(CmsObject cms, String scaleOptions) { 268 269 if (CmsStringUtil.isEmptyOrWhitespaceOnly(scaleOptions)) { 270 m_scaleOptions = ""; 271 if (m_element.element(NODE_SCALE) != null) { 272 m_element.remove(m_element.element(NODE_SCALE)); 273 } 274 } else { 275 m_scaleOptions = scaleOptions; 276 } 277 setParameterValue(cms, CmsImageScaler.PARAM_SCALE, scaleOptions); 278 } 279 280 /** 281 * @see org.opencms.xml.types.A_CmsXmlContentValue#setStringValue(org.opencms.file.CmsObject, java.lang.String) 282 */ 283 @Override 284 public void setStringValue(CmsObject cms, String value) throws CmsIllegalArgumentException { 285 286 // call the super implementation to set the value 287 super.setStringValue(cms, value); 288 if (CmsStringUtil.isEmptyOrWhitespaceOnly(value)) { 289 // no valid value given 290 return; 291 } 292 293 // get the request parameters from the provided value 294 Map<String, String[]> params = getParameterMap(value); 295 296 // create description element if present as parameter 297 String desc = getParameterValue(cms, params, PARAM_DESCRIPTION); 298 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(desc)) { 299 desc = CmsEncoder.unescape(desc, CmsEncoder.ENCODING_UTF_8); 300 m_element.addElement(PARAM_DESCRIPTION).addCDATA(desc); 301 } 302 // create format name element if present as parameter 303 String format = getParameterValue(cms, params, PARAM_FORMAT); 304 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(format)) { 305 m_element.addElement(PARAM_FORMAT).addCDATA(format); 306 } 307 // create scale element if present as parameter 308 String scale = getParameterValue(cms, params, CmsImageScaler.PARAM_SCALE); 309 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(scale)) { 310 m_element.addElement(NODE_SCALE).addCDATA(scale); 311 } 312 // reset the parameter map 313 m_parameters = null; 314 // reset the members containing the element values 315 m_format = null; 316 m_description = null; 317 m_scaleOptions = null; 318 } 319 320 /** 321 * Returns the parameters as Map from the given url String.<p> 322 * 323 * @param url the url String to get the parameters from 324 * @return the parameters as Map 325 */ 326 private Map<String, String[]> getParameterMap(String url) { 327 328 Map<String, String[]> result = new HashMap<String, String[]>(); 329 if (CmsStringUtil.isNotEmpty(url)) { 330 int pos = url.indexOf(CmsRequestUtil.URL_DELIMITER); 331 if (pos >= 0) { 332 result = CmsRequestUtil.createParameterMap(url.substring(pos + 1)); 333 } 334 } 335 return result; 336 } 337 338 /** 339 * Returns the value of the given parameter name from a parameter map.<p> 340 * 341 * @param cms the current users context 342 * @param parameterMap the map containing the parameters 343 * @param key the parameter name 344 * @return the value of the parameter or an empty String 345 */ 346 private String getParameterValue(CmsObject cms, Map<String, String[]> parameterMap, String key) { 347 348 String result = null; 349 String[] params = parameterMap.get(key); 350 if ((params != null) && (params.length > 0)) { 351 result = params[0]; 352 } 353 if (result == null) { 354 return ""; 355 } 356 return result; 357 } 358 359 /** 360 * Returns the value of the given parameter name from the current parameter map.<p> 361 * 362 * @param cms the current users context 363 * @param key the parameter name 364 * @return the value of the parameter or an empty String 365 */ 366 private String getParameterValue(CmsObject cms, String key) { 367 368 if (m_parameters == null) { 369 m_parameters = getParameterMap(getStringValue(cms)); 370 } 371 return getParameterValue(cms, m_parameters, key); 372 } 373 374 /** 375 * Sets a parameter for the image with the provided key as name and the value.<p> 376 * 377 * @param cms the current users context 378 * @param key the parameter name to set 379 * @param value the value of the parameter 380 */ 381 private void setParameterValue(CmsObject cms, String key, String value) { 382 383 if (m_parameters == null) { 384 m_parameters = getParameterMap(getStringValue(cms)); 385 } 386 if (CmsStringUtil.isEmptyOrWhitespaceOnly(value) && m_parameters.containsKey(key)) { 387 m_parameters.remove(key); 388 } else if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(value)) { 389 m_parameters.put(key, new String[] {value}); 390 } 391 String result = CmsRequestUtil.getRequestLink(getStringValue(cms)); 392 result = CmsRequestUtil.appendParameters(result, m_parameters, false); 393 setStringValue(cms, result); 394 } 395 396}