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, 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.xml.containerpage; 029 030import org.opencms.ade.configuration.CmsADEConfigData; 031import org.opencms.ade.configuration.CmsADEManager; 032import org.opencms.ade.containerpage.shared.CmsContainerElement; 033import org.opencms.ade.containerpage.shared.CmsContainerElement.ModelGroupState; 034import org.opencms.ade.containerpage.shared.CmsFormatterConfig; 035import org.opencms.ade.containerpage.shared.CmsInheritanceInfo; 036import org.opencms.file.CmsFile; 037import org.opencms.file.CmsObject; 038import org.opencms.file.CmsResource; 039import org.opencms.file.CmsResourceFilter; 040import org.opencms.file.types.CmsResourceTypeXmlContainerPage; 041import org.opencms.file.types.CmsResourceTypeXmlContent; 042import org.opencms.file.types.I_CmsResourceType; 043import org.opencms.main.CmsException; 044import org.opencms.main.OpenCms; 045import org.opencms.util.CmsNullIgnoringConcurrentMap; 046import org.opencms.util.CmsUUID; 047import org.opencms.xml.CmsXmlContentDefinition; 048import org.opencms.xml.content.CmsXmlContent; 049import org.opencms.xml.content.CmsXmlContentFactory; 050import org.opencms.xml.content.CmsXmlContentPropertyHelper; 051 052import java.util.Collections; 053import java.util.HashMap; 054import java.util.Locale; 055import java.util.Map; 056 057import javax.servlet.ServletRequest; 058 059/** 060 * One element of a container in a container page.<p> 061 * 062 * @since 8.0 063 */ 064public class CmsContainerElementBean implements Cloneable { 065 066 /** Prevent caching in ADE session cache. */ 067 private boolean m_doNotCache; 068 069 /** Flag indicating if a new element should be created replacing the given one on first edit of a container-page. */ 070 private final boolean m_createNew; 071 072 /** The client ADE editor hash. */ 073 private transient String m_editorHash; 074 075 /** The element's structure id. */ 076 private CmsUUID m_elementId; 077 078 /** The formatter's structure id. */ 079 private CmsUUID m_formatterId; 080 081 /** The configured properties. */ 082 private Map<String, String> m_individualSettings; 083 084 /** The inheritance info of this element. */ 085 private CmsInheritanceInfo m_inheritanceInfo; 086 087 /** Indicates whether the represented resource is in memory only and not in the VFS. */ 088 private boolean m_inMemoryOnly; 089 090 /** True if the element is used for a historical content. */ 091 private boolean m_isHistory; 092 093 /** Indicating if the element resource is released and not expired. */ 094 private boolean m_releasedAndNotExpired; 095 096 /** The resource of this element. */ 097 private transient CmsResource m_resource; 098 099 /** The settings of this element containing also default values. */ 100 private transient Map<String, String> m_settings; 101 102 /** The element site path, only set while rendering. */ 103 private String m_sitePath; 104 105 /** Indicates the element bean has a temporary file content set. */ 106 private boolean m_temporaryContent; 107 108 /** 109 * Creates a new container page element bean.<p> 110 * 111 * @param file the element's file 112 * @param formatterId the formatter's structure id, could be <code>null</code> 113 * @param individualSettings the element settings as a map of name/value pairs 114 * @param inMemoryOnly the in memory flag 115 * @param editorHash the editor hash to use 116 * @param createNew <code>true</code> if a new element should be created replacing the given one on first edit of a container-page 117 **/ 118 public CmsContainerElementBean( 119 CmsFile file, 120 CmsUUID formatterId, 121 Map<String, String> individualSettings, 122 boolean inMemoryOnly, 123 String editorHash, 124 boolean createNew) { 125 126 this(file.getStructureId(), formatterId, individualSettings, createNew); 127 m_inMemoryOnly = inMemoryOnly; 128 m_editorHash = editorHash; 129 m_resource = file; 130 } 131 132 /** 133 * Creates a new container page element bean.<p> 134 * 135 * @param elementId the element's structure id 136 * @param formatterId the formatter's structure id, could be <code>null</code> 137 * @param individualSettings the element settings as a map of name/value pairs 138 * @param createNew <code>true</code> if a new element should be created replacing the given one on first edit of a container-page 139 **/ 140 public CmsContainerElementBean( 141 CmsUUID elementId, 142 CmsUUID formatterId, 143 Map<String, String> individualSettings, 144 boolean createNew) { 145 146 m_elementId = elementId; 147 m_formatterId = formatterId; 148 Map<String, String> newSettings = (individualSettings == null 149 ? new HashMap<String, String>() 150 : new HashMap<String, String>(individualSettings)); 151 if (!newSettings.containsKey(CmsContainerElement.ELEMENT_INSTANCE_ID)) { 152 newSettings.put(CmsContainerElement.ELEMENT_INSTANCE_ID, new CmsUUID().toString()); 153 } 154 newSettings.values().removeAll(Collections.singletonList(null)); 155 m_individualSettings = Collections.unmodifiableMap(newSettings); 156 m_editorHash = m_elementId.toString() + getSettingsHash(); 157 m_createNew = createNew; 158 } 159 160 /** 161 * Constructor to enable wrapped elements.<p> 162 */ 163 protected CmsContainerElementBean() { 164 165 m_elementId = null; 166 m_createNew = false; 167 } 168 169 /** 170 * Cloning constructor.<p> 171 * 172 * @param createNew create new flag 173 * @param elementId element id 174 * @param formatterId formatter id 175 * @param individualSettings individual settings 176 * @param inheritanceInfo inheritance info 177 * @param inMemoryOnly in memory only flag 178 * @param temporaryContent temporary content flag 179 * @param releasedAndNotExpired released and not expired flag 180 * @param resource the resource/file object 181 * @param settings the settings 182 * @param sitePath the site path 183 */ 184 private CmsContainerElementBean( 185 boolean createNew, 186 CmsUUID elementId, 187 CmsUUID formatterId, 188 Map<String, String> individualSettings, 189 CmsInheritanceInfo inheritanceInfo, 190 boolean inMemoryOnly, 191 boolean temporaryContent, 192 boolean releasedAndNotExpired, 193 CmsResource resource, 194 Map<String, String> settings, 195 String sitePath) { 196 197 m_createNew = createNew; 198 m_elementId = elementId; 199 m_formatterId = formatterId; 200 m_individualSettings = Collections.unmodifiableMap(individualSettings); 201 m_inheritanceInfo = inheritanceInfo; 202 m_inMemoryOnly = inMemoryOnly; 203 m_releasedAndNotExpired = releasedAndNotExpired; 204 m_resource = resource; 205 setSettings(settings); 206 m_sitePath = sitePath; 207 m_temporaryContent = temporaryContent; 208 } 209 210 /** 211 * Clones the given element bean with a different formatter.<p> 212 * 213 * @param source the element to clone 214 * @param formatterId the new formatter id 215 * 216 * @return the element bean 217 */ 218 public static CmsContainerElementBean cloneWithFormatter(CmsContainerElementBean source, CmsUUID formatterId) { 219 220 CmsContainerElementBean result = source.clone(); 221 result.m_formatterId = formatterId; 222 return result; 223 } 224 225 /** 226 * Clones the given element bean with a different set of settings.<p> 227 * 228 * @param source the element to clone 229 * @param settings the new settings 230 * 231 * @return the element bean 232 */ 233 public static CmsContainerElementBean cloneWithSettings( 234 CmsContainerElementBean source, 235 Map<String, String> settings) { 236 237 boolean createNew = source.m_createNew; 238 if (settings.containsKey(CmsContainerElement.CREATE_AS_NEW)) { 239 createNew = Boolean.valueOf(settings.get(CmsContainerElement.CREATE_AS_NEW)).booleanValue(); 240 settings = new HashMap<String, String>(settings); 241 settings.remove(CmsContainerElement.CREATE_AS_NEW); 242 } 243 CmsContainerElementBean result = new CmsContainerElementBean( 244 source.m_elementId, 245 source.m_formatterId, 246 settings, 247 createNew); 248 result.m_resource = source.m_resource; 249 result.m_sitePath = source.m_sitePath; 250 result.m_inMemoryOnly = source.m_inMemoryOnly; 251 result.m_inheritanceInfo = source.m_inheritanceInfo; 252 if (result.m_inMemoryOnly) { 253 String editorHash = source.m_editorHash; 254 if (editorHash.contains(CmsADEManager.CLIENT_ID_SEPERATOR)) { 255 editorHash = editorHash.substring(0, editorHash.indexOf(CmsADEManager.CLIENT_ID_SEPERATOR)); 256 } 257 editorHash += result.getSettingsHash(); 258 result.m_editorHash = editorHash; 259 } 260 return result; 261 } 262 263 /** 264 * Creates an element bean for the given resource type.<p> 265 * <b>The represented resource will be in memory only and not in the VFS!!!.</b><p> 266 * 267 * @param cms the CMS context 268 * @param resourceType the resource type 269 * @param targetFolder the parent folder of the resource 270 * @param individualSettings the element settings as a map of name/value pairs 271 * @param isCopyModels if this element when used in models should be copied instead of reused 272 * @param locale the locale to use 273 * 274 * @return the created element bean 275 * @throws CmsException if something goes wrong creating the element 276 * @throws IllegalArgumentException if the resource type not instance of {@link org.opencms.file.types.CmsResourceTypeXmlContent} 277 */ 278 public static CmsContainerElementBean createElementForResourceType( 279 CmsObject cms, 280 I_CmsResourceType resourceType, 281 String targetFolder, 282 Map<String, String> individualSettings, 283 boolean isCopyModels, 284 Locale locale) 285 throws CmsException { 286 287 if (!(resourceType instanceof CmsResourceTypeXmlContent)) { 288 throw new IllegalArgumentException(); 289 } 290 291 byte[] content = new byte[0]; 292 String schema = ((CmsResourceTypeXmlContent)resourceType).getSchema(); 293 if (schema != null) { 294 // must set URI of OpenCms user context to parent folder of created resource, 295 // in order to allow reading of properties for default values 296 CmsObject newCms = OpenCms.initCmsObject(cms); 297 newCms.getRequestContext().setUri(targetFolder); 298 // unmarshal the content definition for the new resource 299 CmsXmlContentDefinition contentDefinition = CmsXmlContentDefinition.unmarshal(cms, schema); 300 CmsXmlContent xmlContent = CmsXmlContentFactory.createDocument( 301 newCms, 302 locale, 303 OpenCms.getSystemInfo().getDefaultEncoding(), 304 contentDefinition); 305 // adding all other available locales 306 for (Locale otherLocale : OpenCms.getLocaleManager().getAvailableLocales()) { 307 if (!locale.equals(otherLocale)) { 308 xmlContent.addLocale(newCms, otherLocale); 309 } 310 } 311 content = xmlContent.marshal(); 312 } 313 @SuppressWarnings("deprecation") 314 CmsFile file = new CmsFile( 315 CmsUUID.getNullUUID(), 316 CmsUUID.getNullUUID(), 317 targetFolder + "~", 318 resourceType.getTypeId(), 319 0, 320 cms.getRequestContext().getCurrentProject().getUuid(), 321 CmsResource.STATE_NEW, 322 0, 323 cms.getRequestContext().getCurrentUser().getId(), 324 0, 325 cms.getRequestContext().getCurrentUser().getId(), 326 CmsResource.DATE_RELEASED_DEFAULT, 327 CmsResource.DATE_EXPIRED_DEFAULT, 328 1, 329 content.length, 330 0, 331 0, 332 content); 333 CmsContainerElementBean elementBean = new CmsContainerElementBean( 334 file, 335 null, 336 individualSettings, 337 true, 338 resourceType.getTypeName() + getSettingsHash(individualSettings, isCopyModels), 339 isCopyModels); 340 return elementBean; 341 } 342 343 /** 344 * Gets the hash code for the element settings.<p> 345 * 346 * @param individualSettings the individual settings 347 * @param createNew the create new flag 348 * 349 * @return the hash code for the element settings 350 */ 351 private static String getSettingsHash(Map<String, String> individualSettings, boolean createNew) { 352 353 if (!individualSettings.isEmpty() || createNew) { 354 int hash = (individualSettings.toString() + createNew).hashCode(); 355 return CmsADEManager.CLIENT_ID_SEPERATOR + hash; 356 } 357 return ""; 358 } 359 360 /** 361 * Adds a formatter setting.<p> 362 * 363 * @param containerName the container name 364 * @param formatterId the formatter id 365 */ 366 public void addFormatterSetting(String containerName, String formatterId) { 367 368 Map<String, String> newSettings = new HashMap<String, String>(m_individualSettings); 369 newSettings.put(CmsFormatterConfig.getSettingsKeyForContainer(containerName), formatterId); 370 m_individualSettings = Collections.unmodifiableMap(newSettings); 371 if (m_inMemoryOnly) { 372 String editorHash = m_editorHash; 373 if (editorHash.contains(CmsADEManager.CLIENT_ID_SEPERATOR)) { 374 editorHash = editorHash.substring(0, editorHash.indexOf(CmsADEManager.CLIENT_ID_SEPERATOR)); 375 } 376 editorHash += getSettingsHash(); 377 m_editorHash = editorHash; 378 } else { 379 m_editorHash = m_elementId.toString() + getSettingsHash(); 380 } 381 } 382 383 /** 384 * @see java.lang.Object#clone() 385 */ 386 @Override 387 public CmsContainerElementBean clone() { 388 389 return new CmsContainerElementBean( 390 m_createNew, 391 m_elementId, 392 m_formatterId, 393 m_individualSettings, 394 m_inheritanceInfo, 395 m_inMemoryOnly, 396 m_temporaryContent, 397 m_releasedAndNotExpired, 398 m_resource, 399 m_settings, 400 m_sitePath); 401 } 402 403 /** 404 * Returns the ADE client editor has value.<p> 405 * 406 * @return the ADE client editor has value 407 */ 408 public String editorHash() { 409 410 if (m_editorHash == null) { 411 m_editorHash = m_elementId.toString() + getSettingsHash(); 412 } 413 return m_editorHash; 414 } 415 416 /** 417 * Ensures the element has a new element instance id.<p> 418 */ 419 public void ensureNewInstanceId() { 420 421 Map<String, String> newSettings = new HashMap<String, String>(m_individualSettings); 422 newSettings.put(CmsContainerElement.ELEMENT_INSTANCE_ID, new CmsUUID().toString()); 423 m_individualSettings = Collections.unmodifiableMap(newSettings); 424 m_editorHash = m_elementId.toString() + getSettingsHash(); 425 } 426 427 /** 428 * @see java.lang.Object#equals(java.lang.Object) 429 */ 430 @Override 431 public boolean equals(Object obj) { 432 433 if (!(obj instanceof CmsContainerElementBean)) { 434 return false; 435 } 436 return editorHash().equals(((CmsContainerElementBean)obj).editorHash()); 437 } 438 439 /** 440 * Returns the structure id of the formatter of this element.<p> 441 * 442 * @return the structure id of the formatter of this element 443 */ 444 public CmsUUID getFormatterId() { 445 446 return m_formatterId; 447 } 448 449 /** 450 * Returns the structure id of the resource of this element.<p> 451 * 452 * @return the structure id of the resource of this element 453 */ 454 public CmsUUID getId() { 455 456 return m_elementId; 457 } 458 459 /** 460 * Returns the settings of this element.<p> 461 * 462 * @return the settings of this element 463 */ 464 public Map<String, String> getIndividualSettings() { 465 466 return m_individualSettings; 467 } 468 469 /** 470 * Returns the inheritance info.<p> 471 * 472 * @return the inheritance info or <code>null</code> if not available 473 */ 474 public CmsInheritanceInfo getInheritanceInfo() { 475 476 return m_inheritanceInfo; 477 } 478 479 /** 480 * Returns the element instance id.<p> 481 * 482 * @return the element instance id 483 */ 484 public String getInstanceId() { 485 486 return getIndividualSettings().get(CmsContainerElement.ELEMENT_INSTANCE_ID); 487 } 488 489 /** 490 * Returns the resource of this element.<p> 491 * 492 * It is required to call {@link #initResource(CmsObject)} before this method can be used.<p> 493 * 494 * @return the resource of this element 495 * 496 * @see #initResource(CmsObject) 497 */ 498 public CmsResource getResource() { 499 500 return m_resource; 501 } 502 503 /** 504 * Returns the element settings including default values for settings not set.<p> 505 * Will return <code>null</code> if the element bean has not been initialized with {@link #initResource(org.opencms.file.CmsObject)}.<p> 506 * 507 * @return the element settings 508 */ 509 public Map<String, String> getSettings() { 510 511 return m_settings; 512 } 513 514 /** 515 * Returns the site path of the resource of this element.<p> 516 * 517 * It is required to call {@link #initResource(CmsObject)} before this method can be used.<p> 518 * 519 * @return the site path of the resource of this element 520 * 521 * @see #initResource(CmsObject) 522 */ 523 public String getSitePath() { 524 525 return m_sitePath; 526 } 527 528 /** 529 * Returns the resource type name.<p> 530 * 531 * @return the type name 532 */ 533 public String getTypeName() { 534 535 if (getResource() != null) { 536 return OpenCms.getResourceManager().getResourceType(getResource()).getTypeName(); 537 } else { 538 return "unknown"; 539 } 540 } 541 542 /** 543 * @see java.lang.Object#hashCode() 544 */ 545 @Override 546 public int hashCode() { 547 548 return m_editorHash.hashCode(); 549 } 550 551 /** 552 * Initializes the resource and the site path of this element.<p> 553 * 554 * @param cms the CMS context 555 * 556 * @throws CmsException if something goes wrong reading the element resource 557 */ 558 public void initResource(CmsObject cms) throws CmsException { 559 560 if (m_resource == null) { 561 m_resource = cms.readResource(getId(), CmsResourceFilter.IGNORE_EXPIRATION); 562 m_releasedAndNotExpired = m_resource.isReleasedAndNotExpired(cms.getRequestContext().getRequestTime()); 563 } else if (!isInMemoryOnly()) { 564 CmsUUID id = m_resource.getStructureId(); 565 if (id == null) { 566 id = getId(); 567 } 568 // the resource object may have a wrong root path, e.g. if it was created before the resource was moved 569 if (cms.getRequestContext().getCurrentProject().isOnlineProject()) { 570 m_resource = cms.readResource(id, CmsResourceFilter.IGNORE_EXPIRATION); 571 m_releasedAndNotExpired = m_resource.isReleasedAndNotExpired(cms.getRequestContext().getRequestTime()); 572 } else { 573 if (!isTemporaryContent()) { 574 m_resource = cms.readResource(getId(), CmsResourceFilter.IGNORE_EXPIRATION); 575 } 576 m_releasedAndNotExpired = m_resource.isReleasedAndNotExpired(cms.getRequestContext().getRequestTime()); 577 } 578 } 579 if (m_settings == null) { 580 setSettings(new HashMap<String, String>(getIndividualSettings())); 581 } 582 // redo on every init call to ensure sitepath is calculated for current site 583 m_sitePath = cms.getSitePath(m_resource); 584 } 585 586 /** 587 * Initializes the element settings.<p> 588 * 589 * @param cms the CMS context 590 * @param formatterBean the formatter configuration bean 591 * @param locale the content locale 592 * @param request the current request, if available 593 * @param presets the presets for container element settings 594 */ 595 public void initSettings( 596 CmsObject cms, 597 CmsADEConfigData config, 598 I_CmsFormatterBean formatterBean, 599 Locale locale, 600 ServletRequest request, 601 Map<String, String> presets) { 602 603 Map<String, String> mergedSettings; 604 if (formatterBean == null) { 605 mergedSettings = CmsXmlContentPropertyHelper.mergeDefaults( 606 cms, 607 config, 608 m_resource, 609 getIndividualSettings(), 610 locale, 611 request); 612 } else { 613 mergedSettings = CmsXmlContentPropertyHelper.mergeDefaults( 614 cms, 615 OpenCms.getADEManager().getFormatterSettings( 616 cms, 617 config, 618 formatterBean, 619 getResource(), 620 locale, 621 request), 622 getIndividualSettings()); 623 } 624 if ((presets != null) && (presets.size() > 0)) { 625 mergedSettings.putAll(presets); 626 } 627 if (m_settings == null) { 628 setSettings(mergedSettings); 629 } else { 630 m_settings.putAll(mergedSettings); 631 } 632 } 633 634 /** 635 * Returns if the given element should be used as a copy model.<p> 636 * 637 * @return <code>true</code> if the given element should be used as a copy model 638 */ 639 public boolean isCopyModel() { 640 641 return Boolean.valueOf(getIndividualSettings().get(CmsContainerElement.USE_AS_COPY_MODEL)).booleanValue(); 642 } 643 644 /** 645 * Returns if a new element should be created replacing the given one on first edit of a container-page.<p> 646 * 647 * @return <code>true</code> if a new element should be created replacing the given one on first edit of a container-page 648 */ 649 public boolean isCreateNew() { 650 651 return m_createNew; 652 } 653 654 /** 655 * Checks if the element is uncacheable. 656 * 657 * @return true if the element is uncacheable 658 */ 659 public boolean isDoNotCache() { 660 661 return m_doNotCache; 662 } 663 664 /** 665 * Tests whether this element refers to a group container.<p> 666 * 667 * @param cms the CmsObject used for VFS operations 668 * 669 * @return <code>true</code> if the container element refers to a group container 670 * 671 * @throws CmsException if something goes wrong 672 */ 673 public boolean isGroupContainer(CmsObject cms) throws CmsException { 674 675 if (m_resource == null) { 676 initResource(cms); 677 } 678 return CmsResourceTypeXmlContainerPage.GROUP_CONTAINER_TYPE_NAME.equals( 679 OpenCms.getResourceManager().getResourceType(m_resource).getTypeName()); 680 } 681 682 /** 683 * Checks if the element is used for displaying a historical content (usually from the history dialog). 684 * 685 * @return true if the element is used for displaying a historical content 686 */ 687 public boolean isHistoryContent() { 688 689 return m_isHistory; 690 } 691 692 /** 693 * Returns whether this element refers to an inherited container element.<p> 694 * 695 * @param cms the CmsObject used for VFS operations 696 * 697 * @return <code>true</code> if the container element refers to an inherited container 698 * 699 * @throws CmsException if something goes wrong 700 */ 701 @SuppressWarnings("deprecation") 702 public boolean isInheritedContainer(CmsObject cms) throws CmsException { 703 704 if (m_resource == null) { 705 initResource(cms); 706 } 707 return OpenCms.getResourceManager().getResourceType( 708 CmsResourceTypeXmlContainerPage.INHERIT_CONTAINER_TYPE_NAME).getTypeId() == m_resource.getTypeId(); 709 } 710 711 /** 712 * Returns if the represented resource is in memory only and not persisted in the VFS.<p> 713 * 714 * @return <code>true</code> if the represented resource is in memory only and not persisted in the VFS 715 */ 716 public boolean isInMemoryOnly() { 717 718 return m_inMemoryOnly; 719 } 720 721 /** 722 * Returns if the given element is a model group.<p> 723 * 724 * @return <code>true</code> if the given element is a model group 725 */ 726 public boolean isModelGroup() { 727 728 ModelGroupState state = ModelGroupState.evaluate( 729 getIndividualSettings().get(CmsContainerElement.MODEL_GROUP_STATE)); 730 return state == ModelGroupState.isModelGroup; 731 } 732 733 /** 734 * Returns if all instances of this element should be replaced within a copy model.<p> 735 * 736 * @return <code>true</code> if all instances of this element should be replaced within a copy model 737 */ 738 public boolean isModelGroupAlwaysReplace() { 739 740 return Boolean.parseBoolean(getIndividualSettings().get(CmsContainerElement.IS_MODEL_GROUP_ALWAYS_REPLACE)); 741 } 742 743 /** 744 * Returns if the element resource is released and not expired.<p> 745 * 746 * @return <code>true</code> if the element resource is released and not expired 747 */ 748 public boolean isReleasedAndNotExpired() { 749 750 return isInMemoryOnly() || m_releasedAndNotExpired; 751 } 752 753 /** 754 * Returns if the element resource contains temporary file content.<p> 755 * 756 * @return <code>true</code> if the element resource contains temporary file content 757 */ 758 public boolean isTemporaryContent() { 759 760 return m_temporaryContent; 761 } 762 763 /** 764 * Enables / disables 'do not cache' status, which prevents the element from being cached in the session cache. 765 * 766 * @param doNotCache the new value 767 */ 768 public void setDoNotCache(boolean doNotCache) { 769 770 m_doNotCache = doNotCache; 771 } 772 773 /** 774 * Sets the formatter id.<p> 775 * 776 * @param formatterId the formatter id 777 */ 778 public void setFormatterId(CmsUUID formatterId) { 779 780 m_formatterId = formatterId; 781 } 782 783 /** 784 * Sets a historical file.<p> 785 * 786 * @param file the historical file 787 */ 788 public void setHistoryFile(CmsFile file) { 789 790 m_resource = file; 791 m_inMemoryOnly = true; 792 m_isHistory = true; 793 } 794 795 /** 796 * Sets the inheritance info for this element.<p> 797 * 798 * @param inheritanceInfo the inheritance info 799 */ 800 public void setInheritanceInfo(CmsInheritanceInfo inheritanceInfo) { 801 802 m_inheritanceInfo = inheritanceInfo; 803 } 804 805 /** 806 * Sets the element resource as a temporary file.<p> 807 * 808 * @param elementFile the temporary file 809 */ 810 public void setTemporaryFile(CmsFile elementFile) { 811 812 m_resource = elementFile; 813 m_temporaryContent = true; 814 } 815 816 /** 817 * @see java.lang.Object#toString() 818 */ 819 @Override 820 public String toString() { 821 822 return editorHash(); 823 } 824 825 /** 826 * Updates the individual settings.<p> 827 * 828 * This causes all merged settings (from defaults etc.) to be lost. 829 * 830 * @param newSettings the new settings 831 */ 832 public void updateIndividualSettings(Map<String, String> newSettings) { 833 834 m_individualSettings = Collections.unmodifiableMap(newSettings); 835 setSettings(getIndividualSettings()); 836 } 837 838 /** 839 * Gets the hash code for the element settings.<p> 840 * 841 * @return the hash code for the element settings 842 */ 843 private String getSettingsHash() { 844 845 String instanceId = getInstanceId(); 846 if (instanceId == null) { 847 throw new RuntimeException("Missing instance id"); 848 } 849 return CmsADEManager.CLIENT_ID_SEPERATOR 850 + getInstanceId() 851 + "_" 852 + getIndividualSettings().get(CmsContainerElement.SETTING_PAGE_ID); 853 } 854 855 /** 856 * Sets the settings map.<p> 857 * 858 * @param settings the settings 859 */ 860 private void setSettings(Map<String, String> settings) { 861 862 if (settings == null) { 863 m_settings = null; 864 } else { 865 m_settings = new CmsNullIgnoringConcurrentMap<String, String>(settings); 866 } 867 } 868}