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.module; 029 030import org.opencms.db.CmsExportPoint; 031import org.opencms.file.CmsObject; 032import org.opencms.file.CmsResource; 033import org.opencms.file.CmsResourceFilter; 034import org.opencms.file.types.I_CmsResourceType; 035import org.opencms.main.CmsException; 036import org.opencms.main.CmsIllegalArgumentException; 037import org.opencms.main.CmsLog; 038import org.opencms.main.OpenCms; 039import org.opencms.security.CmsRole; 040import org.opencms.security.CmsRoleViolationException; 041import org.opencms.util.CmsFileUtil; 042import org.opencms.util.CmsStringUtil; 043import org.opencms.workplace.explorer.CmsExplorerTypeSettings; 044 045import java.io.Serializable; 046import java.util.ArrayList; 047import java.util.Collections; 048import java.util.List; 049import java.util.Map; 050import java.util.SortedMap; 051import java.util.StringTokenizer; 052import java.util.TreeMap; 053 054import org.apache.commons.logging.Log; 055 056import com.google.common.collect.Lists; 057 058/** 059 * Describes an OpenCms module.<p> 060 * 061 * OpenCms modules provide a standard mechanism to extend the OpenCms functionality. 062 * Modules can contain VFS data, Java classes and a number of configuration options.<p> 063 * 064 * @since 6.0.0 065 * 066 * @see org.opencms.module.I_CmsModuleAction 067 * @see org.opencms.module.A_CmsModuleAction 068 */ 069public class CmsModule implements Comparable<CmsModule>, Serializable { 070 071 /** The available module export modes. */ 072 public enum ExportMode { 073 /** Default export mode. */ 074 DEFAULT, 075 /** Reduced export, that omits last modification information (dates and users). */ 076 REDUCED; 077 078 /** 079 * @see java.lang.Enum#toString() 080 */ 081 @Override 082 public String toString() { 083 084 return super.toString().toLowerCase(); 085 } 086 } 087 088 /** The default date for module created / installed if not provided. */ 089 public static final long DEFAULT_DATE = 0L; 090 091 /** The log object for this class. */ 092 private static final Log LOG = CmsLog.getLog(CmsModule.class); 093 094 /** 095 * The module property key name to specifiy additional resources which are 096 * part of a module outside of {system/modules}. 097 */ 098 private static final String MODULE_PROPERTY_ADDITIONAL_RESOURCES = "additionalresources"; 099 100 /** Character to separate additional resources specified in the module properties. */ 101 private static final String MODULE_PROPERTY_ADDITIONAL_RESOURCES_SEPARATOR = ";"; 102 103 /** The serial version id. */ 104 private static final long serialVersionUID = -2639349161445831665L; 105 106 /** The module action class name. */ 107 private String m_actionClass; 108 109 /** Initialized module action instance. */ 110 private transient I_CmsModuleAction m_actionInstance; 111 112 /** The email of the author of this module. */ 113 private String m_authorEmail; 114 115 /** The name of the author of this module. */ 116 private String m_authorName; 117 118 /** True if the module's version should be auto-incremented based on module resource changes in the VFS. */ 119 private boolean m_autoIncrement; 120 121 /** Timestamp used for version auto-incrementing: if module resources have been modified after this timestamp, increment the version. */ 122 private long m_checkpointTime; 123 124 /** Flag to create the classes folders when creating the module. */ 125 private transient boolean m_createClassesFolder; 126 127 /** Flag to create the elements folder when creating the module. */ 128 private transient boolean m_createElementsFolder; 129 130 /** Flag to create the formatters folder when creating the module. */ 131 private transient boolean m_createFormattersFolder; 132 133 /** Flag to create the i18n folder when creating the module. */ 134 private transient boolean m_createI18NFolder; 135 136 /** Flag to create the lib folder when creating the module. */ 137 private transient boolean m_createLibFolder; 138 139 /** Flag to create the module folder when creating the module. */ 140 private transient boolean m_createModuleFolder; 141 142 /** Flag to create the resources folder when creating the module. */ 143 private transient boolean m_createResourcesFolder; 144 145 /** Flag to create the schemas folder when creating the module. */ 146 private transient boolean m_createSchemasFolder; 147 148 /** Flag to create the template folder when creating the module. */ 149 private transient boolean m_createTemplateFolder; 150 151 /** The date this module was created by the author. */ 152 private long m_dateCreated; 153 154 /** The date this module was installed. */ 155 private long m_dateInstalled; 156 157 /** List of dependencies of this module. */ 158 private List<CmsModuleDependency> m_dependencies; 159 160 /** The description of this module. */ 161 private String m_description; 162 163 /** List of VFS resources that do not belong to this module. 164 * In particular used for files / folders in folders that belong to the module. 165 */ 166 private List<String> m_excluderesources; 167 168 /** The explorer type settings. */ 169 private List<CmsExplorerTypeSettings> m_explorerTypeSettings; 170 171 /** The export mode to use for the module. */ 172 private ExportMode m_exportMode; 173 174 /** List of export points added by this module. */ 175 private List<CmsExportPoint> m_exportPoints; 176 177 /** The export version (this is only used for module objects which have been read from a zip file). */ 178 private String m_exportVersion; 179 180 /** Indicates if this modules configuration has already been frozen. */ 181 private transient boolean m_frozen; 182 183 /** The group of the module. */ 184 private String m_group; 185 186 /** True if the module has a fixed import site. */ 187 private boolean m_hasImportSite; 188 189 /** The script to execute when the module is imported. */ 190 private String m_importScript; 191 192 /** The name of this module, must be a valid Java package name. */ 193 private String m_name; 194 195 /** The "nice" display name of this module. */ 196 private String m_niceName; 197 198 /** A timestamp from the time this object was created. */ 199 private long m_objectCreateTime = System.currentTimeMillis(); 200 201 /** The additional configuration parameters of this module. */ 202 private SortedMap<String, String> m_parameters; 203 204 /** List of VFS resources that belong to this module. */ 205 private List<String> m_resources; 206 207 /** The list of additional resource types. */ 208 private transient List<I_CmsResourceType> m_resourceTypes; 209 210 /** The module site. */ 211 private String m_site; 212 213 /** The name of the user who installed this module. */ 214 private String m_userInstalled; 215 216 /** The version of this module. */ 217 private CmsModuleVersion m_version; 218 219 /** 220 * Creates a new, empty CmsModule object.<p> 221 */ 222 public CmsModule() { 223 224 m_version = new CmsModuleVersion(CmsModuleVersion.DEFAULT_VERSION); 225 m_resources = Collections.emptyList(); 226 m_excluderesources = Collections.emptyList(); 227 m_exportPoints = Collections.emptyList(); 228 m_dependencies = Collections.emptyList(); 229 m_resourceTypes = Collections.emptyList(); 230 m_explorerTypeSettings = Collections.emptyList(); 231 m_parameters = new TreeMap<String, String>(); 232 m_exportMode = ExportMode.DEFAULT; 233 } 234 235 /** 236 * Creates a new module description with the specified values.<p> 237 * 238 * @param name the name of this module, must be a valid Java package name 239 * @param niceName the "nice" display name of this module 240 * @param group the group of this module 241 * @param actionClass the (optional) module class name 242 * @param importScript the script to execute when the module is imported 243 * @param site the site the module belongs to 244 * @param isImportSite true if the module site should be used as a fixed import site 245 * @param exportMode the export mode that should be used for the module 246 * @param description the description of this module 247 * @param version the version of this module 248 * @param authorName the name of the author of this module 249 * @param authorEmail the email of the author of this module 250 * @param dateCreated the date this module was created by the author 251 * @param userInstalled the name of the user who uploaded this module 252 * @param dateInstalled the date this module was uploaded 253 * @param dependencies a list of dependencies of this module 254 * @param exportPoints a list of export point added by this module 255 * @param resources a list of VFS resources that belong to this module 256 * @param excluderesources a list of VFS resources that are exclude from the module's resources 257 * @param parameters the parameters for this module 258 */ 259 public CmsModule( 260 String name, 261 String niceName, 262 String group, 263 String actionClass, 264 String importScript, 265 String site, 266 boolean isImportSite, 267 ExportMode exportMode, 268 String description, 269 CmsModuleVersion version, 270 String authorName, 271 String authorEmail, 272 long dateCreated, 273 String userInstalled, 274 long dateInstalled, 275 List<CmsModuleDependency> dependencies, 276 List<CmsExportPoint> exportPoints, 277 List<String> resources, 278 List<String> excluderesources, 279 Map<String, String> parameters) { 280 281 super(); 282 m_name = name; 283 setNiceName(niceName); 284 setActionClass(actionClass); 285 setGroup(group); 286 287 m_exportMode = null == exportMode ? ExportMode.DEFAULT : exportMode; 288 289 if (CmsStringUtil.isEmpty(description)) { 290 m_description = ""; 291 } else { 292 m_description = description; 293 } 294 m_version = version; 295 if (CmsStringUtil.isEmpty(authorName)) { 296 m_authorName = ""; 297 } else { 298 m_authorName = authorName; 299 } 300 if (CmsStringUtil.isEmpty(authorEmail)) { 301 m_authorEmail = ""; 302 } else { 303 m_authorEmail = authorEmail; 304 } 305 // remove milisecounds 306 m_dateCreated = (dateCreated / 1000L) * 1000L; 307 if (CmsStringUtil.isEmpty(userInstalled)) { 308 m_userInstalled = ""; 309 } else { 310 m_userInstalled = userInstalled; 311 } 312 m_dateInstalled = (dateInstalled / 1000L) * 1000L; 313 if (dependencies == null) { 314 m_dependencies = Collections.emptyList(); 315 } else { 316 m_dependencies = Collections.unmodifiableList(dependencies); 317 } 318 if (exportPoints == null) { 319 m_exportPoints = Collections.emptyList(); 320 } else { 321 m_exportPoints = Collections.unmodifiableList(exportPoints); 322 } 323 if (resources == null) { 324 m_resources = Collections.emptyList(); 325 } else { 326 m_resources = Collections.unmodifiableList(resources); 327 } 328 if (excluderesources == null) { 329 m_excluderesources = Collections.emptyList(); 330 } else { 331 m_excluderesources = Collections.unmodifiableList(excluderesources); 332 } 333 if (parameters == null) { 334 m_parameters = new TreeMap<String, String>(); 335 } else { 336 m_parameters = new TreeMap<String, String>(parameters); 337 } 338 339 m_site = site; 340 341 m_hasImportSite = isImportSite; 342 343 m_importScript = importScript; 344 345 initOldAdditionalResources(); 346 347 if (LOG.isDebugEnabled()) { 348 LOG.debug(Messages.get().getBundle().key(Messages.LOG_MODULE_INSTANCE_CREATED_1, m_name)); 349 } 350 m_resourceTypes = Collections.emptyList(); 351 m_explorerTypeSettings = Collections.emptyList(); 352 } 353 354 /** Determines the resources that are: 355 * <ul> 356 * <li>accessible with the provided {@link CmsObject},</li> 357 * <li>part of the <code>moduleResources</code> (or in a folder of these resources) and</li> 358 * <li><em>not</em> contained in <code>excludedResources</code> (or a folder of these resources).</li> 359 * </ul> 360 * and adds the to <code>result</code> 361 * 362 * @param result the resource list, that gets extended by the calculated resources. 363 * @param cms the {@link CmsObject} used to read resources. 364 * @param moduleResources the resources to include. 365 * @param excludeResources the site paths of the resources to exclude. 366 * @throws CmsException thrown if reading resources fails. 367 */ 368 public static void addCalculatedModuleResources( 369 List<CmsResource> result, 370 final CmsObject cms, 371 final List<CmsResource> moduleResources, 372 final List<String> excludeResources) 373 throws CmsException { 374 375 for (CmsResource resource : moduleResources) { 376 377 String sitePath = cms.getSitePath(resource); 378 379 List<String> excludedSubResources = getExcludedForResource(sitePath, excludeResources); 380 381 // check if resources have to be excluded 382 if (excludedSubResources.isEmpty()) { 383 // no resource has to be excluded - add the whole resource 384 // (that is, also all resources in the folder, if the resource is a folder) 385 result.add(resource); 386 } else { 387 // cannot add the complete resource (i.e., including the whole sub-tree) 388 if (CmsStringUtil.comparePaths(sitePath, excludedSubResources.get(0))) { 389 // the resource itself is excluded -> do not add it and check the next resource 390 continue; 391 } 392 // try to include sub-resources. 393 List<CmsResource> subResources = cms.readResources(sitePath, CmsResourceFilter.ALL, false); 394 addCalculatedModuleResources(result, cms, subResources, excludedSubResources); 395 } 396 } 397 398 } 399 400 /** Calculates the resources belonging to the module, taking excluded resources and readability of resources into account, 401 * and returns site paths of the module resources.<p> 402 * For more details of the returned resource, see {@link #calculateModuleResources(CmsObject, CmsModule)}. 403 * 404 * @param cms the {@link CmsObject} used to read the resources. 405 * @param module the module, for which the resources should be calculated 406 * @return the calculated module resources 407 * @throws CmsException thrown if reading resources fails. 408 */ 409 public static List<String> calculateModuleResourceNames(final CmsObject cms, final CmsModule module) 410 throws CmsException { 411 412 // adjust the site root, if necessary 413 CmsObject cmsClone = adjustSiteRootIfNecessary(cms, module); 414 415 // calculate the module resources 416 List<CmsResource> moduleResources = calculateModuleResources(cmsClone, module); 417 418 // get the site paths 419 List<String> moduleResouceNames = new ArrayList<String>(moduleResources.size()); 420 for (CmsResource resource : moduleResources) { 421 moduleResouceNames.add(cmsClone.getSitePath(resource)); 422 } 423 return moduleResouceNames; 424 } 425 426 /** Calculates and returns the resources belonging to the module, taking excluded resources and readability of resources into account. 427 * The list of returned resources contains: 428 * <ul> 429 * <li>Only resources that are readable (present at the system and accessible with the provided {@link CmsObject}</li> 430 * <li>Only the resource for a folder, if <em>all</em> resources in the folder belong to the module.</li> 431 * <li>Only resources that are specified as module resources and <em>not</em> excluded by the module's exclude resources.</li> 432 * </ul> 433 * 434 * @param cms the {@link CmsObject} used to read the resources. 435 * @param module the module, for which the resources should be calculated 436 * @return the calculated module resources 437 * @throws CmsException thrown if reading resources fails. 438 */ 439 public static List<CmsResource> calculateModuleResources(final CmsObject cms, final CmsModule module) 440 throws CmsException { 441 442 CmsObject cmsClone = adjustSiteRootIfNecessary(cms, module); 443 List<CmsResource> result = null; 444 List<String> excluded = CmsFileUtil.removeRedundancies(module.getExcludeResources()); 445 excluded = removeNonAccessible(cmsClone, excluded); 446 List<String> resourceSitePaths = CmsFileUtil.removeRedundancies(module.getResources()); 447 resourceSitePaths = removeNonAccessible(cmsClone, resourceSitePaths); 448 449 List<CmsResource> moduleResources = new ArrayList<CmsResource>(resourceSitePaths.size()); 450 for (String resourceSitePath : resourceSitePaths) { 451 // assumes resources are accessible - already checked aboveremoveNonAccessible 452 CmsResource resource = cmsClone.readResource(resourceSitePath); 453 moduleResources.add(resource); 454 } 455 456 if (excluded.isEmpty()) { 457 result = moduleResources; 458 } else { 459 result = new ArrayList<CmsResource>(); 460 461 addCalculatedModuleResources(result, cmsClone, moduleResources, excluded); 462 463 } 464 return result; 465 466 } 467 468 /** Adjusts the site root and returns a cloned CmsObject, iff the module has set an import site that differs 469 * from the site root of the CmsObject provided as argument. Otherwise returns the provided CmsObject unchanged. 470 * @param cms The original CmsObject. 471 * @param module The module where the import site is read from. 472 * @return The original CmsObject, or, if necessary, a clone with adjusted site root 473 * @throws CmsException see {@link OpenCms#initCmsObject(CmsObject)} 474 */ 475 private static CmsObject adjustSiteRootIfNecessary(final CmsObject cms, final CmsModule module) 476 throws CmsException { 477 478 CmsObject cmsClone; 479 if ((null == module.getSite()) || cms.getRequestContext().getSiteRoot().equals(module.getSite())) { 480 cmsClone = cms; 481 } else { 482 cmsClone = OpenCms.initCmsObject(cms); 483 cmsClone.getRequestContext().setSiteRoot(module.getSite()); 484 } 485 486 return cmsClone; 487 } 488 489 /** Returns only the resource names starting with the provided <code>sitePath</code>. 490 * 491 * @param sitePath the site relative path, all paths should start with. 492 * @param excluded the paths to filter. 493 * @return the paths from <code>excluded</code>, that start with <code>sitePath</code>. 494 */ 495 private static List<String> getExcludedForResource(final String sitePath, final List<String> excluded) { 496 497 List<String> result = new ArrayList<String>(); 498 for (String exclude : excluded) { 499 if (CmsStringUtil.isPrefixPath(sitePath, exclude)) { 500 result.add(exclude); 501 } 502 } 503 return result; 504 } 505 506 /** Removes the resources not accessible with the provided {@link CmsObject}. 507 * 508 * @param cms the {@link CmsObject} used to read the resources. 509 * @param sitePaths site relative paths of the resources that should be checked for accessibility. 510 * @return site paths of the accessible resources. 511 */ 512 private static List<String> removeNonAccessible(CmsObject cms, List<String> sitePaths) { 513 514 List<String> result = new ArrayList<String>(sitePaths.size()); 515 for (String sitePath : sitePaths) { 516 if (cms.existsResource(sitePath, CmsResourceFilter.IGNORE_EXPIRATION)) { 517 result.add(sitePath); 518 } 519 } 520 return result; 521 } 522 523 /** 524 * Checks if this module depends on another given module, 525 * will return the dependency, or <code>null</code> if no dependency was found.<p> 526 * 527 * @param module the other module to check against 528 * @return the dependency, or null if no dependency was found 529 */ 530 public CmsModuleDependency checkDependency(CmsModule module) { 531 532 CmsModuleDependency otherDepdendency = new CmsModuleDependency(module.getName(), module.getVersion()); 533 534 // loop through all the dependencies 535 for (int i = 0; i < m_dependencies.size(); i++) { 536 CmsModuleDependency dependency = m_dependencies.get(i); 537 if (dependency.dependesOn(otherDepdendency)) { 538 // short circuit here 539 return dependency; 540 } 541 } 542 543 // no dependency was found 544 return null; 545 } 546 547 /** 548 * Checks if all resources of the module are present.<p> 549 * 550 * @param cms an initialized OpenCms user context which must have read access to all module resources 551 * 552 * @throws CmsIllegalArgumentException in case not all module resources exist or can be read with the given OpenCms user context 553 */ 554 public void checkResources(CmsObject cms) throws CmsIllegalArgumentException { 555 556 CmsFileUtil.checkResources(cms, getResources()); 557 } 558 559 /** 560 * Clones a CmsModule which is not set to frozen.<p> 561 * This clones module can be used to be update the module information. 562 * 563 * @see java.lang.Object#clone() 564 */ 565 @Override 566 public CmsModule clone() { 567 568 // create a copy of the module 569 CmsModule result = new CmsModule( 570 m_name, 571 m_niceName, 572 m_group, 573 m_actionClass, 574 m_importScript, 575 m_site, 576 m_hasImportSite, 577 m_exportMode, 578 m_description, 579 m_version, 580 m_authorName, 581 m_authorEmail, 582 m_dateCreated, 583 m_userInstalled, 584 m_dateInstalled, 585 m_dependencies, 586 m_exportPoints, 587 m_resources, 588 m_excluderesources, 589 m_parameters); 590 // and set its frozen state to false 591 result.m_frozen = false; 592 593 if (getExplorerTypes() != null) { 594 List<CmsExplorerTypeSettings> settings = new ArrayList<CmsExplorerTypeSettings>(); 595 for (CmsExplorerTypeSettings setting : getExplorerTypes()) { 596 settings.add((CmsExplorerTypeSettings)setting.clone()); 597 } 598 result.setExplorerTypes(settings); 599 } 600 if (getResourceTypes() != null) { 601 // TODO: The resource types must be cloned also, otherwise modification will effect the origin also 602 result.setResourceTypes(new ArrayList<I_CmsResourceType>(getResourceTypes())); 603 } 604 if (getDependencies() != null) { 605 List<CmsModuleDependency> deps = new ArrayList<CmsModuleDependency>(); 606 for (CmsModuleDependency dep : getDependencies()) { 607 deps.add((CmsModuleDependency)dep.clone()); 608 } 609 result.setDependencies(new ArrayList<CmsModuleDependency>(getDependencies())); 610 } 611 if (getExportPoints() != null) { 612 List<CmsExportPoint> exps = new ArrayList<CmsExportPoint>(); 613 for (CmsExportPoint exp : getExportPoints()) { 614 exps.add((CmsExportPoint)exp.clone()); 615 } 616 result.setExportPoints(exps); 617 } 618 619 result.setAutoIncrement(m_autoIncrement); 620 result.setCheckpointTime(m_checkpointTime); 621 622 result.setCreateClassesFolder(m_createClassesFolder); 623 result.setCreateElementsFolder(m_createElementsFolder); 624 result.setCreateLibFolder(m_createLibFolder); 625 result.setCreateModuleFolder(m_createModuleFolder); 626 result.setCreateResourcesFolder(m_createResourcesFolder); 627 result.setCreateSchemasFolder(m_createSchemasFolder); 628 result.setCreateTemplateFolder(m_createTemplateFolder); 629 result.setCreateFormattersFolder(m_createFormattersFolder); 630 631 result.setResources(new ArrayList<String>(m_resources)); 632 result.setExcludeResources(new ArrayList<String>(m_excluderesources)); 633 634 return result; 635 } 636 637 /** 638 * @see java.lang.Comparable#compareTo(java.lang.Object) 639 */ 640 public int compareTo(CmsModule obj) { 641 642 if (obj == this) { 643 return 0; 644 } 645 return m_name.compareTo(obj.m_name); 646 } 647 648 /** 649 * Two instances of a module are considered equal if their name is equal.<p> 650 * 651 * @param obj the object to compare 652 * 653 * @return true if the objects are equal 654 * 655 * @see java.lang.Object#equals(java.lang.Object) 656 * @see #isIdentical(CmsModule) 657 */ 658 @Override 659 public boolean equals(Object obj) { 660 661 if (obj == this) { 662 return true; 663 } 664 if (obj instanceof CmsModule) { 665 return ((CmsModule)obj).m_name.equals(m_name); 666 } 667 return false; 668 } 669 670 /** 671 * Returns the class name of this modules (optional) action class.<p> 672 * 673 * If this module does not use an action class, 674 * <code>null</code> is returned.<p> 675 * 676 * @return the class name of this modules (optional) action class 677 */ 678 public String getActionClass() { 679 680 return m_actionClass; 681 } 682 683 /** 684 * Returns the module action instance of this module, or <code>null</code> 685 * if no module action instance is configured.<p> 686 * 687 * @return the module action instance of this module 688 */ 689 public I_CmsModuleAction getActionInstance() { 690 691 return m_actionInstance; 692 } 693 694 /** 695 * Returns the email of the module author.<p> 696 * 697 * @return the email of the module author 698 */ 699 public String getAuthorEmail() { 700 701 return m_authorEmail; 702 } 703 704 /** 705 * Returns the name of the author of this module.<p> 706 * 707 * @return the name of the author of this module 708 */ 709 public String getAuthorName() { 710 711 return m_authorName; 712 } 713 714 /** 715 * Gets the module checkpoint time.<p> 716 * 717 * This timestamp is used for auto-incrementing the version: if module resources have been modified in the VFS after this timestamp, increment 718 * the version.<p> 719 * 720 * Note: This is not exported in the manifest. * 721 * 722 * @return the checkpoint timestamp 723 */ 724 public long getCheckpointTime() { 725 726 return m_checkpointTime; 727 } 728 729 /** 730 * Gets the module configuration path.<p> 731 * 732 * @return the module configuration path 733 */ 734 public String getConfigurationPath() { 735 736 String parameter = getParameter("config.sitemap"); 737 if (parameter != null) { 738 return parameter; 739 } else { 740 return "/system/modules/" + getName() + "/.config"; 741 } 742 } 743 744 /** 745 * Returns the date this module was created by the author.<p> 746 * 747 * @return the date this module was created by the author 748 */ 749 public long getDateCreated() { 750 751 return m_dateCreated; 752 } 753 754 /** 755 * Returns the date this module was uploaded.<p> 756 * 757 * @return the date this module was uploaded 758 */ 759 public long getDateInstalled() { 760 761 return m_dateInstalled; 762 } 763 764 /** 765 * Returns the list of dependencies of this module.<p> 766 * 767 * @return the list of dependencies of this module 768 */ 769 public List<CmsModuleDependency> getDependencies() { 770 771 return m_dependencies; 772 } 773 774 /** 775 * Returns the description of this module.<p> 776 * 777 * @return the description of this module 778 */ 779 public String getDescription() { 780 781 return m_description; 782 } 783 784 /** 785 * Returns the list of VFS resources that do not belong to this module.<p> 786 * In particular, files / folders that would be included otherwise, 787 * considering the module resources.<p> 788 * 789 * @return the list of VFS resources that do not belong to this module 790 */ 791 public List<String> getExcludeResources() { 792 793 return m_excluderesources; 794 } 795 796 /** 797 * Returns the list of explorer resource types that belong to this module.<p> 798 * 799 * @return the list of explorer resource types that belong to this module 800 */ 801 public List<CmsExplorerTypeSettings> getExplorerTypes() { 802 803 return m_explorerTypeSettings; 804 } 805 806 /** Returns the export mode specified for the module. 807 * @return the module's export mode. 808 */ 809 public ExportMode getExportMode() { 810 811 return m_exportMode; 812 } 813 814 /** 815 * Returns the list of export point added by this module.<p> 816 * 817 * @return the list of export point added by this module 818 */ 819 public List<CmsExportPoint> getExportPoints() { 820 821 return m_exportPoints; 822 } 823 824 /** 825 * Gets the export version.<p> 826 * 827 * This is only used for module objects which have been read from a zip file. 828 * 829 * @return the export version 830 */ 831 public String getExportVersion() { 832 833 return m_exportVersion; 834 } 835 836 /** 837 * Returns the group name of this module.<p> 838 * 839 * @return the group name of this module 840 */ 841 public String getGroup() { 842 843 return m_group; 844 } 845 846 /** 847 * Returns true if the module has an import site set.<p> 848 * 849 * @return true if the module has an import site set 850 */ 851 public boolean getHasImportSite() { 852 853 return hasImportSite(); 854 } 855 856 /** 857 * Returns the importScript.<p> 858 * 859 * @return the importScript 860 */ 861 public String getImportScript() { 862 863 return m_importScript; 864 } 865 866 /** 867 * Gets the import site.<p> 868 * 869 * If this is not empty, then it will be used as the site root for importing and exporting this module.<p> 870 * 871 * @return the import site 872 */ 873 public String getImportSite() { 874 875 if (m_hasImportSite) { 876 return m_site; 877 } else { 878 return null; 879 } 880 881 } 882 883 /** 884 * Returns the name of this module.<p> 885 * 886 * The module name must be a valid java package name.<p> 887 * 888 * @return the name of this module 889 */ 890 public String getName() { 891 892 return m_name; 893 } 894 895 /** 896 * Returns the "nice" display name of this module.<p> 897 * 898 * @return the "nice" display name of this module 899 */ 900 public String getNiceName() { 901 902 return m_niceName; 903 } 904 905 /** 906 * Gets the timestamp of this object's creation time.<p> 907 * 908 * @return the object creation timestamp 909 */ 910 public long getObjectCreateTime() { 911 912 return m_objectCreateTime; 913 } 914 915 /** 916 * Returns a parameter value from the module parameters.<p> 917 * 918 * @param key the parameter to return the value for 919 * @return the parameter value from the module parameters 920 */ 921 public String getParameter(String key) { 922 923 return m_parameters.get(key); 924 } 925 926 /** 927 * Returns a parameter value from the module parameters, 928 * or a given default value in case the parameter is not set.<p> 929 * 930 * @param key the parameter to return the value for 931 * @param defaultValue the default value in case there is no value stored for this key 932 * @return the parameter value from the module parameters 933 */ 934 public String getParameter(String key, String defaultValue) { 935 936 String value = m_parameters.get(key); 937 return (value != null) ? value : defaultValue; 938 } 939 940 /** 941 * Returns the configured (immutable) module parameters.<p> 942 * 943 * @return the configured (immutable) module parameters 944 */ 945 public SortedMap<String, String> getParameters() { 946 947 return m_parameters; 948 } 949 950 /** 951 * Returns the list of VFS resources that belong to this module.<p> 952 * 953 * @return the list of VFS resources that belong to this module 954 */ 955 public List<String> getResources() { 956 957 return m_resources; 958 } 959 960 /** 961 * Returns the list of additional resource types that belong to this module.<p> 962 * 963 * @return the list of additional resource types that belong to this module 964 */ 965 public List<I_CmsResourceType> getResourceTypes() { 966 967 return m_resourceTypes; 968 } 969 970 /** 971 * Gets the module's site.<p> 972 * 973 * @return the site of the module 974 */ 975 public String getSite() { 976 977 return m_site; 978 } 979 980 /** 981 * Returns the name of the user who uploaded this module.<p> 982 * 983 * @return the name of the user who uploaded this module 984 */ 985 public String getUserInstalled() { 986 987 return m_userInstalled; 988 } 989 990 /** 991 * Returns the version of this module.<p> 992 * 993 * @return the version of this module 994 */ 995 public CmsModuleVersion getVersion() { 996 997 return m_version; 998 } 999 1000 /** 1001 * Gets the version number as a string.<p> 1002 * 1003 * @return the version number as a string 1004 */ 1005 public String getVersionStr() { 1006 1007 return m_version.toString(); 1008 } 1009 1010 /** 1011 * @see java.lang.Object#hashCode() 1012 */ 1013 @Override 1014 public int hashCode() { 1015 1016 return m_name.hashCode(); 1017 } 1018 1019 /** 1020 * Returns true if the module has a fixed import site.<p> 1021 * 1022 * @return true if the module has a fixed import site 1023 */ 1024 public boolean hasImportSite() { 1025 1026 return m_hasImportSite; 1027 } 1028 1029 /** 1030 * Determines if the module haas resources whose site is undefined.<p> 1031 * 1032 * @return true if there are module resources with an undefined site 1033 */ 1034 public boolean hasModuleResourcesWithUndefinedSite() { 1035 1036 if (getSite() == null) { 1037 for (String modRes : getResources()) { 1038 if (!CmsStringUtil.isPrefixPath("/system/", modRes) 1039 && !OpenCms.getSiteManager().startsWithShared(modRes)) { 1040 return true; 1041 } 1042 1043 } 1044 } 1045 return false; 1046 } 1047 1048 /** 1049 * Check if all module resources are under /system or the shared folder.<p> 1050 * 1051 * @return true if the module only has resources under system or the shared folder 1052 */ 1053 public boolean hasOnlySystemAndSharedResources() { 1054 1055 for (String modRes : getResources()) { 1056 if (!CmsStringUtil.isPrefixPath("/system/", modRes) && !OpenCms.getSiteManager().startsWithShared(modRes)) { 1057 return false; 1058 } 1059 } 1060 return true; 1061 } 1062 1063 /** 1064 * Returns true if version auto-incrementation is enabled for this module. 1065 * 1066 * @return true if version auto-incrementation is enabled for this module 1067 */ 1068 public boolean isAutoIncrement() { 1069 1070 return m_autoIncrement; 1071 } 1072 1073 /** 1074 * Returns the createClassesFolder flag.<p> 1075 * 1076 * @return the createClassesFolder flag 1077 */ 1078 public boolean isCreateClassesFolder() { 1079 1080 return m_createClassesFolder; 1081 } 1082 1083 /** 1084 * Returns the createElementsFolder flag.<p> 1085 * 1086 * @return the createElementsFolder flag 1087 */ 1088 public boolean isCreateElementsFolder() { 1089 1090 return m_createElementsFolder; 1091 } 1092 1093 /** 1094 * Returns the createFormattersFolder flag.<p> 1095 * 1096 * @return the createFormattersFolder flag 1097 */ 1098 public boolean isCreateFormattersFolder() { 1099 1100 return m_createFormattersFolder; 1101 } 1102 1103 /** 1104 * Returns the createI18NFolder flag.<p> 1105 * 1106 * @return boolean 1107 */ 1108 public boolean isCreateI18NFolder() { 1109 1110 return m_createI18NFolder; 1111 } 1112 1113 /** 1114 * Returns the createLibFolder flag.<p> 1115 * 1116 * @return the createLibFolder flag 1117 */ 1118 public boolean isCreateLibFolder() { 1119 1120 return m_createLibFolder; 1121 } 1122 1123 /** 1124 * Returns the createModuleFolder flag.<p> 1125 * 1126 * @return the createModuleFolder flag 1127 */ 1128 public boolean isCreateModuleFolder() { 1129 1130 return m_createModuleFolder; 1131 } 1132 1133 /** 1134 * Returns the createResourcesFolder flag.<p> 1135 * 1136 * @return the createResourcesFolder flag 1137 */ 1138 public boolean isCreateResourcesFolder() { 1139 1140 return m_createResourcesFolder; 1141 } 1142 1143 /** 1144 * Returns the createSchemasFolder flag.<p> 1145 * 1146 * @return the createSchemasFolder flag 1147 */ 1148 public boolean isCreateSchemasFolder() { 1149 1150 return m_createSchemasFolder; 1151 } 1152 1153 /** 1154 * Returns the createTemplateFolder flag.<p> 1155 * 1156 * @return the createTemplateFolder flag 1157 */ 1158 public boolean isCreateTemplateFolder() { 1159 1160 return m_createTemplateFolder; 1161 } 1162 1163 /** 1164 * Checks if this module is identical with another module.<p> 1165 * 1166 * Modules A, B are <b>identical</b> if <i>all</i> values of A are equal to B. 1167 * The values from {@link #getUserInstalled()} and {@link #getDateInstalled()} 1168 * are ignored for this test.<p> 1169 * 1170 * Modules A, B are <b>equal</b> if just the name of A is equal to the name of B.<p> 1171 * 1172 * @param other the module to compare with 1173 * 1174 * @return if the modules are identical 1175 * 1176 * @see #equals(Object) 1177 */ 1178 public boolean isIdentical(CmsModule other) { 1179 1180 // some code redundancy here but this is easier to debug 1181 if (!isEqual(m_name, other.m_name)) { 1182 return false; 1183 } 1184 if (!isEqual(m_niceName, other.m_niceName)) { 1185 return false; 1186 } 1187 if (!isEqual(m_version, other.m_version)) { 1188 return false; 1189 } 1190 if (!isEqual(m_actionClass, other.m_actionClass)) { 1191 return false; 1192 } 1193 if (!isEqual(m_description, other.m_description)) { 1194 return false; 1195 } 1196 if (!isEqual(m_authorName, other.m_authorName)) { 1197 return false; 1198 } 1199 if (!isEqual(m_authorEmail, other.m_authorEmail)) { 1200 return false; 1201 } 1202 if (m_dateCreated != other.m_dateCreated) { 1203 return false; 1204 } 1205 return true; 1206 } 1207 1208 /** Checks, if the module should use the reduced export mode. 1209 * @return if reduce export mode should be used <code>true</code>, otherwise <code>false</code>. 1210 */ 1211 public boolean isReducedExportMode() { 1212 1213 return ExportMode.REDUCED.equals(m_exportMode); 1214 } 1215 1216 /** 1217 * Sets the class name of this modules (optional) action class.<p> 1218 * 1219 * Providing <code>null</code> as a value indicates that this module does not use an action class.<p> 1220 * 1221 * <i>Please note:</i>It's not possible to set the action class name once the module 1222 * configuration has been frozen.<p> 1223 * 1224 * @param value the class name of this modules (optional) action class to set 1225 */ 1226 public void setActionClass(String value) { 1227 1228 checkFrozen(); 1229 if (CmsStringUtil.isEmpty(value)) { 1230 m_actionClass = null; 1231 } else { 1232 if (!CmsStringUtil.isValidJavaClassName(value)) { 1233 throw new CmsIllegalArgumentException( 1234 Messages.get().container(Messages.ERR_MODULE_ACTION_CLASS_2, value, getName())); 1235 } 1236 m_actionClass = value; 1237 } 1238 } 1239 1240 /** 1241 * Sets the author email of this module.<p> 1242 * 1243 * 1244 * <i>Please note:</i>It's not possible to set the modules author email once the module 1245 * configuration has been frozen.<p> 1246 * 1247 * @param value the module description to set 1248 */ 1249 public void setAuthorEmail(String value) { 1250 1251 checkFrozen(); 1252 m_authorEmail = value.trim(); 1253 } 1254 1255 /** 1256 * Sets the author name of this module.<p> 1257 * 1258 * 1259 * <i>Please note:</i>It's not possible to set the modules author name once the module 1260 * configuration has been frozen.<p> 1261 * 1262 * @param value the module description to set 1263 */ 1264 public void setAuthorName(String value) { 1265 1266 checkFrozen(); 1267 m_authorName = value.trim(); 1268 } 1269 1270 /** 1271 * Sets auto-increment mode. 1272 * 1273 * @param autoIncrement true if version auto-incrementation should be enabled 1274 */ 1275 public void setAutoIncrement(boolean autoIncrement) { 1276 1277 m_autoIncrement = autoIncrement; 1278 } 1279 1280 /** 1281 * Sets the module checkpoint time. 1282 * 1283 * @param checkpointTime the module checkpoint time 1284 */ 1285 public void setCheckpointTime(long checkpointTime) { 1286 1287 m_checkpointTime = checkpointTime; 1288 } 1289 1290 /** 1291 * Sets the createClassesFolder flag.<p> 1292 * 1293 * @param createClassesFolder the createClassesFolder flag to set 1294 */ 1295 public void setCreateClassesFolder(boolean createClassesFolder) { 1296 1297 m_createClassesFolder = createClassesFolder; 1298 } 1299 1300 /** 1301 * Sets the createElementsFolder flag.<p> 1302 * 1303 * @param createElementsFolder the createElementsFolder flag to set 1304 */ 1305 public void setCreateElementsFolder(boolean createElementsFolder) { 1306 1307 m_createElementsFolder = createElementsFolder; 1308 } 1309 1310 /** 1311 * Sets the createFormattersFolder flag.<p> 1312 * 1313 * @param createFormattersFolder the createFormattersFolder flag to set 1314 */ 1315 public void setCreateFormattersFolder(boolean createFormattersFolder) { 1316 1317 m_createFormattersFolder = createFormattersFolder; 1318 } 1319 1320 /** 1321 * Sets the createI18NFolder flag.<p> 1322 * 1323 * @param createI18NFolder boolean 1324 */ 1325 public void setCreateI18NFolder(boolean createI18NFolder) { 1326 1327 m_createI18NFolder = createI18NFolder; 1328 } 1329 1330 /** 1331 * Sets the createLibFolder flag.<p> 1332 * 1333 * @param createLibFolder the createLibFolder flag to set 1334 */ 1335 public void setCreateLibFolder(boolean createLibFolder) { 1336 1337 m_createLibFolder = createLibFolder; 1338 } 1339 1340 /** 1341 * Sets the createModuleFolder flag.<p> 1342 * 1343 * @param createModuleFolder the createModuleFolder flag to set 1344 */ 1345 public void setCreateModuleFolder(boolean createModuleFolder) { 1346 1347 m_createModuleFolder = createModuleFolder; 1348 } 1349 1350 /** 1351 * Sets the createResourcesFolder flag.<p> 1352 * 1353 * @param createResourcesFolder the createResourcesFolder flag to set 1354 */ 1355 public void setCreateResourcesFolder(boolean createResourcesFolder) { 1356 1357 m_createResourcesFolder = createResourcesFolder; 1358 } 1359 1360 /** 1361 * Sets the createSchemasFolder flag .<p> 1362 * 1363 * @param createSchemasFolder the createSchemasFolder flag to set 1364 */ 1365 public void setCreateSchemasFolder(boolean createSchemasFolder) { 1366 1367 m_createSchemasFolder = createSchemasFolder; 1368 } 1369 1370 /** 1371 * Sets the createTemplateFolder flag .<p> 1372 * 1373 * @param createTemplateFolder the createTemplateFolder flag to set 1374 */ 1375 public void setCreateTemplateFolder(boolean createTemplateFolder) { 1376 1377 m_createTemplateFolder = createTemplateFolder; 1378 } 1379 1380 /** 1381 * Sets the date created of this module.<p> 1382 * 1383 * 1384 * <i>Please note:</i>It's not possible to set the module date created once the module 1385 * configuration has been frozen.<p> 1386 * 1387 * @param value the date created to set 1388 */ 1389 public void setDateCreated(long value) { 1390 1391 checkFrozen(); 1392 m_dateCreated = value; 1393 } 1394 1395 /** 1396 * Sets the installation date of this module.<p> 1397 * 1398 * 1399 * <i>Please note:</i>It's not possible to set the installation date once the module 1400 * configuration has been frozen.<p> 1401 * 1402 * @param value the installation date this module 1403 */ 1404 public void setDateInstalled(long value) { 1405 1406 checkFrozen(); 1407 m_dateInstalled = value; 1408 } 1409 1410 /** 1411 * Sets the list of module dependencies.<p> 1412 * 1413 * @param dependencies list of module dependencies 1414 */ 1415 public void setDependencies(List<CmsModuleDependency> dependencies) { 1416 1417 checkFrozen(); 1418 m_dependencies = dependencies; 1419 } 1420 1421 /** 1422 * Sets the description of this module.<p> 1423 * 1424 * 1425 * <i>Please note:</i>It's not possible to set the modules description once the module 1426 * configuration has been frozen.<p> 1427 * 1428 * @param value the module description to set 1429 */ 1430 public void setDescription(String value) { 1431 1432 checkFrozen(); 1433 m_description = value.trim(); 1434 } 1435 1436 /** 1437 * Sets the resources excluded from this module.<p> 1438 * 1439 * 1440 * <i>Please note:</i>It's not possible to set the module resources once the module 1441 * configuration has been frozen.<p> 1442 * 1443 * @param value the resources to exclude from the module 1444 */ 1445 public void setExcludeResources(List<String> value) { 1446 1447 checkFrozen(); 1448 m_excluderesources = value; 1449 } 1450 1451 /** 1452 * Sets the additional explorer types that belong to this module.<p> 1453 * 1454 * @param explorerTypeSettings the explorer type settings. 1455 */ 1456 public void setExplorerTypes(List<CmsExplorerTypeSettings> explorerTypeSettings) { 1457 1458 m_explorerTypeSettings = explorerTypeSettings; 1459 } 1460 1461 /** 1462 * Sets the export points of this module.<p> 1463 * 1464 * @param exportPoints the export points of this module. 1465 */ 1466 public void setExportPoints(List<CmsExportPoint> exportPoints) { 1467 1468 m_exportPoints = exportPoints; 1469 } 1470 1471 /** 1472 * Sets the export version.<p> 1473 * 1474 * @param exportVersion the export version 1475 */ 1476 public void setExportVersion(String exportVersion) { 1477 1478 m_exportVersion = exportVersion; 1479 1480 } 1481 1482 /** 1483 * Sets the group name of this module.<p> 1484 * 1485 * 1486 * <i>Please note:</i>It's not possible to set the modules group name once the module 1487 * configuration has been frozen.<p> 1488 * 1489 * @param value the module group name to set 1490 */ 1491 public void setGroup(String value) { 1492 1493 checkFrozen(); 1494 m_group = value; 1495 } 1496 1497 /** 1498 * Sets the hasImportSite flag, which determines whether the module site should be used as a fixed import site. 1499 * 1500 * @param isImportSite true if the module site should be treated as a fixed import site 1501 */ 1502 public void setHasImportSite(boolean isImportSite) { 1503 1504 checkFrozen(); 1505 m_hasImportSite = isImportSite; 1506 } 1507 1508 /** 1509 * Sets the importScript.<p> 1510 * 1511 * @param importScript the importScript to set 1512 */ 1513 public void setImportScript(String importScript) { 1514 1515 checkFrozen(); 1516 m_importScript = importScript; 1517 } 1518 1519 /** 1520 * Sets the import site.<p> 1521 * 1522 * @param importSite the import site 1523 */ 1524 public void setImportSite(String importSite) { 1525 1526 checkFrozen(); 1527 if (importSite != null) { 1528 importSite = importSite.trim(); 1529 } 1530 m_site = importSite; 1531 m_hasImportSite = true; 1532 } 1533 1534 /** 1535 * Sets the name of this module.<p> 1536 * 1537 * The module name must be a valid java package name.<p> 1538 * 1539 * <i>Please note:</i>It's not possible to set the modules name once the module 1540 * configuration has been frozen.<p> 1541 * 1542 * @param value the module name to set 1543 */ 1544 public void setName(String value) { 1545 1546 checkFrozen(); 1547 if (!CmsStringUtil.isValidJavaClassName(value)) { 1548 throw new CmsIllegalArgumentException(Messages.get().container(Messages.ERR_MODULE_NAME_1, value)); 1549 } 1550 m_name = value; 1551 } 1552 1553 /** 1554 * Sets the "nice" display name of this module.<p> 1555 * 1556 * <i>Please note:</i>It's not possible to set the modules "nice" name once the module 1557 * configuration has been frozen.<p> 1558 * 1559 * @param value the "nice" display name of this module to set 1560 */ 1561 public void setNiceName(String value) { 1562 1563 checkFrozen(); 1564 if (CmsStringUtil.isEmptyOrWhitespaceOnly(value)) { 1565 m_niceName = getName(); 1566 } else { 1567 m_niceName = value.trim(); 1568 } 1569 } 1570 1571 /** 1572 * Sets the parameters of this module.<p> 1573 * 1574 * 1575 * <i>Please note:</i>It's not possible to set the module parameters once the module 1576 * configuration has been frozen.<p> 1577 * 1578 * @param parameters the module parameters to set 1579 */ 1580 public void setParameters(SortedMap<String, String> parameters) { 1581 1582 checkFrozen(); 1583 m_parameters = parameters; 1584 } 1585 1586 /** Set/unset the reduced export mode. 1587 * @param reducedExportMode if <code>true</code>, the export mode is set to {@link ExportMode#REDUCED}, otherwise to {@link ExportMode#DEFAULT}. 1588 */ 1589 public void setReducedExportMode(boolean reducedExportMode) { 1590 1591 m_exportMode = reducedExportMode ? ExportMode.REDUCED : ExportMode.DEFAULT; 1592 } 1593 1594 /** 1595 * Sets the resources of this module.<p> 1596 * 1597 * 1598 * <i>Please note:</i>It's not possible to set the module resources once the module 1599 * configuration has been frozen.<p> 1600 * 1601 * @param value the module resources to set 1602 */ 1603 public void setResources(List<String> value) { 1604 1605 checkFrozen(); 1606 m_resources = value; 1607 } 1608 1609 /** 1610 * Sets the list of additional resource types that belong to this module.<p> 1611 * 1612 * @param resourceTypes list of additional resource types that belong to this module 1613 */ 1614 public void setResourceTypes(List<I_CmsResourceType> resourceTypes) { 1615 1616 m_resourceTypes = Collections.unmodifiableList(resourceTypes); 1617 } 1618 1619 /** 1620 * Sets the module site. 1621 * 1622 * @param siteRoot the module site root 1623 */ 1624 public void setSite(String siteRoot) { 1625 1626 if (siteRoot == null) { 1627 m_hasImportSite = false; 1628 } 1629 m_site = siteRoot; 1630 } 1631 1632 /** 1633 * Sets the user who installed of this module.<p> 1634 * 1635 * 1636 * <i>Please note:</i>It's not possible to set the user installed once the module 1637 * configuration has been frozen.<p> 1638 * 1639 * @param value the user who installed this module 1640 */ 1641 public void setUserInstalled(String value) { 1642 1643 checkFrozen(); 1644 m_userInstalled = value.trim(); 1645 } 1646 1647 /** 1648 * Sets the version number as a string. 1649 * 1650 * @param versionString the version number string 1651 */ 1652 public void setVersionStr(String versionString) { 1653 1654 checkFrozen(); 1655 m_version = new CmsModuleVersion(versionString); 1656 1657 } 1658 1659 /** 1660 * Determines if the version should be incremented based on the module resources' modification dates. 1661 * 1662 * @param cms the CMS context 1663 * @return true if the version number should be incremented 1664 * 1665 * @throws CmsException if something goes wrong 1666 */ 1667 public boolean shouldIncrementVersionBasedOnResources(CmsObject cms) throws CmsException { 1668 1669 if (m_checkpointTime == 0) { 1670 return true; 1671 } 1672 1673 // adjust the site root, if necessary 1674 CmsObject cmsClone = adjustSiteRootIfNecessary(cms, this); 1675 1676 // calculate the module resources 1677 List<CmsResource> moduleResources = calculateModuleResources(cmsClone, this); 1678 1679 for (CmsResource resource : moduleResources) { 1680 try { 1681 List<CmsResource> resourcesToCheck = Lists.newArrayList(); 1682 resourcesToCheck.add(resource); 1683 if (resource.isFolder()) { 1684 resourcesToCheck.addAll(cms.readResources(resource, CmsResourceFilter.IGNORE_EXPIRATION, true)); 1685 } 1686 for (CmsResource resourceToCheck : resourcesToCheck) { 1687 if (resourceToCheck.getDateLastModified() > m_checkpointTime) { 1688 return true; 1689 } 1690 } 1691 } catch (CmsException e) { 1692 LOG.warn(e.getLocalizedMessage(), e); 1693 continue; 1694 } 1695 } 1696 return false; 1697 } 1698 1699 /** 1700 * @see java.lang.Object#toString() 1701 */ 1702 @Override 1703 public String toString() { 1704 1705 if (m_name != null) { 1706 return "[CmsModule: " + m_name + "]"; 1707 } 1708 return super.toString(); 1709 } 1710 1711 /** 1712 * Checks if this modules configuration is frozen.<p> 1713 * 1714 * @throws CmsIllegalArgumentException in case the configuration is already frozen 1715 */ 1716 protected void checkFrozen() throws CmsIllegalArgumentException { 1717 1718 if (m_frozen) { 1719 throw new CmsIllegalArgumentException(Messages.get().container(Messages.ERR_MODULE_FROZEN_1, getName())); 1720 } 1721 } 1722 1723 /** 1724 * Initializes this module, also freezing the module configuration.<p> 1725 * 1726 * @param cms an initialized OpenCms user context 1727 * 1728 * @throws CmsRoleViolationException if the given users does not have the <code>{@link CmsRole#DATABASE_MANAGER}</code> role 1729 */ 1730 protected void initialize(CmsObject cms) throws CmsRoleViolationException { 1731 1732 checkFrozen(); 1733 // check if the user has the required permissions 1734 OpenCms.getRoleManager().checkRole(cms, CmsRole.DATABASE_MANAGER); 1735 1736 m_frozen = true; 1737 m_resources = Collections.unmodifiableList(m_resources); 1738 m_excluderesources = Collections.unmodifiableList(m_excluderesources); 1739 } 1740 1741 /** 1742 * Sets the module action instance for this module.<p> 1743 * 1744 * @param actionInstance the module action instance for this module 1745 */ 1746 /*package*/void setActionInstance(I_CmsModuleAction actionInstance) { 1747 1748 m_actionInstance = actionInstance; 1749 1750 } 1751 1752 /** 1753 * Resolves the module property "additionalresources" to the resource list and 1754 * vice versa.<p> 1755 * 1756 * This "special" module property is required as long as we do not have a new 1757 * GUI for editing of module resource entries. Once we have the new GUI, the 1758 * handling of "additionalresources" will be moved to the import of the module 1759 * and done only if the imported module is a 5.0 module.<p> 1760 */ 1761 private void initOldAdditionalResources() { 1762 1763 SortedMap<String, String> parameters = new TreeMap<String, String>(m_parameters); 1764 List<String> resources = new ArrayList<String>(m_resources); 1765 1766 String additionalResources; 1767 additionalResources = parameters.get(MODULE_PROPERTY_ADDITIONAL_RESOURCES); 1768 if (additionalResources != null) { 1769 StringTokenizer tok = new StringTokenizer( 1770 additionalResources, 1771 MODULE_PROPERTY_ADDITIONAL_RESOURCES_SEPARATOR); 1772 while (tok.hasMoreTokens()) { 1773 String resource = tok.nextToken().trim(); 1774 if ((!"-".equals(resource)) && (!resources.contains(resource))) { 1775 resources.add(resource); 1776 } 1777 } 1778 } 1779 1780 m_resources = resources; 1781 } 1782 1783 /** 1784 * Checks if two objects are either both null, or equal.<p> 1785 * 1786 * @param a the first object to check 1787 * @param b the second object to check 1788 * @return true if the two object are either both null, or equal 1789 */ 1790 private boolean isEqual(Object a, Object b) { 1791 1792 if (a == null) { 1793 return (b == null); 1794 } 1795 if (b == null) { 1796 return false; 1797 } 1798 return a.equals(b); 1799 } 1800 1801}