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