001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (https://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: https://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: https://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.configuration; 029 030import org.opencms.db.CmsOnlineFolderOptions; 031import org.opencms.file.CmsProperty; 032import org.opencms.file.collectors.I_CmsResourceCollector; 033import org.opencms.file.types.CmsResourceTypeXmlContainerPage; 034import org.opencms.file.types.CmsResourceTypeXmlContent; 035import org.opencms.file.types.I_CmsResourceType; 036import org.opencms.loader.CmsDefaultFileNameGenerator; 037import org.opencms.loader.CmsMimeType; 038import org.opencms.loader.CmsResourceManager; 039import org.opencms.loader.I_CmsResourceLoader; 040import org.opencms.main.CmsLog; 041import org.opencms.main.OpenCms; 042import org.opencms.relations.CmsRelationType; 043import org.opencms.util.CmsHtmlConverterOption; 044import org.opencms.util.CmsResourceTranslator; 045import org.opencms.util.CmsStringUtil; 046import org.opencms.widgets.I_CmsWidget; 047import org.opencms.xml.CmsXmlContentTypeManager; 048import org.opencms.xml.types.I_CmsXmlSchemaType; 049 050import java.util.ArrayList; 051import java.util.Collections; 052import java.util.Iterator; 053import java.util.List; 054 055import org.apache.commons.digester3.Digester; 056import org.apache.commons.digester3.Rule; 057 058import org.dom4j.Element; 059import org.xml.sax.Attributes; 060 061/** 062 * VFS master configuration class.<p> 063 * 064 * @since 6.0.0 065 */ 066public class CmsVfsConfiguration extends A_CmsXmlConfiguration { 067 068 /** The adjust-links-folder attribute. */ 069 public static final String A_ADJUST_LINKS_FOLDER = "adjust-links-folder"; 070 071 /** The widget configuration attribute. */ 072 public static final String A_CONFIGURATION = "configuration"; 073 074 /** The widget attribute. */ 075 public static final String A_DEFAULTWIDGET = "defaultwidget"; 076 077 /** The extension attribute name. */ 078 public static final String A_EXTENSION = "extension"; 079 080 /** The source attribute name. */ 081 public static final String A_SOURCE = "source"; 082 083 /** The target attribute name. */ 084 public static final String A_TARGET = "target"; 085 086 /** The name of the DTD for this configuration. */ 087 public static final String CONFIGURATION_DTD_NAME = "opencms-vfs.dtd"; 088 089 /** The name of the default XML file for this configuration. */ 090 public static final String DEFAULT_XML_FILE_NAME = "opencms-vfs.xml"; 091 092 /** The collector node name. */ 093 public static final String N_COLLECTOR = "collector"; 094 095 /** The collectors node name. */ 096 public static final String N_COLLECTORS = "collectors"; 097 098 public static final String N_PATH = "path"; 099 100 /** The copy-resource node name.*/ 101 public static final String N_COPY_RESOURCE = "copy-resource"; 102 103 /** The copy-resources node name.*/ 104 public static final String N_COPY_RESOURCES = "copy-resources"; 105 106 /** The defaultfile node name. */ 107 public static final String N_DEFAULTFILE = "defaultfile"; 108 109 /** The defaultfiles node name. */ 110 public static final String N_DEFAULTFILES = "defaultfiles"; 111 112 /** File translations node name. */ 113 public static final String N_FILETRANSLATIONS = "filetranslations"; 114 115 /** Folder translations node name. */ 116 public static final String N_FOLDERTRANSLATIONS = "foldertranslations"; 117 118 /** The html-converter node name.*/ 119 public static final String N_HTML_CONVERTER = "html-converter"; 120 121 /** The html-converters node name.*/ 122 public static final String N_HTML_CONVERTERS = "html-converters"; 123 124 /** The node name of an individual resource loader. */ 125 public static final String N_LOADER = "loader"; 126 127 /** The mapping node name. */ 128 public static final String N_MAPPING = "mapping"; 129 130 /** The mappings node name. */ 131 public static final String N_MAPPINGS = "mappings"; 132 133 /** The mimetype node name. */ 134 public static final String N_MIMETYPE = "mimetype"; 135 136 /** The mimetypes node name. */ 137 public static final String N_MIMETYPES = "mimetypes"; 138 139 /** The properties node name. */ 140 public static final String N_PROPERTIES = "properties"; 141 142 /** The relation type node name. */ 143 public static final String N_RELATIONTYPE = "relationtype"; 144 145 /** The relation types node name. */ 146 public static final String N_RELATIONTYPES = "relationtypes"; 147 148 /** The resource loaders node name. */ 149 public static final String N_RESOURCELOADERS = "resourceloaders"; 150 151 /** The main resource node name. */ 152 public static final String N_RESOURCES = "resources"; 153 154 /** The resource types node name. */ 155 public static final String N_RESOURCETYPES = "resourcetypes"; 156 157 /** The schematype node name. */ 158 public static final String N_SCHEMATYPE = "schematype"; 159 160 /** The online-folders node name. */ 161 public static final String N_ONLINE_FOLDERS = "online-folders"; 162 163 /** The schematypes node name. */ 164 public static final String N_SCHEMATYPES = "schematypes"; 165 166 /** Individual translation node name. */ 167 public static final String N_TRANSLATION = "translation"; 168 169 /** The translations master node name. */ 170 public static final String N_TRANSLATIONS = "translations"; 171 172 /** The node name of an individual resource type. */ 173 public static final String N_TYPE = "type"; 174 175 /** The node name for the version history. */ 176 public static final String N_VERSIONHISTORY = "versionhistory"; 177 178 /** The main vfs configuration node name. */ 179 public static final String N_VFS = "vfs"; 180 181 /** The widget node name. */ 182 public static final String N_WIDGET = "widget"; 183 184 /** The widget alias node name. */ 185 public static final String N_WIDGET_ALIAS = "widget-alias"; 186 187 /** The widgets node name. */ 188 public static final String N_WIDGETS = "widgets"; 189 190 /** The xmlcontent node name. */ 191 public static final String N_XMLCONTENT = "xmlcontent"; 192 193 /** The xmlcontents node name. */ 194 public static final String N_XMLCONTENTS = "xmlcontents"; 195 196 /** XSD translations node name. */ 197 public static final String N_XSDTRANSLATIONS = "xsdtranslations"; 198 199 /** The namegenerator node name. */ 200 private static final String N_NAMEGENERATOR = "namegenerator"; 201 202 private CmsOnlineFolderOptions m_onlineFolderOptions = new CmsOnlineFolderOptions( 203 new ArrayList<>(), 204 new CmsParameterConfiguration()); 205 206 /** The configured XML content type manager. */ 207 CmsXmlContentTypeManager m_xmlContentTypeManager; 208 209 /** The list of configured default files. */ 210 private List<String> m_defaultFiles; 211 212 /** Controls if file translation is enabled. */ 213 private boolean m_fileTranslationEnabled; 214 215 /** The list of file translations. */ 216 private List<String> m_fileTranslations; 217 218 /** Controls if folder translation is enabled. */ 219 private boolean m_folderTranslationEnabled; 220 221 /** The list of folder translations. */ 222 private List<String> m_folderTranslations; 223 224 /** The configured resource manager. */ 225 private CmsResourceManager m_resourceManager; 226 227 /** Controls if XSD translation is enabled. */ 228 private boolean m_xsdTranslationEnabled; 229 230 /** The list of XSD translations. */ 231 private List<String> m_xsdTranslations; 232 233 /** 234 * Adds the resource type rules to the given digester.<p> 235 * 236 * @param digester the digester to add the rules to 237 */ 238 public static void addResourceTypeXmlRules(Digester digester) { 239 240 // add rules for resource types 241 digester.addFactoryCreate("*/" + N_RESOURCETYPES + "/" + N_TYPE, CmsDigesterResourceTypeCreationFactory.class); 242 digester.addSetNext("*/" + N_RESOURCETYPES + "/" + N_TYPE, I_CmsResourceType.ADD_RESOURCE_TYPE_METHOD); 243 244 // please note: the order of the rules is very important here, 245 // the "set next" rule (above) must be added _before_ the "call method" rule (below)! 246 // reason is digester will call the rule that was last added first 247 // here we must make sure that the resource type is initialized first (with the "call method" rule) 248 // before it is actually added to the resource type container (with the "set next" rule) 249 // otherwise there will be an empty resource type added to the container, and validation will not work 250 digester.addCallMethod( 251 "*/" + N_RESOURCETYPES + "/" + N_TYPE, 252 I_CmsConfigurationParameterHandler.INIT_CONFIGURATION_METHOD, 253 3); 254 // please note: the resource types use a special version of the init method with 3 parameters 255 digester.addCallParam("*/" + N_RESOURCETYPES + "/" + N_TYPE, 0, A_NAME); 256 digester.addCallParam("*/" + N_RESOURCETYPES + "/" + N_TYPE, 1, A_ID); 257 digester.addCallParam("*/" + N_RESOURCETYPES + "/" + N_TYPE, 2, A_CLASS); 258 259 // add rules for default properties 260 digester.addObjectCreate( 261 "*/" + N_RESOURCETYPES + "/" + N_TYPE + "/" + N_PROPERTIES + "/" + N_PROPERTY, 262 CmsProperty.class); 263 digester.addCallMethod( 264 "*/" + N_RESOURCETYPES + "/" + N_TYPE + "/" + N_PROPERTIES + "/" + N_PROPERTY + "/" + N_NAME, 265 "setName", 266 1); 267 digester.addCallParam( 268 "*/" + N_RESOURCETYPES + "/" + N_TYPE + "/" + N_PROPERTIES + "/" + N_PROPERTY + "/" + N_NAME, 269 0); 270 271 digester.addCallMethod( 272 "*/" + N_RESOURCETYPES + "/" + N_TYPE + "/" + N_PROPERTIES + "/" + N_PROPERTY + "/" + N_VALUE, 273 "setValue", 274 2); 275 digester.addCallParam( 276 "*/" + N_RESOURCETYPES + "/" + N_TYPE + "/" + N_PROPERTIES + "/" + N_PROPERTY + "/" + N_VALUE, 277 0); 278 digester.addCallParam( 279 "*/" + N_RESOURCETYPES + "/" + N_TYPE + "/" + N_PROPERTIES + "/" + N_PROPERTY + "/" + N_VALUE, 280 1, 281 A_TYPE); 282 283 digester.addSetNext( 284 "*/" + N_RESOURCETYPES + "/" + N_TYPE + "/" + N_PROPERTIES + "/" + N_PROPERTY, 285 "addDefaultProperty"); 286 287 // extension mapping rules 288 digester.addCallMethod( 289 "*/" + N_RESOURCETYPES + "/" + N_TYPE + "/" + N_MAPPINGS + "/" + N_MAPPING, 290 I_CmsResourceType.ADD_MAPPING_METHOD, 291 1); 292 digester.addCallParam("*/" + N_RESOURCETYPES + "/" + N_TYPE + "/" + N_MAPPINGS + "/" + N_MAPPING, 0, A_SUFFIX); 293 294 digester.addCallMethod( 295 "*/" + N_RESOURCETYPES + "/" + N_TYPE + "/" + N_COPY_RESOURCES, 296 "setAdjustLinksFolder", 297 1); 298 digester.addCallParam("*/" + N_RESOURCETYPES + "/" + N_TYPE + "/" + N_COPY_RESOURCES, 0, A_ADJUST_LINKS_FOLDER); 299 300 // copy resource rules 301 digester.addCallMethod( 302 "*/" + N_RESOURCETYPES + "/" + N_TYPE + "/" + N_COPY_RESOURCES + "/" + N_COPY_RESOURCE, 303 "addCopyResource", 304 3); 305 digester.addCallParam( 306 "*/" + N_RESOURCETYPES + "/" + N_TYPE + "/" + N_COPY_RESOURCES + "/" + N_COPY_RESOURCE, 307 0, 308 A_SOURCE); 309 digester.addCallParam( 310 "*/" + N_RESOURCETYPES + "/" + N_TYPE + "/" + N_COPY_RESOURCES + "/" + N_COPY_RESOURCE, 311 1, 312 A_TARGET); 313 digester.addCallParam( 314 "*/" + N_RESOURCETYPES + "/" + N_TYPE + "/" + N_COPY_RESOURCES + "/" + N_COPY_RESOURCE, 315 2, 316 A_TYPE); 317 318 } 319 320 /** 321 * Creates the xml output for resourcetype nodes.<p> 322 * 323 * @param startNode the startnode to add all rescource types to 324 * @param resourceTypes the list of resource types 325 * @param module flag, signaling to add them module resource types or not 326 */ 327 public static void generateResourceTypeXml( 328 Element startNode, 329 List<I_CmsResourceType> resourceTypes, 330 boolean module) { 331 332 for (int i = 0; i < resourceTypes.size(); i++) { 333 I_CmsResourceType resType = resourceTypes.get(i); 334 // only add this resource type to the xml output, if it is no additional type defined 335 // in a module 336 if (resType.isAdditionalModuleResourceType() == module) { 337 Element resourceType = startNode.addElement(N_TYPE).addAttribute(A_CLASS, resType.getClassName()); 338 // add type id and type name 339 resourceType.addAttribute(A_NAME, resType.getTypeName()); 340 resourceType.addAttribute(A_ID, String.valueOf(resType.getTypeId())); 341 // add resource mappings 342 List<String> mappings = resType.getConfiguredMappings(); 343 if ((mappings != null) && (mappings.size() > 0)) { 344 Element mappingsNode = resourceType.addElement(N_MAPPINGS); 345 for (int j = 0; j < mappings.size(); j++) { 346 Element mapping = mappingsNode.addElement(N_MAPPING); 347 mapping.addAttribute(A_SUFFIX, mappings.get(j)); 348 } 349 } 350 // add default properties 351 List<CmsProperty> properties = resType.getConfiguredDefaultProperties(); 352 if (properties != null) { 353 if (properties.size() > 0) { 354 Element propertiesNode = resourceType.addElement(N_PROPERTIES); 355 Iterator<CmsProperty> p = properties.iterator(); 356 while (p.hasNext()) { 357 CmsProperty property = p.next(); 358 Element propertyNode = propertiesNode.addElement(N_PROPERTY); 359 propertyNode.addElement(N_NAME).addText(property.getName()); 360 if (property.getStructureValue() != null) { 361 propertyNode.addElement(N_VALUE).addCDATA(property.getStructureValue()); 362 } 363 if (property.getResourceValue() != null) { 364 propertyNode.addElement(N_VALUE).addAttribute(A_TYPE, CmsProperty.TYPE_SHARED).addCDATA( 365 property.getResourceValue()); 366 } 367 } 368 } 369 } 370 // add copy resources 371 List<CmsConfigurationCopyResource> copyRes = resType.getConfiguredCopyResources(); 372 if ((copyRes != null) && (copyRes.size() > 0)) { 373 Element copyResNode = resourceType.addElement(N_COPY_RESOURCES); 374 Iterator<CmsConfigurationCopyResource> p = copyRes.iterator(); 375 String adjustLinksFolder = resType.getAdjustLinksFolder(); 376 if (adjustLinksFolder != null) { 377 copyResNode.addAttribute(A_ADJUST_LINKS_FOLDER, adjustLinksFolder); 378 } 379 while (p.hasNext()) { 380 CmsConfigurationCopyResource cRes = p.next(); 381 Element cNode = copyResNode.addElement(N_COPY_RESOURCE); 382 cNode.addAttribute(A_SOURCE, cRes.getSource()); 383 if (!cRes.isTargetWasNull()) { 384 cNode.addAttribute(A_TARGET, cRes.getTarget()); 385 } 386 if (!cRes.isTypeWasNull()) { 387 cNode.addAttribute(A_TYPE, cRes.getTypeString()); 388 } 389 } 390 } 391 // add optional parameters 392 CmsParameterConfiguration configuration = resType.getConfiguration(); 393 if (configuration != null) { 394 List<String> ignore = null; 395 if ((resType instanceof CmsResourceTypeXmlContainerPage)) { 396 ignore = new ArrayList<String>(1); 397 ignore.add(CmsResourceTypeXmlContent.CONFIGURATION_SCHEMA); 398 } 399 configuration.appendToXml(resourceType, ignore); 400 } 401 } 402 } 403 } 404 405 /** 406 * Adds a directory default file.<p> 407 * 408 * @param defaultFile the directory default file to add 409 */ 410 public void addDefaultFile(String defaultFile) { 411 412 m_defaultFiles.add(defaultFile); 413 if (CmsLog.INIT.isInfoEnabled()) { 414 CmsLog.INIT.info( 415 Messages.get().getBundle().key( 416 Messages.INIT_VFS_DEFAULT_FILE_2, 417 Integer.valueOf(m_defaultFiles.size()), 418 defaultFile)); 419 } 420 } 421 422 /** 423 * Adds one file translation rule.<p> 424 * 425 * @param translation the file translation rule to add 426 */ 427 public void addFileTranslation(String translation) { 428 429 m_fileTranslations.add(translation); 430 if (CmsLog.INIT.isInfoEnabled()) { 431 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_VFS_ADD_FILE_TRANSLATION_1, translation)); 432 } 433 } 434 435 /** 436 * Adds one folder translation rule.<p> 437 * 438 * @param translation the folder translation rule to add 439 */ 440 public void addFolderTranslation(String translation) { 441 442 m_folderTranslations.add(translation); 443 if (CmsLog.INIT.isInfoEnabled()) { 444 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_VFS_ADD_FOLDER_TRANSLATION_1, translation)); 445 } 446 } 447 448 /** 449 * @see org.opencms.configuration.I_CmsXmlConfiguration#addXmlDigesterRules(org.apache.commons.digester3.Digester) 450 */ 451 public void addXmlDigesterRules(Digester digester) { 452 453 // add finish rule 454 digester.addCallMethod("*/" + N_VFS, "initializeFinished"); 455 456 // creation of the resource manager 457 digester.addObjectCreate("*/" + N_VFS + "/" + N_RESOURCES, CmsResourceManager.class); 458 digester.addCallMethod( 459 "*/" + N_VFS + "/" + N_RESOURCES, 460 I_CmsConfigurationParameterHandler.INIT_CONFIGURATION_METHOD); 461 digester.addSetNext("*/" + N_VFS + "/" + N_RESOURCES, "setResourceManager"); 462 463 // add rules for resource loaders 464 digester.addObjectCreate( 465 "*/" + N_VFS + "/" + N_RESOURCES + "/" + N_RESOURCELOADERS + "/" + N_LOADER, 466 CmsConfigurationException.class.getName(), 467 A_CLASS); 468 digester.addCallMethod( 469 "*/" + N_VFS + "/" + N_RESOURCES + "/" + N_RESOURCELOADERS + "/" + N_LOADER, 470 I_CmsConfigurationParameterHandler.INIT_CONFIGURATION_METHOD); 471 digester.addSetNext("*/" + N_VFS + "/" + N_RESOURCES + "/" + N_RESOURCELOADERS + "/" + N_LOADER, "addLoader"); 472 473 // add rules for resource types 474 addResourceTypeXmlRules(digester); 475 476 // add rules for VFS content collectors 477 digester.addCallMethod( 478 "*/" + N_VFS + "/" + N_RESOURCES + "/" + N_COLLECTORS + "/" + N_COLLECTOR, 479 "addContentCollector", 480 2); 481 digester.addCallParam("*/" + N_VFS + "/" + N_RESOURCES + "/" + N_COLLECTORS + "/" + N_COLLECTOR, 0, A_CLASS); 482 digester.addCallParam("*/" + N_VFS + "/" + N_RESOURCES + "/" + N_COLLECTORS + "/" + N_COLLECTOR, 1, A_ORDER); 483 484 // add the name generator 485 digester.addObjectCreate( 486 "*/" + N_VFS + "/" + N_RESOURCES + "/" + N_NAMEGENERATOR, 487 CmsDefaultFileNameGenerator.class.getName(), 488 A_CLASS); 489 digester.addSetNext("*/" + N_VFS + "/" + N_RESOURCES + "/" + N_NAMEGENERATOR, "setNameGenerator"); 490 491 // add MIME type rules 492 digester.addCallMethod( 493 "*/" + N_VFS + "/" + N_RESOURCES + "/" + N_MIMETYPES + "/" + N_MIMETYPE, 494 "addMimeType", 495 2); 496 digester.addCallParam("*/" + N_VFS + "/" + N_RESOURCES + "/" + N_MIMETYPES + "/" + N_MIMETYPE, 0, A_EXTENSION); 497 digester.addCallParam("*/" + N_VFS + "/" + N_RESOURCES + "/" + N_MIMETYPES + "/" + N_MIMETYPE, 1, A_TYPE); 498 499 // add relation type rules 500 digester.addCallMethod( 501 "*/" + N_VFS + "/" + N_RESOURCES + "/" + N_RELATIONTYPES + "/" + N_RELATIONTYPE, 502 "addRelationType", 503 2); 504 digester.addCallParam( 505 "*/" + N_VFS + "/" + N_RESOURCES + "/" + N_RELATIONTYPES + "/" + N_RELATIONTYPE, 506 0, 507 A_NAME); 508 digester.addCallParam( 509 "*/" + N_VFS + "/" + N_RESOURCES + "/" + N_RELATIONTYPES + "/" + N_RELATIONTYPE, 510 1, 511 A_TYPE); 512 513 // add html converter rules 514 digester.addCallMethod( 515 "*/" + N_VFS + "/" + N_RESOURCES + "/" + N_HTML_CONVERTERS + "/" + N_HTML_CONVERTER, 516 "addHtmlConverter", 517 2); 518 digester.addCallParam( 519 "*/" + N_VFS + "/" + N_RESOURCES + "/" + N_HTML_CONVERTERS + "/" + N_HTML_CONVERTER, 520 0, 521 A_NAME); 522 digester.addCallParam( 523 "*/" + N_VFS + "/" + N_RESOURCES + "/" + N_HTML_CONVERTERS + "/" + N_HTML_CONVERTER, 524 1, 525 A_CLASS); 526 527 // generic <param> parameter rules 528 digester.addCallMethod( 529 "*/" + I_CmsXmlConfiguration.N_PARAM, 530 I_CmsConfigurationParameterHandler.ADD_PARAMETER_METHOD, 531 2); 532 digester.addCallParam("*/" + I_CmsXmlConfiguration.N_PARAM, 0, I_CmsXmlConfiguration.A_NAME); 533 digester.addCallParam("*/" + I_CmsXmlConfiguration.N_PARAM, 1); 534 535 // add rule for default files 536 digester.addCallMethod("*/" + N_VFS + "/" + N_DEFAULTFILES + "/" + N_DEFAULTFILE, "addDefaultFile", 1); 537 digester.addCallParam("*/" + N_VFS + "/" + N_DEFAULTFILES + "/" + N_DEFAULTFILE, 0, A_NAME); 538 539 // add rules for file translations 540 digester.addCallMethod( 541 "*/" + N_VFS + "/" + N_TRANSLATIONS + "/" + N_FILETRANSLATIONS + "/" + N_TRANSLATION, 542 "addFileTranslation", 543 0); 544 digester.addCallMethod( 545 "*/" + N_VFS + "/" + N_TRANSLATIONS + "/" + N_FILETRANSLATIONS, 546 "setFileTranslationEnabled", 547 1); 548 digester.addCallParam("*/" + N_VFS + "/" + N_TRANSLATIONS + "/" + N_FILETRANSLATIONS, 0, A_ENABLED); 549 550 // add rules for file translations 551 digester.addCallMethod( 552 "*/" + N_VFS + "/" + N_TRANSLATIONS + "/" + N_FOLDERTRANSLATIONS + "/" + N_TRANSLATION, 553 "addFolderTranslation", 554 0); 555 digester.addCallMethod( 556 "*/" + N_VFS + "/" + N_TRANSLATIONS + "/" + N_FOLDERTRANSLATIONS, 557 "setFolderTranslationEnabled", 558 1); 559 digester.addCallParam("*/" + N_VFS + "/" + N_TRANSLATIONS + "/" + N_FOLDERTRANSLATIONS, 0, A_ENABLED); 560 561 // add rules for file translations 562 digester.addCallMethod( 563 "*/" + N_VFS + "/" + N_TRANSLATIONS + "/" + N_XSDTRANSLATIONS + "/" + N_TRANSLATION, 564 "addXsdTranslation", 565 0); 566 digester.addCallMethod( 567 "*/" + N_VFS + "/" + N_TRANSLATIONS + "/" + N_XSDTRANSLATIONS, 568 "setXsdTranslationEnabled", 569 1); 570 digester.addCallParam("*/" + N_VFS + "/" + N_TRANSLATIONS + "/" + N_XSDTRANSLATIONS, 0, A_ENABLED); 571 572 // XML content type manager creation rules 573 digester.addObjectCreate("*/" + N_VFS + "/" + N_XMLCONTENT, CmsXmlContentTypeManager.class); 574 digester.addSetNext("*/" + N_VFS + "/" + N_XMLCONTENT, "setXmlContentTypeManager"); 575 576 // XML content widgets add rules 577 578 // Widget definitions. 579 // 'aliases' list is used/reset by the rule for widgets, and filled by the rule for aliases. 580 final List<String> aliases = new ArrayList<>(); 581 digester.addRule("*/" + N_VFS + "/" + N_XMLCONTENT + "/" + N_WIDGETS + "/" + N_WIDGET, new Rule() { 582 583 private String m_className; 584 private String m_config; 585 586 @Override 587 public void begin(String namespace, String name, Attributes attributes) throws Exception { 588 589 m_className = attributes.getValue(A_CLASS); 590 m_config = attributes.getValue(A_CONFIGURATION); 591 String alias = attributes.getValue(A_ALIAS); 592 593 aliases.clear(); 594 if (alias != null) { 595 aliases.add(alias.trim()); 596 } 597 } 598 599 @Override 600 public void end(String namespace, String name) throws Exception { 601 602 CmsXmlContentTypeManager manager = getDigester().peek(); 603 List<String> aliasesCopy = new ArrayList<>(aliases); 604 manager.addWidget(m_className, aliasesCopy, m_config); 605 } 606 }); 607 608 digester.addRule( 609 "*/" + N_VFS + "/" + N_XMLCONTENT + "/" + N_WIDGETS + "/" + N_WIDGET + "/" + N_WIDGET_ALIAS, 610 new Rule() { 611 612 @Override 613 public void body(String namespace, String name, String text) throws Exception { 614 615 aliases.add(text.trim()); 616 } 617 618 }); 619 620 // XML content schema type add rules 621 digester.addCallMethod( 622 "*/" + N_VFS + "/" + N_XMLCONTENT + "/" + N_SCHEMATYPES + "/" + N_SCHEMATYPE, 623 "addSchemaType", 624 2); 625 digester.addCallParam("*/" + N_VFS + "/" + N_XMLCONTENT + "/" + N_SCHEMATYPES + "/" + N_SCHEMATYPE, 0, A_CLASS); 626 digester.addCallParam( 627 "*/" + N_VFS + "/" + N_XMLCONTENT + "/" + N_SCHEMATYPES + "/" + N_SCHEMATYPE, 628 1, 629 A_DEFAULTWIDGET); 630 631 final CmsParameterConfiguration onlineFolderParams = new CmsParameterConfiguration(); 632 final List<String> onlineFolderPaths = new ArrayList<>(); 633 digester.addRule("*/" + N_ONLINE_FOLDERS, new Rule() { 634 635 @Override 636 public void begin(String namespace, String name, Attributes attributes) throws Exception { 637 638 super.begin(namespace, name, attributes); 639 getDigester().push(new I_CmsConfigurationParameterHandler() { 640 641 @Override 642 public void addConfigurationParameter(String paramName, String paramValue) { 643 644 onlineFolderParams.add(paramName, paramValue); 645 } 646 647 @Override 648 public CmsParameterConfiguration getConfiguration() { 649 650 return onlineFolderParams; 651 652 } 653 654 @Override 655 public void initConfiguration() throws CmsConfigurationException { 656 657 // TODO Auto-generated method stub 658 659 } 660 }); 661 } 662 663 @Override 664 public void end(String namespace, String name) throws Exception { 665 666 getDigester().pop(); 667 m_onlineFolderOptions = new CmsOnlineFolderOptions(onlineFolderPaths, onlineFolderParams); 668 } 669 }); 670 digester.addRule("*/" + N_ONLINE_FOLDERS + "/" + N_PATH, new Rule() { 671 672 public void body(String namespace, String name, String text) throws Exception { 673 674 if (!CmsStringUtil.isEmptyOrWhitespaceOnly(text)) { 675 onlineFolderPaths.add(text); 676 } 677 } 678 }); 679 } 680 681 /** 682 * Adds one XSD translation rule.<p> 683 * 684 * @param translation the XSD translation rule to add 685 */ 686 public void addXsdTranslation(String translation) { 687 688 m_xsdTranslations.add(translation); 689 if (CmsLog.INIT.isInfoEnabled()) { 690 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_VFS_ADD_XSD_TRANSLATION_1, translation)); 691 } 692 } 693 694 /** 695 * @see org.opencms.configuration.I_CmsXmlConfiguration#generateXml(org.dom4j.Element) 696 */ 697 public Element generateXml(Element parent) { 698 699 if (OpenCms.getRunLevel() >= OpenCms.RUNLEVEL_3_SHELL_ACCESS) { 700 m_resourceManager = OpenCms.getResourceManager(); 701 m_xmlContentTypeManager = OpenCms.getXmlContentTypeManager(); 702 m_defaultFiles = OpenCms.getDefaultFiles(); 703 } 704 705 // generate vfs node and subnodes 706 Element vfs = parent.addElement(N_VFS); 707 708 // add resources main element 709 Element resources = vfs.addElement(N_RESOURCES); 710 711 // add resource loader 712 Element resourceloadersElement = resources.addElement(N_RESOURCELOADERS); 713 for (I_CmsResourceLoader loader : m_resourceManager.getLoaders()) { 714 // add the loader node 715 Element loaderNode = resourceloadersElement.addElement(N_LOADER); 716 loaderNode.addAttribute(A_CLASS, loader.getClass().getName()); 717 CmsParameterConfiguration loaderConfiguration = loader.getConfiguration(); 718 if (loaderConfiguration != null) { 719 loaderConfiguration.appendToXml(loaderNode); 720 } 721 } 722 723 // add resource types 724 Element resourcetypesElement = resources.addElement(N_RESOURCETYPES); 725 List<I_CmsResourceType> resourceTypes = new ArrayList<I_CmsResourceType>(); 726 if (m_resourceManager.getResTypeUnknownFolder() != null) { 727 resourceTypes.add(m_resourceManager.getResTypeUnknownFolder()); 728 } 729 if (m_resourceManager.getResTypeUnknownFile() != null) { 730 resourceTypes.add(m_resourceManager.getResTypeUnknownFile()); 731 } 732 resourceTypes.addAll(m_resourceManager.getResourceTypes()); 733 generateResourceTypeXml(resourcetypesElement, resourceTypes, false); 734 735 // add VFS content collectors 736 Element collectorsElement = resources.addElement(N_COLLECTORS); 737 for (I_CmsResourceCollector collector : m_resourceManager.getRegisteredContentCollectors()) { 738 collectorsElement.addElement(N_COLLECTOR).addAttribute( 739 A_CLASS, 740 collector.getClass().getName()).addAttribute(A_ORDER, String.valueOf(collector.getOrder())); 741 } 742 743 Element namegeneratorElement = resources.addElement(N_NAMEGENERATOR); 744 String nameGeneratorClass = m_resourceManager.getNameGenerator().getClass().getName(); 745 namegeneratorElement.addAttribute(A_CLASS, nameGeneratorClass); 746 747 // add MIME types 748 Element mimeTypesElement = resources.addElement(N_MIMETYPES); 749 for (CmsMimeType type : m_resourceManager.getMimeTypes()) { 750 mimeTypesElement.addElement(N_MIMETYPE).addAttribute(A_EXTENSION, type.getExtension()).addAttribute( 751 A_TYPE, 752 type.getType()); 753 } 754 755 // add relation types 756 Element relationTypesElement = resources.addElement(N_RELATIONTYPES); 757 for (CmsRelationType type : m_resourceManager.getRelationTypes()) { 758 relationTypesElement.addElement(N_RELATIONTYPE).addAttribute(A_NAME, type.getName()).addAttribute( 759 A_TYPE, 760 type.getType()); 761 } 762 763 // HTML converter configuration 764 boolean writeConfig = false; 765 for (CmsHtmlConverterOption converter : m_resourceManager.getHtmlConverters()) { 766 if (!converter.isDefault()) { 767 // found a non default converter configuration, set flag to write configuration 768 writeConfig = true; 769 break; 770 } 771 } 772 if (writeConfig) { 773 // configuration is written because non default options were found 774 Element htmlConvertersElement = resources.addElement(N_HTML_CONVERTERS); 775 for (CmsHtmlConverterOption converter : m_resourceManager.getHtmlConverters()) { 776 Element converterElement = htmlConvertersElement.addElement(N_HTML_CONVERTER).addAttribute( 777 A_NAME, 778 converter.getName()); 779 converterElement.addAttribute(A_CLASS, converter.getClassName()); 780 } 781 } 782 783 // add default file names 784 Element defaultFileElement = vfs.addElement(N_DEFAULTFILES); 785 for (String element : m_defaultFiles) { 786 defaultFileElement.addElement(N_DEFAULTFILE).addAttribute(A_NAME, element); 787 } 788 789 // add translation rules 790 Element translationsElement = vfs.addElement(N_TRANSLATIONS); 791 792 // file translation rules 793 Element fileTransElement = translationsElement.addElement(N_FILETRANSLATIONS).addAttribute( 794 A_ENABLED, 795 String.valueOf(m_fileTranslationEnabled)); 796 for (String translation : m_fileTranslations) { 797 fileTransElement.addElement(N_TRANSLATION).setText(translation); 798 } 799 800 // folder translation rules 801 Element folderTransElement = translationsElement.addElement(N_FOLDERTRANSLATIONS).addAttribute( 802 A_ENABLED, 803 String.valueOf(m_folderTranslationEnabled)); 804 for (String translation : m_folderTranslations) { 805 folderTransElement.addElement(N_TRANSLATION).setText(translation); 806 } 807 808 // XSD translation rules 809 Element xsdTransElement = translationsElement.addElement(N_XSDTRANSLATIONS).addAttribute( 810 A_ENABLED, 811 String.valueOf(m_xsdTranslationEnabled)); 812 for (String translation : m_xsdTranslations) { 813 xsdTransElement.addElement(N_TRANSLATION).setText(translation); 814 } 815 816 Element onlineFoldersElement = vfs.addElement(N_ONLINE_FOLDERS); 817 for (String path : m_onlineFolderOptions.getPaths()) { 818 Element pathElem = onlineFoldersElement.addElement(N_PATH); 819 pathElem.setText(path); 820 } 821 for (String key : m_onlineFolderOptions.getParams().keySet()) { 822 Element paramElem = onlineFoldersElement.addElement(N_PARAM); 823 paramElem.addAttribute(A_NAME, key); 824 paramElem.setText(m_onlineFolderOptions.getParams().get(key)); 825 } 826 827 // XML content configuration 828 Element xmlContentsElement = vfs.addElement(N_XMLCONTENT); 829 830 // XML widgets 831 Element xmlWidgetsElement = xmlContentsElement.addElement(N_WIDGETS); 832 for (String widget : m_xmlContentTypeManager.getRegisteredWidgetNames()) { 833 Element widgetElement = xmlWidgetsElement.addElement(N_WIDGET).addAttribute(A_CLASS, widget); 834 for (String alias : m_xmlContentTypeManager.getRegisteredWidgetAliases(widget)) { 835 widgetElement.addElement(N_WIDGET_ALIAS).addText(alias); 836 } 837 String defaultConfiguration = m_xmlContentTypeManager.getWidgetDefaultConfiguration(widget); 838 if (CmsStringUtil.isNotEmpty(defaultConfiguration)) { 839 widgetElement.addAttribute(A_CONFIGURATION, defaultConfiguration); 840 } 841 } 842 843 // XML content types 844 Element xmlSchemaTypesElement = xmlContentsElement.addElement(N_SCHEMATYPES); 845 for (I_CmsXmlSchemaType type : m_xmlContentTypeManager.getRegisteredSchemaTypes()) { 846 I_CmsWidget widget = m_xmlContentTypeManager.getWidgetDefault(type.getTypeName()); 847 xmlSchemaTypesElement.addElement(N_SCHEMATYPE).addAttribute( 848 A_CLASS, 849 type.getClass().getName()).addAttribute(A_DEFAULTWIDGET, widget.getClass().getName()); 850 } 851 852 // return the vfs node 853 return vfs; 854 } 855 856 /** 857 * Returns the (unmodifiable) list of configured directory default files.<p> 858 * 859 * @return the (unmodifiable) list of configured directory default files 860 */ 861 public List<String> getDefaultFiles() { 862 863 return Collections.unmodifiableList(m_defaultFiles); 864 } 865 866 /** 867 * @see org.opencms.configuration.I_CmsXmlConfiguration#getDtdFilename() 868 */ 869 public String getDtdFilename() { 870 871 return CONFIGURATION_DTD_NAME; 872 } 873 874 /** 875 * Returns the file resource translator that has been initialized 876 * with the configured file translation rules.<p> 877 * 878 * @return the file resource translator 879 */ 880 public CmsResourceTranslator getFileTranslator() { 881 882 String[] array = new String[0]; 883 if (m_fileTranslationEnabled) { 884 array = new String[m_fileTranslations.size()]; 885 for (int i = 0; i < m_fileTranslations.size(); i++) { 886 array[i] = m_fileTranslations.get(i); 887 } 888 } 889 return new CmsResourceTranslator(array, true); 890 } 891 892 /** 893 * Returns the folder resource translator that has been initialized 894 * with the configured folder translation rules.<p> 895 * 896 * @return the folder resource translator 897 */ 898 public CmsResourceTranslator getFolderTranslator() { 899 900 String[] array = new String[0]; 901 if (m_folderTranslationEnabled) { 902 array = new String[m_folderTranslations.size()]; 903 for (int i = 0; i < m_folderTranslations.size(); i++) { 904 array[i] = m_folderTranslations.get(i); 905 } 906 } 907 return new CmsResourceTranslator(array, false); 908 } 909 910 /** 911 * Gets the configured online folder options. 912 * 913 * @return the online folder options 914 */ 915 public CmsOnlineFolderOptions getOnlineFolderOptions() { 916 917 return m_onlineFolderOptions; 918 } 919 920 /** 921 * Returns the initialized resource manager.<p> 922 * 923 * @return the initialized resource manager 924 */ 925 public CmsResourceManager getResourceManager() { 926 927 return m_resourceManager; 928 } 929 930 /** 931 * Returns the configured XML content type manager.<p> 932 * 933 * @return the configured XML content type manager 934 */ 935 public CmsXmlContentTypeManager getXmlContentTypeManager() { 936 937 return m_xmlContentTypeManager; 938 } 939 940 /** 941 * Returns the XSD translator that has been initialized 942 * with the configured XSD translation rules.<p> 943 * 944 * @return the XSD translator 945 */ 946 public CmsResourceTranslator getXsdTranslator() { 947 948 String[] array = m_xsdTranslationEnabled ? new String[m_xsdTranslations.size()] : new String[0]; 949 for (int i = 0; i < m_xsdTranslations.size(); i++) { 950 array[i] = m_xsdTranslations.get(i); 951 } 952 return new CmsResourceTranslator(array, true); 953 } 954 955 /** 956 * Will be called when configuration of this object is finished.<p> 957 */ 958 public void initializeFinished() { 959 960 if (CmsLog.INIT.isInfoEnabled()) { 961 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_VFS_CONFIG_FINISHED_0)); 962 } 963 } 964 965 /** 966 * Enables or disables the file translation rules.<p> 967 * 968 * @param value if <code>"true"</code>, file translation is enabled, otherwise it is disabled 969 */ 970 public void setFileTranslationEnabled(String value) { 971 972 m_fileTranslationEnabled = Boolean.valueOf(value).booleanValue(); 973 if (CmsLog.INIT.isInfoEnabled()) { 974 if (m_fileTranslationEnabled) { 975 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_VFS_FILE_TRANSLATION_ENABLE_0)); 976 } else { 977 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_VFS_FILE_TRANSLATION_DISABLE_0)); 978 } 979 } 980 } 981 982 /** 983 * Enables or disables the folder translation rules.<p> 984 * 985 * @param value if <code>"true"</code>, folder translation is enabled, otherwise it is disabled 986 */ 987 public void setFolderTranslationEnabled(String value) { 988 989 m_folderTranslationEnabled = Boolean.valueOf(value).booleanValue(); 990 if (CmsLog.INIT.isInfoEnabled()) { 991 if (m_folderTranslationEnabled) { 992 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_VFS_FOLDER_TRANSLATION_ENABLE_0)); 993 } else { 994 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_VFS_FOLDER_TRANSLATION_DISABLE_0)); 995 } 996 } 997 } 998 999 /** 1000 * Sets the generated resource manager.<p> 1001 * 1002 * @param manager the resource manager to set 1003 */ 1004 public void setResourceManager(CmsResourceManager manager) { 1005 1006 m_resourceManager = manager; 1007 } 1008 1009 /** 1010 * Sets the generated XML content type manager.<p> 1011 * 1012 * @param manager the generated XML content type manager to set 1013 */ 1014 public void setXmlContentTypeManager(CmsXmlContentTypeManager manager) { 1015 1016 if (CmsLog.INIT.isInfoEnabled()) { 1017 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_VFS_XML_CONTENT_FINISHED_0)); 1018 } 1019 m_xmlContentTypeManager = manager; 1020 } 1021 1022 /** 1023 * Enables or disables the XSD translation rules.<p> 1024 * 1025 * @param value if <code>"true"</code>, XSD translation is enabled, otherwise it is disabled 1026 */ 1027 public void setXsdTranslationEnabled(String value) { 1028 1029 m_xsdTranslationEnabled = Boolean.valueOf(value).booleanValue(); 1030 if (CmsLog.INIT.isInfoEnabled()) { 1031 if (m_xsdTranslationEnabled) { 1032 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_VFS_XSD_TRANSLATION_ENABLE_0)); 1033 } else { 1034 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_VFS_XSD_TRANSLATION_DISABLE_0)); 1035 } 1036 } 1037 } 1038 1039 /** 1040 * @see org.opencms.configuration.A_CmsXmlConfiguration#initMembers() 1041 */ 1042 @Override 1043 protected void initMembers() { 1044 1045 setXmlFileName(DEFAULT_XML_FILE_NAME); 1046 m_fileTranslations = new ArrayList<String>(); 1047 m_folderTranslations = new ArrayList<String>(); 1048 m_xsdTranslations = new ArrayList<String>(); 1049 m_defaultFiles = new ArrayList<String>(); 1050 if (CmsLog.INIT.isInfoEnabled()) { 1051 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_VFS_CONFIG_INIT_0)); 1052 } 1053 } 1054}