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