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