001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (C) Alkacon Software (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, 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.ade.configuration; 029 030import org.opencms.ade.containerpage.shared.CmsCntPageData.ElementDeleteMode; 031import org.opencms.file.CmsObject; 032import org.opencms.file.CmsProperty; 033import org.opencms.file.CmsRequestContext; 034import org.opencms.file.CmsResource; 035import org.opencms.file.CmsResourceFilter; 036import org.opencms.file.CmsVfsResourceNotFoundException; 037import org.opencms.file.types.CmsResourceTypeFunctionConfig; 038import org.opencms.file.types.I_CmsResourceType; 039import org.opencms.lock.CmsLock; 040import org.opencms.lock.CmsLockException; 041import org.opencms.main.CmsException; 042import org.opencms.main.CmsLog; 043import org.opencms.main.OpenCms; 044import org.opencms.relations.CmsCategoryService; 045import org.opencms.security.CmsPermissionSet; 046import org.opencms.security.CmsRole; 047import org.opencms.ui.util.CmsNewResourceBuilder; 048import org.opencms.util.CmsStringUtil; 049import org.opencms.util.CmsUUID; 050import org.opencms.util.CmsVfsUtil; 051import org.opencms.workplace.explorer.CmsExplorerTypeSettings; 052import org.opencms.xml.containerpage.CmsXmlDynamicFunctionHandler; 053 054import java.util.ArrayList; 055import java.util.HashSet; 056import java.util.Locale; 057import java.util.Set; 058 059import org.apache.commons.logging.Log; 060 061/** 062 * The configuration for a single resource type.<p> 063 */ 064public class CmsResourceTypeConfig implements I_CmsConfigurationObject<CmsResourceTypeConfig>, Cloneable { 065 066 /** 067 * Enum used to distinguish the type of menu in which a configured resource type can be displayed. 068 */ 069 public enum AddMenuType { 070 /** ADE add menu. */ 071 ade, 072 073 /** Workplace dialogs. */ 074 workplace 075 } 076 077 /** 078 * Represents the visibility status of a resource type in the 'Add' menu of the container page editor.<p> 079 */ 080 public enum AddMenuVisibility { 081 082 /** Type should not be creatable. */ 083 createDisabled, 084 085 /** Type not visible. */ 086 disabled, 087 088 /** Type does not belong to current view, but has been configured to be still visible in it. */ 089 fromOtherView, 090 091 /** Type is normally visible. */ 092 visible 093 } 094 095 /** The log instance for this class. */ 096 private static final Log LOG = CmsLog.getLog(CmsResourceTypeConfig.class); 097 098 /** The parameter for setting the default value for 'check reuse'. */ 099 private static final Object PARAM_CHECK_REUSE_DEFAULT = "checkReuseDefault"; 100 101 /** The CMS object used for VFS operations. */ 102 protected CmsObject m_cms; 103 104 /** Flag which controls whether adding elements of this type using ADE is disabled. */ 105 private boolean m_addDisabled; 106 107 /** True if availability has not been set in the configuration file.*/ 108 private boolean m_availabilityNotSet; 109 110 /** 'Check reuse' value (may be null). */ 111 private Boolean m_checkReuse; 112 113 /** Elements of this type when used in models should be copied instead of reused. */ 114 private Boolean m_copyInModels; 115 116 /** Flag which controls whether creating elements of this type using ADE is disabled. */ 117 private boolean m_createDisabled; 118 119 /** The flag for disabling detail pages. */ 120 private boolean m_detailPagesDisabled; 121 122 /** True if this is a disabled configuration. */ 123 private boolean m_disabled; 124 125 /** True if editing is disabled for container elements of this type. */ 126 private boolean m_editDisabled; 127 128 /** The element delete mode. */ 129 private ElementDeleteMode m_elementDeleteMode; 130 131 /** The element view id. */ 132 private CmsUUID m_elementView; 133 134 /** True if this creating/editing for this type should be enabled in lists (e.g. search or contentload tags). */ 135 private boolean m_enableInLists; 136 137 /** A reference to a folder of folder name. */ 138 private CmsContentFolderDescriptor m_folderOrName; 139 140 /** The bundle to add as workplace bundle for the resource type. */ 141 private String m_localization; 142 143 /** The name pattern .*/ 144 private String m_namePattern; 145 146 /** The number used for sorting the resource type configurations. */ 147 private Integer m_order; 148 149 /** Flag which controls whether this type should be shown in the 'add' menu in the default view. */ 150 private Boolean m_showInDefaultView; 151 152 /** The set of template context keys associated with this type via the template=... parameter in master configuration links. */ 153 private Set<String> m_templates = new HashSet<>(); 154 155 /** The name of the resource type. */ 156 private String m_typeName; 157 158 /** 159 * Creates a new resource type configuration.<p> 160 * 161 * @param typeName the resource type name 162 * @param disabled true if this is a disabled configuration 163 * @param folder the folder reference 164 * @param pattern the name pattern 165 */ 166 public CmsResourceTypeConfig(String typeName, boolean disabled, CmsContentFolderDescriptor folder, String pattern) { 167 168 this( 169 typeName, 170 disabled, 171 folder, 172 pattern, 173 false, 174 false, 175 false, 176 false, 177 false, 178 false, 179 CmsElementView.DEFAULT_ELEMENT_VIEW.getId(), 180 null, 181 null, 182 null, 183 Integer.valueOf(I_CmsConfigurationObject.DEFAULT_ORDER), 184 null, 185 null); 186 } 187 188 /** 189 * Creates a new resource type configuration.<p> 190 * 191 * @param typeName the resource type name 192 * @param disabled true if this is a disabled configuration 193 * @param folder the folder reference 194 * @param pattern the name pattern 195 * @param detailPagesDisabled true if detail page creation should be disabled for this type 196 * @param addDisabled true if adding elements of this type via ADE should be disabled 197 * @param editDisabled true if editing container elements of the type should be disabled 198 * @param enableInLists true if the type should be enabled, but only for the direct edit buttons in lists and not ADE/drag/drop. 199 * @param createDisabled true if creating elements of this type via ADE should be disabled 200 * @param availabilityNotSet true if the availability has not been set 201 * @param elementView the element view id 202 * @param localization the base name of the bundle to add as workplace bundle for the resource type 203 * @param showInDefaultView if true, the element type should be shown in the default element view even if it doesn't belong to it 204 * @param copyInModels if elements of this type when used in models should be copied instead of reused 205 * @param order the display order 206 * @param elementDeleteMode the element delete mode 207 * @param checkReuse indicates whether element reuse should be checked for this type 208 */ 209 public CmsResourceTypeConfig( 210 String typeName, 211 boolean disabled, 212 CmsContentFolderDescriptor folder, 213 String pattern, 214 boolean detailPagesDisabled, 215 boolean addDisabled, 216 boolean createDisabled, 217 boolean editDisabled, 218 boolean enableInLists, 219 boolean availabilityNotSet, 220 CmsUUID elementView, 221 String localization, 222 Boolean showInDefaultView, 223 Boolean copyInModels, 224 Integer order, 225 ElementDeleteMode elementDeleteMode, 226 Boolean checkReuse) { 227 228 m_typeName = typeName; 229 m_disabled = disabled; 230 m_folderOrName = folder; 231 m_namePattern = pattern; 232 m_detailPagesDisabled = detailPagesDisabled; 233 m_addDisabled = addDisabled; 234 m_createDisabled = createDisabled; 235 m_availabilityNotSet = availabilityNotSet; 236 m_elementView = elementView; 237 m_editDisabled = editDisabled; 238 m_enableInLists = enableInLists; 239 m_localization = localization; 240 m_showInDefaultView = showInDefaultView; 241 m_copyInModels = copyInModels; 242 m_order = order; 243 m_elementDeleteMode = elementDeleteMode; 244 m_checkReuse = checkReuse; 245 } 246 247 /** 248 * Checks if this resource type is creatable.<p> 249 * 250 * @param cms the current CMS context 251 * @param pageFolderRootPath the root path of the folder containing the current container page 252 * 253 * @return <code>true</code> if the resource type is creatable 254 * 255 * @throws CmsException if something goes wrong 256 */ 257 public boolean checkCreatable(CmsObject cms, String pageFolderRootPath) throws CmsException { 258 259 if (cms.getRequestContext().getCurrentProject().isOnlineProject()) { 260 return false; 261 } 262 if (OpenCms.getRoleManager().hasRole(cms, CmsRole.ROOT_ADMIN)) { 263 return true; 264 } 265 if (CmsXmlDynamicFunctionHandler.TYPE_FUNCTION.equals(m_typeName) 266 || CmsResourceTypeFunctionConfig.TYPE_NAME.equals(m_typeName)) { 267 return OpenCms.getRoleManager().hasRole(cms, CmsRole.DEVELOPER); 268 } 269 checkInitialized(); 270 if ((m_folderOrName != null) && m_folderOrName.isPageRelative() && (pageFolderRootPath == null)) { 271 LOG.info( 272 "type " 273 + m_typeName 274 + " not creatable for pageFolderRootPath=null because it is configured to be page-relative"); 275 return false; 276 } 277 String folderPath = getFolderPath(cms, pageFolderRootPath); 278 String oldSiteRoot = cms.getRequestContext().getSiteRoot(); 279 cms.getRequestContext().setSiteRoot(""); 280 //tryToUnlock(cms, folderPath); 281 CmsResource permissionCheckFolder = null; 282 for (String currentPath = folderPath; currentPath != null; currentPath = CmsResource.getParentFolder( 283 currentPath)) { 284 try { 285 permissionCheckFolder = cms.readResource(currentPath); 286 break; 287 } catch (CmsVfsResourceNotFoundException e) { 288 // ignore 289 } 290 } 291 try { 292 if (permissionCheckFolder == null) { 293 return false; 294 } 295 LOG.info("Using " + permissionCheckFolder + " as a permission check folder for " + folderPath); 296 CmsExplorerTypeSettings settings = OpenCms.getWorkplaceManager().getExplorerTypeSetting(m_typeName); 297 if (settings == null) { 298 return false; 299 } 300 boolean editable = settings.isEditable(cms, permissionCheckFolder); 301 boolean controlPermission = settings.getAccess().getPermissions( 302 cms, 303 permissionCheckFolder).requiresControlPermission(); 304 boolean hasWritePermission = cms.hasPermissions( 305 permissionCheckFolder, 306 CmsPermissionSet.ACCESS_WRITE, 307 false, 308 CmsResourceFilter.ONLY_VISIBLE_NO_DELETED); 309 return editable && controlPermission && hasWritePermission; 310 } catch (CmsVfsResourceNotFoundException e) { 311 return false; 312 } catch (CmsException e) { 313 LOG.error(e.getLocalizedMessage(), e); 314 return false; 315 } finally { 316 cms.getRequestContext().setSiteRoot(oldSiteRoot); 317 } 318 } 319 320 /** 321 * Checks whether the object is initialized and throws an exception otherwise.<p> 322 */ 323 public void checkInitialized() { 324 325 if (m_cms == null) { 326 throw new IllegalStateException(); 327 } 328 } 329 330 /** 331 * Checks whether the cms context is in the offline project and throws an exception otherwise.<p> 332 * 333 * @param cms the cms context 334 */ 335 public void checkOffline(CmsObject cms) { 336 337 if (cms.getRequestContext().getCurrentProject().isOnlineProject()) { 338 throw new IllegalStateException(); 339 } 340 } 341 342 /** 343 * Checks if a resource type is viewable for the current user. 344 * If not, this resource type should not be available at all within the ADE 'add-wizard'.<p> 345 * 346 * @param cms the current CMS context 347 * @param referenceUri the resource URI to check permissions for 348 * 349 * @return <code>true</code> if the resource type is viewable 350 */ 351 public boolean checkViewable(CmsObject cms, String referenceUri) { 352 353 try { 354 CmsExplorerTypeSettings settings = OpenCms.getWorkplaceManager().getExplorerTypeSetting(m_typeName); 355 CmsResource referenceResource = cms.readResource( 356 referenceUri, 357 CmsResourceFilter.ignoreExpirationOffline(cms)); 358 if (settings == null) { 359 // no explorer type 360 return false; 361 } 362 return settings.getAccess().getPermissions(cms, referenceResource).requiresViewPermission(); 363 } catch (CmsException e) { 364 LOG.error(e.getLocalizedMessage(), e); 365 return false; 366 } 367 } 368 369 /** 370 * Similar to createNewElement, but just sets parameters on a resource builder instead of actually creating the resource.<p> 371 * 372 * @param cms the CMS context 373 * @param pageFolderRootPath the page folder root path 374 * @param builder the resource builder 375 * 376 * @throws CmsException if something goes wrong 377 */ 378 public void configureCreateNewElement(CmsObject cms, String pageFolderRootPath, CmsNewResourceBuilder builder) 379 throws CmsException { 380 381 checkOffline(cms); 382 checkInitialized(); 383 String folderPath = getFolderPath(cms, pageFolderRootPath); 384 CmsVfsUtil.createFolder(cms, folderPath); 385 String destination = CmsStringUtil.joinPaths(folderPath, getNamePattern(true)); 386 builder.setSiteRoot(""); 387 builder.setPatternPath(destination); 388 builder.setType(getTypeName()); 389 builder.setLocale(cms.getRequestContext().getLocale()); 390 } 391 392 /** 393 * Creates a new element.<p> 394 * 395 * @param userCms the CMS context to use 396 * @param modelResource the model resource to use 397 * @param pageFolderRootPath the root path of the folder containing the current container page 398 * 399 * @return the created resource 400 * 401 * @throws CmsException if something goes wrong 402 */ 403 public CmsResource createNewElement(CmsObject userCms, CmsResource modelResource, String pageFolderRootPath) 404 throws CmsException { 405 406 checkOffline(userCms); 407 checkInitialized(); 408 CmsObject rootCms = rootCms(userCms); 409 String folderPath = getFolderPath(userCms, pageFolderRootPath); 410 CmsVfsUtil.createFolder(userCms, folderPath); 411 String destination = CmsStringUtil.joinPaths(folderPath, getNamePattern(true)); 412 String creationPath = OpenCms.getResourceManager().getNameGenerator().getNewFileName(rootCms, destination, 5); 413 // set the content locale 414 Locale contentLocale = userCms.getRequestContext().getLocale(); 415 if (!OpenCms.getLocaleManager().getAvailableLocales(rootCms, folderPath).contains(contentLocale)) { 416 contentLocale = OpenCms.getLocaleManager().getDefaultLocale(rootCms, folderPath); 417 } 418 rootCms.getRequestContext().setAttribute(CmsRequestContext.ATTRIBUTE_NEW_RESOURCE_LOCALE, contentLocale); 419 if (modelResource != null) { 420 // set the model resource 421 rootCms.getRequestContext().setAttribute(CmsRequestContext.ATTRIBUTE_MODEL, modelResource.getRootPath()); 422 } 423 CmsResource createdResource = rootCms.createResource( 424 creationPath, 425 getType(), 426 null, 427 new ArrayList<CmsProperty>(0)); 428 if (modelResource != null) { 429 // set the model resource 430 CmsCategoryService.getInstance().copyCategories(rootCms, modelResource, creationPath); 431 } 432 try { 433 rootCms.unlockResource(creationPath); 434 } catch (CmsLockException e) { 435 // probably the parent folder is locked 436 LOG.info(e.getLocalizedMessage(), e); 437 } 438 return createdResource; 439 } 440 441 /** 442 * Creates a new element.<p> 443 * 444 * @param userCms the CMS context to use 445 * @param pageFolderRootPath root path of the folder containing the current container page 446 * 447 * @return the created resource 448 * 449 * @throws CmsException if something goes wrong 450 */ 451 public CmsResource createNewElement(CmsObject userCms, String pageFolderRootPath) throws CmsException { 452 453 return createNewElement(userCms, null, pageFolderRootPath); 454 } 455 456 /** 457 * Gets the visibility status in the 'add' menu for this type and the given element view.<p> 458 * 459 * @param elementViewId the id of the view for which to compute the visibility status 460 * @param menuType the menu type for which we want to evaluate the visibility 461 * 462 * @return the visibility status 463 */ 464 public AddMenuVisibility getAddMenuVisibility(CmsUUID elementViewId, AddMenuType menuType) { 465 466 if (isAddDisabled()) { 467 return AddMenuVisibility.disabled; 468 } 469 470 if (elementViewId.equals(getElementView())) { 471 if (isCreateDisabled() && (menuType == AddMenuType.ade)) { 472 return AddMenuVisibility.createDisabled; 473 } 474 return AddMenuVisibility.visible; 475 } 476 477 if (isShowInDefaultView() && elementViewId.equals(CmsElementView.DEFAULT_ELEMENT_VIEW.getId())) { 478 return AddMenuVisibility.fromOtherView; 479 } 480 481 return AddMenuVisibility.disabled; 482 } 483 484 /** 485 * Gets the 'check reuse' value, without applying the default value. 486 * 487 * <p>The return value may be null if this is not set. 488 * 489 * @return the value of the 'check reuse' option 490 */ 491 public Boolean getCheckReuseObj() { 492 493 return m_checkReuse; 494 } 495 496 /** 497 * Returns the bundle that is configured as workplace bundle for the resource type, or <code>null</code> if none is configured. 498 * @return the bundle that is configured as workplace bundle for the resource type, or <code>null</code> if none is configured. 499 */ 500 public String getConfiguredWorkplaceBundle() { 501 502 return m_localization; 503 } 504 505 /** 506 * Gets the element delete mode.<p> 507 * 508 * @return the element delete mode 509 */ 510 public ElementDeleteMode getElementDeleteMode() { 511 512 return m_elementDeleteMode; 513 } 514 515 /** 516 * Returns the element view id.<p> 517 * 518 * @return the element view id 519 */ 520 public CmsUUID getElementView() { 521 522 return m_elementView == null ? CmsElementView.DEFAULT_ELEMENT_VIEW.getId() : m_elementView; 523 } 524 525 /** 526 * Computes the folder path for this resource type.<p> 527 * 528 * @param cms the cms context to use 529 * @param pageFolderRootPath root path of the folder containing the current container page 530 * 531 * @return the folder root path for this resource type 532 */ 533 public String getFolderPath(CmsObject cms, String pageFolderRootPath) { 534 535 checkInitialized(); 536 if (m_folderOrName != null) { 537 return m_folderOrName.getFolderPath(cms, pageFolderRootPath); 538 } else { 539 String siteRoot = null; 540 if (pageFolderRootPath != null) { 541 siteRoot = OpenCms.getSiteManager().getSiteRoot(pageFolderRootPath); 542 } 543 if (siteRoot == null) { 544 siteRoot = cms.getRequestContext().getSiteRoot(); 545 } 546 return CmsStringUtil.joinPaths(siteRoot, CmsADEManager.CONTENT_FOLDER_NAME, m_typeName); 547 } 548 } 549 550 /** 551 * @see org.opencms.ade.configuration.I_CmsConfigurationObject#getKey() 552 */ 553 public String getKey() { 554 555 return m_typeName; 556 } 557 558 /** 559 * Gets the name pattern.<p> 560 * 561 * @param useDefaultIfEmpty if true, uses a default value if the name pattern isn't set directly 562 * 563 * @return the name pattern 564 */ 565 public String getNamePattern(boolean useDefaultIfEmpty) { 566 567 if (m_namePattern != null) { 568 return m_namePattern; 569 } 570 if (useDefaultIfEmpty) { 571 return m_typeName + "-%(number).xml"; 572 } 573 return null; 574 } 575 576 /** 577 * Returns the number used for sorting module resource types.<p> 578 * 579 * @return the number used for sorting module resource types 580 */ 581 public int getOrder() { 582 583 if (m_order == null) { 584 return I_CmsConfigurationObject.DEFAULT_ORDER; 585 } 586 587 return m_order.intValue(); 588 } 589 590 /** 591 * Returns the order as an object (or null if it's not set). 592 * 593 * @return the order 594 */ 595 public Integer getOrderObject() { 596 597 return m_order; 598 } 599 600 /** 601 * Gets the actual resource type for which this is a configuration.<p> 602 * 603 * @return the actual resource type 604 * 605 * @throws CmsException if something goes wrong 606 */ 607 public I_CmsResourceType getType() throws CmsException { 608 609 return OpenCms.getResourceManager().getResourceType(m_typeName); 610 } 611 612 /** 613 * Returns the type name.<p> 614 * 615 * @return the type name 616 */ 617 public String getTypeName() { 618 619 return m_typeName; 620 } 621 622 /** 623 * Initializes this instance.<p> 624 * 625 * @param cms the CMS context to use 626 */ 627 public void initialize(CmsObject cms) { 628 629 m_cms = cms; 630 631 } 632 633 /** 634 * Returns true if adding elements of this type via ADE should be disabled.<p> 635 * 636 * @return true if elements of this type shouldn't be added to the page 637 */ 638 public boolean isAddDisabled() { 639 640 return m_addDisabled; 641 } 642 643 /** 644 * Checks if the type can be used for the given template context key. 645 * 646 * <p>If this type isn't specifically associated with one or more template keys, this returns true, 647 * otherwise it will check if the 'template' argument is among the template keys 648 * 649 * @param template the template key to check 650 * @return true if the type should be available for the template 651 */ 652 public boolean isAvailableInTemplate(String template) { 653 654 return (template == null) || (m_templates.size() == 0) || m_templates.contains(template); 655 } 656 657 /** 658 * Returns true if reuse should be checked for elements of this type. 659 * 660 * <p>This tries to use the value configured for this type first, and if it doesn't have one, returns the global default. 661 * 662 * @return true if reuse should be checked for this type 663 */ 664 public boolean isCheckReuse() { 665 666 if (m_checkReuse != null) { 667 return m_checkReuse.booleanValue(); 668 } 669 String defaultStr = OpenCms.getADEManager().getParameters(null).get(PARAM_CHECK_REUSE_DEFAULT); 670 return Boolean.parseBoolean(defaultStr); 671 } 672 673 /** 674 * Returns if elements of this type when used in models should be copied instead of reused.<p> 675 * 676 * @return if elements of this type when used in models should be copied instead of reused 677 */ 678 public boolean isCopyInModels() { 679 680 return (m_copyInModels == null) || m_copyInModels.booleanValue(); 681 } 682 683 /** 684 * Returns whether creating elements of this type via ADE should be disabled.<p> 685 * 686 * @return <code>true</code> if creating elements of this type via ADE should be disabled 687 */ 688 public boolean isCreateDisabled() { 689 690 return m_createDisabled; 691 } 692 693 /** 694 * True if the detail page creation should be disabled for this resource type.<p> 695 * 696 * @return true if detail page creation should be disabled for this type 697 */ 698 public boolean isDetailPagesDisabled() { 699 700 return m_detailPagesDisabled; 701 } 702 703 /** 704 * @see org.opencms.ade.configuration.I_CmsConfigurationObject#isDisabled() 705 */ 706 public boolean isDisabled() { 707 708 return m_disabled; 709 } 710 711 /** 712 * Checks if editing should be disabled for container elements of this type. 713 * 714 * @return true if editing should be disabled for container elements of this type 715 */ 716 public boolean isEditDisabled() { 717 718 return m_editDisabled; 719 } 720 721 /** 722 * Checks if creating and editing resources of this type should be possible via the edit buttons generated by lists. 723 * 724 * @return true if creating/editing resources of this type in lists should be possible 725 */ 726 public boolean isEnabledInLists() { 727 728 return m_enableInLists; 729 } 730 731 /** 732 * Returns true if this resource type is configured as 'page relative', i.e. elements of this type are to be stored 733 * with the container page on which they were created.<p> 734 * 735 * @return true if this is a page relative type configuration 736 */ 737 public boolean isPageRelative() { 738 739 return (m_folderOrName != null) && m_folderOrName.isPageRelative(); 740 } 741 742 /** 743 * Returns true if the type should be shown in the default view if it is not assigned to it.<p> 744 * 745 * This defaults to 'false' if not set. 746 * 747 * @return true if the type should be shown in the default view event if it doens't belong to that element view 748 */ 749 public boolean isShowInDefaultView() { 750 751 return (m_showInDefaultView != null) && m_showInDefaultView.booleanValue(); 752 } 753 754 /** 755 * If 'template' is not null, returns a copy of this type bean, but adds 'template' to the 756 * set of supported templates in the copy. 757 * 758 * @param template a template context key 759 * @return a new copy associated with the given template key 760 */ 761 public CmsResourceTypeConfig markWithTemplate(String template) { 762 763 try { 764 if (template == null) { 765 return this; 766 } 767 CmsResourceTypeConfig result = (CmsResourceTypeConfig)super.clone(); 768 HashSet<String> templates = new HashSet<>(); 769 templates.add(template); 770 result.m_templates = templates; 771 return result; 772 773 } catch (CloneNotSupportedException e) { 774 return null; 775 } 776 } 777 778 /** 779 * @see org.opencms.ade.configuration.I_CmsConfigurationObject#merge(org.opencms.ade.configuration.I_CmsConfigurationObject) 780 */ 781 public CmsResourceTypeConfig merge(CmsResourceTypeConfig childConfig) { 782 783 CmsContentFolderDescriptor folderOrName = childConfig.m_folderOrName != null 784 ? childConfig.m_folderOrName 785 : m_folderOrName; 786 String namePattern = childConfig.m_namePattern != null ? childConfig.m_namePattern : m_namePattern; 787 CmsUUID elementView = childConfig.m_elementView != null ? childConfig.m_elementView : m_elementView; 788 Boolean showInDefaultView = childConfig.m_showInDefaultView != null 789 ? childConfig.m_showInDefaultView 790 : m_showInDefaultView; 791 Boolean copyInModels = childConfig.m_copyInModels != null ? childConfig.m_copyInModels : m_copyInModels; 792 ElementDeleteMode deleteMode = childConfig.m_elementDeleteMode != null 793 ? childConfig.m_elementDeleteMode 794 : m_elementDeleteMode; 795 Integer order = childConfig.m_order != null ? childConfig.m_order : m_order; 796 797 boolean mergedDisabled = childConfig.m_availabilityNotSet ? isDisabled() : childConfig.isDisabled(); 798 boolean mergedAddDisabled = childConfig.m_availabilityNotSet ? isAddDisabled() : childConfig.isAddDisabled(); 799 boolean mergedCreateDisabled = childConfig.m_availabilityNotSet 800 ? isCreateDisabled() 801 : (isCreateDisabled() || childConfig.isCreateDisabled()); 802 803 boolean mergedEnableInLists = childConfig.m_availabilityNotSet ? m_enableInLists : childConfig.m_enableInLists; 804 boolean mergedDisableEdit = childConfig.m_availabilityNotSet ? m_editDisabled : childConfig.m_editDisabled; 805 Boolean checkReuse = childConfig.m_checkReuse != null ? childConfig.m_checkReuse : m_checkReuse; 806 807 CmsResourceTypeConfig result = new CmsResourceTypeConfig( 808 m_typeName, 809 mergedDisabled, 810 folderOrName, 811 namePattern, 812 isDetailPagesDisabled() || childConfig.isDetailPagesDisabled(), 813 mergedAddDisabled, 814 // a type marked as not creatable, should not be creatable in any sub site 815 mergedCreateDisabled, 816 mergedDisableEdit, 817 mergedEnableInLists, 818 false /* availabilityNotSet - doesn't matter what we use here, because we do not use the return value of this method as a child for configuration merging (which is the only way this attribute is used) */, 819 elementView, 820 m_localization, 821 showInDefaultView, 822 copyInModels, 823 order, 824 deleteMode, 825 checkReuse); 826 result.m_templates = new HashSet<>(this.m_templates); 827 result.m_templates.addAll(childConfig.m_templates); 828 return result; 829 } 830 831 /** 832 * @see java.lang.Object#toString() 833 */ 834 @Override 835 public String toString() { 836 837 return getClass().getSimpleName() + "[" + m_typeName + "]"; 838 } 839 840 /** 841 * Creates a shallow copy of this resource type configuration object.<p> 842 * 843 * @return a copy of the resource type configuration object 844 */ 845 protected CmsResourceTypeConfig copy() { 846 847 return copy(false); 848 } 849 850 /** 851 * Creates a shallow copy of this resource type configuration object.<p> 852 * 853 * @param disabled true if the copy should be disabled regardless of whether the original is disabled 854 * 855 * @return a copy of the resource type configuration object 856 */ 857 protected CmsResourceTypeConfig copy(boolean disabled) { 858 859 CmsResourceTypeConfig result = new CmsResourceTypeConfig( 860 m_typeName, 861 m_disabled || disabled, 862 getFolderOrName(), 863 m_namePattern, 864 m_detailPagesDisabled, 865 isAddDisabled(), 866 isCreateDisabled(), 867 m_editDisabled, 868 m_enableInLists, 869 m_availabilityNotSet, 870 m_elementView, 871 m_localization, 872 m_showInDefaultView, 873 m_copyInModels, 874 m_order, 875 m_elementDeleteMode, 876 m_checkReuse); 877 result.m_templates = m_templates; 878 return result; 879 } 880 881 /** 882 * Returns the folder bean from the configuration.<p> 883 * 884 * Normally, you should use getFolderPath() instead.<p> 885 * 886 * @return the folder bean from the configuration 887 */ 888 protected CmsContentFolderDescriptor getFolderOrName() { 889 890 return m_folderOrName; 891 } 892 893 /** 894 * Gets the configured name pattern.<p> 895 * 896 * @return the configured name pattern 897 */ 898 protected String getNamePattern() { 899 900 return m_namePattern; 901 } 902 903 /** 904 * Creates a new CMS object based on existing one and changes its site root to the site root.<p> 905 * 906 * @param cms the CMS context 907 * @return the root site CMS context 908 * @throws CmsException if something goes wrong 909 */ 910 protected CmsObject rootCms(CmsObject cms) throws CmsException { 911 912 CmsObject result = OpenCms.initCmsObject(cms); 913 result.getRequestContext().setSiteRoot(""); 914 return result; 915 } 916 917 /** 918 * Tries to remove a lock on an ancestor of a given path owned by the current user.<p> 919 * 920 * @param cms the CMS context 921 * @param folderPath the path for which the lock should be removed 922 * 923 * @throws CmsException if something goes wrong 924 */ 925 protected void tryToUnlock(CmsObject cms, String folderPath) throws CmsException { 926 927 // Get path of first ancestor that actually exists 928 while (!cms.existsResource(folderPath)) { 929 folderPath = CmsResource.getParentFolder(folderPath); 930 } 931 CmsResource resource = cms.readResource(folderPath); 932 CmsLock lock = cms.getLock(resource); 933 // we are only interested in locks we can safely unlock, i.e. locks by the current user 934 if (lock.isOwnedBy(cms.getRequestContext().getCurrentUser())) { 935 // walk up the tree until we get to the location from which the lock is inherited 936 while (lock.isInherited()) { 937 folderPath = CmsResource.getParentFolder(folderPath); 938 resource = cms.readResource(folderPath); 939 lock = cms.getLock(resource); 940 } 941 cms.unlockResource(folderPath); 942 } 943 } 944 945 /** 946 * Updates the base path for the folder information.<p> 947 * 948 * @param basePath the new base path 949 */ 950 protected void updateBasePath(String basePath) { 951 952 if (m_folderOrName != null) { 953 if (m_folderOrName.isName()) { 954 m_folderOrName = new CmsContentFolderDescriptor(basePath, m_folderOrName.getFolderName()); 955 } 956 } else { 957 m_folderOrName = new CmsContentFolderDescriptor(basePath, m_typeName); 958 } 959 } 960}