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.jsp.decorator; 029 030import org.opencms.file.CmsFile; 031import org.opencms.file.CmsObject; 032import org.opencms.file.CmsResource; 033import org.opencms.i18n.CmsLocaleManager; 034import org.opencms.main.CmsException; 035import org.opencms.xml.content.CmsXmlContent; 036import org.opencms.xml.content.CmsXmlContentFactory; 037 038import java.util.ArrayList; 039import java.util.List; 040import java.util.Locale; 041 042import org.htmlparser.Tag; 043 044/** 045 * The CmsDecoratorConfiguration initalizes and stores the text decorations.<p> 046 * 047 * It uses uses the information of one or more <code>{@link CmsDecorationDefintion}</code> to create the 048 * pre- and postfixs for text decorations. 049 * 050 * @since 6.1.3 051 */ 052 053public class CmsDecoratorConfiguration implements I_CmsDecoratorConfiguration { 054 055 /** The xpath for the decoration configuration. */ 056 public static final String XPATH_DECORATION = "decoration"; 057 058 /** The xpath for the exclude configuration. */ 059 public static final String XPATH_EXCLUDE = "exclude"; 060 061 /** The xpath for the exclude configuration. */ 062 public static final String XPATH_EXCLUDEATTR = "excludeattr"; 063 064 /** The xpath for the uselocale configuration. */ 065 public static final String XPATH_USELOCALE = "uselocale"; 066 067 /** The xpath for the filename configuration. */ 068 private static final String XPATH_FILENAME = "filename"; 069 070 /** The xpath for the markfirst configuration. */ 071 private static final String XPATH_MARKFIRST = "markfirst"; 072 073 /** The xpath for the name configuration. */ 074 private static final String XPATH_NAME = "name"; 075 076 /** The xpath for the posttext configuration. */ 077 private static final String XPATH_POSTTEXT = "posttext"; 078 079 /** The xpath for the posttextfirst configuration. */ 080 private static final String XPATH_POSTTEXTFIRST = "posttextfirst"; 081 082 /** The xpath for the pretext configuration. */ 083 private static final String XPATH_PRETEXT = "pretext"; 084 085 /** The xpath for the pretextfirst configuration. */ 086 private static final String XPATH_PRETEXTFIRST = "pretextfirst"; 087 088 /** The CmsObject. */ 089 private CmsObject m_cms; 090 091 /** The config file. */ 092 private String m_configFile; 093 094 /** The locale for extracting the configuration data. */ 095 private Locale m_configurationLocale = CmsLocaleManager.getLocale("en"); 096 097 /** Map of configured decorations. */ 098 private CmsDecorationBundle m_decorations; 099 100 /** The list of excluded tags. */ 101 private List<String> m_excludes; 102 103 /** The list of excluded attributes. */ 104 private List<String> m_excludeattr; 105 106 /** The locale for to build the configuration for. */ 107 private Locale m_locale; 108 109 /** The list of already used decorations. */ 110 private List<String> m_usedDecorations; 111 112 /** The list with all <code>{@link CmsDecorationDefintion}</code> instances parsed from the config file. */ 113 private List<CmsDecorationDefintion> m_decorationDefinitions; 114 115 /** 116 * Constructor, creates a new, empty CmsDecoratorConfiguration.<p> 117 * 118 */ 119 public CmsDecoratorConfiguration() { 120 121 m_decorations = new CmsDecorationBundle(); 122 m_configFile = null; 123 m_cms = null; 124 m_locale = null; 125 m_usedDecorations = new ArrayList<String>(); 126 m_excludes = new ArrayList<String>(); 127 m_excludeattr = new ArrayList<String>(); 128 m_decorationDefinitions = new ArrayList<CmsDecorationDefintion>(); 129 } 130 131 /** 132 * Constructor, creates a new, empty CmsDecoratorConfiguration.<p> 133 * 134 * @param cms the CmsObject 135 * @throws CmsException if something goes wrong 136 * 137 */ 138 public CmsDecoratorConfiguration(CmsObject cms) 139 throws CmsException { 140 141 m_decorations = new CmsDecorationBundle(); 142 m_configFile = null; 143 m_cms = cms; 144 m_locale = m_cms.getRequestContext().getLocale(); 145 m_usedDecorations = new ArrayList<String>(); 146 m_excludes = new ArrayList<String>(); 147 m_excludeattr = new ArrayList<String>(); 148 m_decorationDefinitions = new ArrayList<CmsDecorationDefintion>(); 149 init(cms, null, null); 150 } 151 152 /** 153 * Constructor, creates a new, CmsDecoratorConfiguration with a given config file.<p> 154 * 155 * @param cms the CmsObject 156 * @param configFile the configuration file 157 * @throws CmsException if something goes wrong 158 */ 159 public CmsDecoratorConfiguration(CmsObject cms, String configFile) 160 throws CmsException { 161 162 m_decorations = new CmsDecorationBundle(); 163 m_configFile = null; 164 m_cms = cms; 165 m_locale = m_cms.getRequestContext().getLocale(); 166 m_usedDecorations = new ArrayList<String>(); 167 m_excludes = new ArrayList<String>(); 168 m_excludeattr = new ArrayList<String>(); 169 m_decorationDefinitions = new ArrayList<CmsDecorationDefintion>(); 170 init(cms, configFile, null); 171 } 172 173 /** 174 * Constructor, creates a new, CmsDecoratorConfiguration with a given config file and locale.<p> 175 * 176 * @param cms the CmsObject 177 * @param configFile the configuration file 178 * @param locale to locale to build this configuration for 179 * @throws CmsException if something goes wrong 180 */ 181 public CmsDecoratorConfiguration(CmsObject cms, String configFile, Locale locale) 182 throws CmsException { 183 184 m_decorations = new CmsDecorationBundle(); 185 m_configFile = null; 186 m_cms = cms; 187 m_locale = m_cms.getRequestContext().getLocale(); 188 m_usedDecorations = new ArrayList<String>(); 189 m_excludes = new ArrayList<String>(); 190 m_excludeattr = new ArrayList<String>(); 191 m_decorationDefinitions = new ArrayList<CmsDecorationDefintion>(); 192 init(cms, configFile, locale); 193 } 194 195 /** 196 * Adds decorations defined in a <code>{@link CmsDecorationDefintion}</code> object to the map of all decorations.<p> 197 * @param decorationDefinition the <code>{@link CmsDecorationDefintion}</code> the decorations to be added 198 * @throws CmsException if something goes wrong 199 */ 200 public void addDecorations(CmsDecorationDefintion decorationDefinition) throws CmsException { 201 202 m_decorations.putAll(decorationDefinition.createDecorationBundle(m_cms, m_configurationLocale).getAll()); 203 } 204 205 /** 206 * Returns the cms.<p> 207 * 208 * @return the cms 209 */ 210 public CmsObject getCms() { 211 212 return m_cms; 213 } 214 215 /** 216 * Returns the configFile.<p> 217 * 218 * @return the configFile 219 */ 220 public String getConfigFile() { 221 222 return m_configFile; 223 } 224 225 /** 226 * Returns the configurationLocale.<p> 227 * 228 * @return the configurationLocale 229 */ 230 public Locale getConfigurationLocale() { 231 232 return m_configurationLocale; 233 } 234 235 /** 236 * Builds a CmsDecorationDefintion from a given configuration file.<p> 237 * 238 * @param configuration the configuration file 239 * @param i the number of the decoration definition to create 240 * @return CmsDecorationDefintion created form configuration file 241 */ 242 public CmsDecorationDefintion getDecorationDefinition(CmsXmlContent configuration, int i) { 243 244 CmsDecorationDefintion decDef = new CmsDecorationDefintion(); 245 String name = configuration.getValue(XPATH_DECORATION + "[" + i + "]/" + XPATH_NAME, m_configurationLocale).getStringValue( 246 m_cms); 247 String markfirst = configuration.getValue( 248 XPATH_DECORATION + "[" + i + "]/" + XPATH_MARKFIRST, 249 m_configurationLocale).getStringValue(m_cms); 250 String pretext = configuration.getValue( 251 XPATH_DECORATION + "[" + i + "]/" + XPATH_PRETEXT, 252 m_configurationLocale).getStringValue(m_cms); 253 String posttext = configuration.getValue( 254 XPATH_DECORATION + "[" + i + "]/" + XPATH_POSTTEXT, 255 m_configurationLocale).getStringValue(m_cms); 256 String pretextfirst = configuration.getValue( 257 XPATH_DECORATION + "[" + i + "]/" + XPATH_PRETEXTFIRST, 258 m_configurationLocale).getStringValue(m_cms); 259 String posttextfirst = configuration.getValue( 260 XPATH_DECORATION + "[" + i + "]/" + XPATH_POSTTEXTFIRST, 261 m_configurationLocale).getStringValue(m_cms); 262 String filenname = configuration.getValue( 263 XPATH_DECORATION + "[" + i + "]/" + XPATH_FILENAME, 264 m_configurationLocale).getStringValue(m_cms); 265 266 decDef.setName(name); 267 decDef.setMarkFirst(markfirst.equals("true")); 268 decDef.setPreText(pretext); 269 decDef.setPostText(posttext); 270 decDef.setPreTextFirst(pretextfirst); 271 decDef.setPostTextFirst(posttextfirst); 272 decDef.setConfigurationFile(filenname); 273 274 return decDef; 275 } 276 277 /** 278 * Returns the list with all <code>{@link CmsDecorationDefintion}</code> 279 * instances parsed from the config file.<p> 280 * 281 * @return The list with all <code>{@link CmsDecorationDefintion}</code> instances 282 * parsed from the config file 283 */ 284 public List<CmsDecorationDefintion> getDecorationDefinitions() { 285 286 return m_decorationDefinitions; 287 } 288 289 /** 290 * Gets the decoration bundle.<p> 291 *@return the decoration bundle to be used 292 */ 293 public CmsDecorationBundle getDecorations() { 294 295 return m_decorations; 296 } 297 298 /** 299 * Returns the excludeattr.<p> 300 * 301 * @return the excludeattr 302 */ 303 public List<String> getExcludeattr() { 304 305 return m_excludeattr; 306 } 307 308 /** 309 * Returns the excludes.<p> 310 * 311 * @return the excludes 312 */ 313 public List<String> getExcludes() { 314 315 return m_excludes; 316 } 317 318 /** 319 * Returns the locale.<p> 320 * 321 * @return the locale 322 */ 323 public Locale getLocale() { 324 325 return m_locale; 326 } 327 328 /** 329 * Returns the usedDecorations.<p> 330 * 331 * @return the usedDecorations 332 */ 333 public List<String> getUsedDecorations() { 334 335 return m_usedDecorations; 336 } 337 338 /** 339 * Tests if a decoration key was used before in this configuration.<p> 340 * @param key the key to look for 341 * @return true if this key was already used 342 */ 343 public boolean hasUsed(String key) { 344 345 return m_usedDecorations.contains(key); 346 } 347 348 /** 349 * @see org.opencms.jsp.decorator.I_CmsDecoratorConfiguration#init(org.opencms.file.CmsObject, java.lang.String, java.util.Locale) 350 */ 351 public void init(CmsObject cms, String configFile, Locale locale) throws CmsException { 352 353 m_cms = cms; 354 m_locale = cms.getRequestContext().getLocale(); 355 if (configFile != null) { 356 m_configFile = configFile; 357 } 358 if (locale != null) { 359 m_decorations = new CmsDecorationBundle(locale); 360 m_locale = locale; 361 } 362 363 if (m_configFile != null) { 364 365 // get the configuration file 366 CmsResource res = m_cms.readResource(m_configFile); 367 CmsFile file = m_cms.readFile(res); 368 CmsXmlContent configuration = CmsXmlContentFactory.unmarshal(m_cms, file); 369 370 // get the uselocale flag 371 // if this flag is not set to true, we must build locale independent decoration bundles 372 String uselocale = configuration.getValue(XPATH_USELOCALE, m_configurationLocale).getStringValue(m_cms); 373 if (!uselocale.equals("true")) { 374 m_locale = null; 375 } 376 // get the number of decoration definitions 377 int decorationDefCount = configuration.getIndexCount(XPATH_DECORATION, m_configurationLocale); 378 // get all the decoration definitions 379 for (int i = 1; i <= decorationDefCount; i++) { 380 CmsDecorationDefintion decDef = getDecorationDefinition(configuration, i); 381 m_decorationDefinitions.add(decDef); 382 CmsDecorationBundle decBundle = decDef.createDecorationBundle(m_cms, m_locale); 383 // merge it to the already existing decorations 384 m_decorations.putAll(decBundle.getAll()); 385 } 386 387 // now read the exclude values 388 int excludeValuesCount = configuration.getIndexCount(XPATH_EXCLUDE, m_configurationLocale); 389 // get all the exclude definitions 390 for (int i = 1; i <= excludeValuesCount; i++) { 391 String excludeValue = configuration.getStringValue( 392 m_cms, 393 XPATH_EXCLUDE + "[" + i + "]", 394 m_configurationLocale); 395 m_excludes.add(excludeValue.toLowerCase()); 396 } 397 398 // now read the exclude attributes 399 int excludeAttrValuesCount = configuration.getIndexCount(XPATH_EXCLUDEATTR, m_configurationLocale); 400 // get all the exclude attribute definitions 401 for (int i = 1; i <= excludeAttrValuesCount; i++) { 402 String excludeAttrValue = configuration.getStringValue( 403 m_cms, 404 XPATH_EXCLUDEATTR + "[" + i + "]", 405 m_configurationLocale); 406 m_excludeattr.add(excludeAttrValue.toLowerCase()); 407 } 408 409 } 410 } 411 412 /** 413 * Tests if a tag is contained in the exclude list of the decorator.<p> 414 * 415 * @param tag the tag to test 416 * @return true if the tag is in the exclode list, false othwerwise. 417 */ 418 public boolean isExcluded(String tag) { 419 420 return m_excludes.contains(tag.toLowerCase()); 421 } 422 423 /** 424 * 425 * @see org.opencms.jsp.decorator.I_CmsDecoratorConfiguration#isExcludedAttr(org.htmlparser.Tag) 426 */ 427 public boolean isExcludedAttr(Tag tag) { 428 429 boolean isExcluded = false; 430 for (String attr : m_excludeattr) { 431 if (tag.getAttribute(attr.toLowerCase()) != null) { 432 isExcluded = true; 433 break; 434 } 435 } 436 return isExcluded; 437 } 438 439 /** 440 * Mark a decoration key as already used.<p> 441 * @param key the key to mark 442 */ 443 public void markAsUsed(String key) { 444 445 m_usedDecorations.add(key); 446 } 447 448 /** 449 * Resets the used decoration keys.<p> 450 */ 451 public void resetMarkedDecorations() { 452 453 m_usedDecorations = new ArrayList<String>(); 454 } 455 456 /** 457 * Sets the cms.<p> 458 * 459 * @param cms the cms to set 460 */ 461 public void setCms(CmsObject cms) { 462 463 m_cms = cms; 464 } 465 466 /** 467 * Sets the configFile.<p> 468 * 469 * @param configFile the configFile to set 470 */ 471 public void setConfigFile(String configFile) { 472 473 m_configFile = configFile; 474 } 475 476 /** 477 * Sets the configurationLocale.<p> 478 * 479 * @param configurationLocale the configurationLocale to set 480 */ 481 public void setConfigurationLocale(Locale configurationLocale) { 482 483 m_configurationLocale = configurationLocale; 484 } 485 486 /** 487 * Sets the decorationDefinitions.<p> 488 * 489 * @param decorationDefinitions the decorationDefinitions to set 490 */ 491 public void setDecorationDefinitions(List<CmsDecorationDefintion> decorationDefinitions) { 492 493 m_decorationDefinitions = decorationDefinitions; 494 } 495 496 /** 497 * Sets the decoration bundle, overwriting an exiting one.<p> 498 * 499 * @param decorations new decoration bundle 500 */ 501 public void setDecorations(CmsDecorationBundle decorations) { 502 503 m_decorations = decorations; 504 } 505 506 /** 507 * Sets the excludeattr.<p> 508 * 509 * @param excludeattr the excludeattr to set 510 */ 511 public void setExcludeattr(List<String> excludeattr) { 512 513 m_excludeattr = excludeattr; 514 } 515 516 /** 517 * Sets the excludes.<p> 518 * 519 * @param excludes the excludes to set 520 */ 521 public void setExcludes(List<String> excludes) { 522 523 m_excludes = excludes; 524 } 525 526 /** 527 * Sets the locale.<p> 528 * 529 * @param locale the locale to set 530 */ 531 public void setLocale(Locale locale) { 532 533 m_locale = locale; 534 } 535 536 /** 537 * Sets the usedDecorations.<p> 538 * 539 * @param usedDecorations the usedDecorations to set 540 */ 541 public void setUsedDecorations(List<String> usedDecorations) { 542 543 m_usedDecorations = usedDecorations; 544 } 545 546 /** 547 * @see java.lang.Object#toString() 548 */ 549 @Override 550 public String toString() { 551 552 StringBuffer buf = new StringBuffer(); 553 buf.append(this.getClass().getName()); 554 buf.append(" [configFile = '"); 555 buf.append(m_configFile); 556 buf.append("', decorations = '"); 557 buf.append(m_decorations); 558 buf.append("', locale = '"); 559 buf.append(m_locale); 560 buf.append("']"); 561 return buf.toString(); 562 } 563 564}