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.jsp.util; 029 030import org.opencms.ade.configuration.CmsADEConfigData; 031import org.opencms.ade.configuration.CmsADEManager; 032import org.opencms.ade.configuration.CmsFunctionReference; 033import org.opencms.ade.containerpage.CmsContainerpageService; 034import org.opencms.ade.containerpage.CmsModelGroupHelper; 035import org.opencms.ade.containerpage.shared.CmsFormatterConfig; 036import org.opencms.ade.containerpage.shared.CmsInheritanceInfo; 037import org.opencms.ade.detailpage.CmsDetailPageInfo; 038import org.opencms.ade.detailpage.CmsDetailPageResourceHandler; 039import org.opencms.file.CmsFile; 040import org.opencms.file.CmsObject; 041import org.opencms.file.CmsPropertyDefinition; 042import org.opencms.file.CmsRequestContext; 043import org.opencms.file.CmsResource; 044import org.opencms.file.CmsResourceFilter; 045import org.opencms.file.history.CmsHistoryResourceHandler; 046import org.opencms.file.types.CmsResourceTypeXmlContainerPage; 047import org.opencms.flex.CmsFlexController; 048import org.opencms.flex.CmsFlexRequest; 049import org.opencms.gwt.shared.CmsGwtConstants; 050import org.opencms.i18n.CmsLocaleGroupService; 051import org.opencms.jsp.CmsJspBean; 052import org.opencms.jsp.CmsJspResourceWrapper; 053import org.opencms.jsp.CmsJspTagContainer; 054import org.opencms.jsp.CmsJspTagEditable; 055import org.opencms.jsp.Messages; 056import org.opencms.jsp.jsonpart.CmsJsonPartFilter; 057import org.opencms.loader.CmsTemplateContextManager; 058import org.opencms.main.CmsException; 059import org.opencms.main.CmsLog; 060import org.opencms.main.CmsRuntimeException; 061import org.opencms.main.CmsSystemInfo; 062import org.opencms.main.OpenCms; 063import org.opencms.relations.CmsCategory; 064import org.opencms.relations.CmsCategoryService; 065import org.opencms.search.galleries.CmsGalleryNameMacroResolver; 066import org.opencms.site.CmsSite; 067import org.opencms.util.CmsCollectionsGenericWrapper; 068import org.opencms.util.CmsMacroResolver; 069import org.opencms.util.CmsStringUtil; 070import org.opencms.util.CmsUUID; 071import org.opencms.xml.containerpage.CmsADESessionCache; 072import org.opencms.xml.containerpage.CmsContainerBean; 073import org.opencms.xml.containerpage.CmsContainerElementBean; 074import org.opencms.xml.containerpage.CmsContainerPageBean; 075import org.opencms.xml.containerpage.CmsDynamicFunctionBean; 076import org.opencms.xml.containerpage.CmsDynamicFunctionParser; 077import org.opencms.xml.containerpage.CmsFormatterConfiguration; 078import org.opencms.xml.containerpage.CmsMetaMapping; 079import org.opencms.xml.containerpage.CmsXmlContainerPage; 080import org.opencms.xml.containerpage.CmsXmlContainerPageFactory; 081import org.opencms.xml.containerpage.I_CmsFormatterBean; 082import org.opencms.xml.content.CmsXmlContent; 083import org.opencms.xml.content.CmsXmlContentFactory; 084import org.opencms.xml.content.CmsXmlContentProperty; 085import org.opencms.xml.templatemapper.CmsTemplateMapper; 086import org.opencms.xml.types.I_CmsXmlContentValue; 087 088import java.lang.reflect.Constructor; 089import java.lang.reflect.Method; 090import java.util.ArrayList; 091import java.util.Arrays; 092import java.util.Collections; 093import java.util.HashMap; 094import java.util.List; 095import java.util.Locale; 096import java.util.Map; 097 098import javax.servlet.ServletRequest; 099import javax.servlet.http.HttpServletRequest; 100 101import org.apache.commons.collections.Transformer; 102import org.apache.commons.lang3.LocaleUtils; 103import org.apache.commons.logging.Log; 104 105/** 106 * Allows convenient access to the most important OpenCms functions on a JSP page, 107 * indented to be used from a JSP with the JSTL or EL.<p> 108 * 109 * This bean is available by default in the context of an OpenCms managed JSP.<p> 110 * 111 * @since 8.0 112 */ 113public final class CmsJspStandardContextBean { 114 115 /** 116 * Container element wrapper to add some API methods.<p> 117 */ 118 public class CmsContainerElementWrapper extends CmsContainerElementBean { 119 120 /** The wrapped element instance. */ 121 private CmsContainerElementBean m_wrappedElement; 122 123 /** 124 * Constructor.<p> 125 * 126 * @param element the element to wrap 127 */ 128 protected CmsContainerElementWrapper(CmsContainerElementBean element) { 129 130 m_wrappedElement = element; 131 132 } 133 134 /** 135 * @see org.opencms.xml.containerpage.CmsContainerElementBean#clone() 136 */ 137 @Override 138 public CmsContainerElementBean clone() { 139 140 return m_wrappedElement.clone(); 141 } 142 143 /** 144 * @see org.opencms.xml.containerpage.CmsContainerElementBean#editorHash() 145 */ 146 @Override 147 public String editorHash() { 148 149 return m_wrappedElement.editorHash(); 150 } 151 152 /** 153 * @see org.opencms.xml.containerpage.CmsContainerElementBean#equals(java.lang.Object) 154 */ 155 @Override 156 public boolean equals(Object obj) { 157 158 return m_wrappedElement.equals(obj); 159 } 160 161 /** 162 * @see org.opencms.xml.containerpage.CmsContainerElementBean#getFormatterId() 163 */ 164 @Override 165 public CmsUUID getFormatterId() { 166 167 return m_wrappedElement.getFormatterId(); 168 } 169 170 /** 171 * @see org.opencms.xml.containerpage.CmsContainerElementBean#getId() 172 */ 173 @Override 174 public CmsUUID getId() { 175 176 return m_wrappedElement.getId(); 177 } 178 179 /** 180 * @see org.opencms.xml.containerpage.CmsContainerElementBean#getIndividualSettings() 181 */ 182 @Override 183 public Map<String, String> getIndividualSettings() { 184 185 return m_wrappedElement.getIndividualSettings(); 186 } 187 188 /** 189 * @see org.opencms.xml.containerpage.CmsContainerElementBean#getInheritanceInfo() 190 */ 191 @Override 192 public CmsInheritanceInfo getInheritanceInfo() { 193 194 return m_wrappedElement.getInheritanceInfo(); 195 } 196 197 /** 198 * @see org.opencms.xml.containerpage.CmsContainerElementBean#getInstanceId() 199 */ 200 @Override 201 public String getInstanceId() { 202 203 return m_wrappedElement.getInstanceId(); 204 } 205 206 /** 207 * Returns the parent element if present.<p> 208 * 209 * @return the parent element or <code>null</code> if not available 210 */ 211 public CmsContainerElementWrapper getParent() { 212 213 CmsContainerElementBean parent = getParentElement(m_wrappedElement); 214 return parent != null ? new CmsContainerElementWrapper(getParentElement(m_wrappedElement)) : null; 215 } 216 217 /** 218 * @see org.opencms.xml.containerpage.CmsContainerElementBean#getResource() 219 */ 220 @Override 221 public CmsResource getResource() { 222 223 return m_wrappedElement.getResource(); 224 } 225 226 /** 227 * Returns the resource type name of the element resource.<p> 228 * 229 * @return the resource type name 230 */ 231 public String getResourceTypeName() { 232 233 String result = ""; 234 try { 235 result = OpenCms.getResourceManager().getResourceType(m_wrappedElement.getResource()).getTypeName(); 236 } catch (Exception e) { 237 CmsJspStandardContextBean.LOG.error(e.getLocalizedMessage(), e); 238 } 239 return result; 240 } 241 242 /** 243 * Returns a lazy initialized setting map.<p> 244 * 245 * The values returned in the map are instances of {@link A_CmsJspValueWrapper}. 246 * 247 * @return the wrapped settings 248 */ 249 public Map<String, CmsJspElementSettingValueWrapper> getSetting() { 250 251 return CmsCollectionsGenericWrapper.createLazyMap(new SettingsTransformer(m_wrappedElement)); 252 } 253 254 /** 255 * @see org.opencms.xml.containerpage.CmsContainerElementBean#getSettings() 256 */ 257 @Override 258 public Map<String, String> getSettings() { 259 260 return m_wrappedElement.getSettings(); 261 } 262 263 /** 264 * @see org.opencms.xml.containerpage.CmsContainerElementBean#getSitePath() 265 */ 266 @Override 267 public String getSitePath() { 268 269 return m_wrappedElement.getSitePath(); 270 } 271 272 /** 273 * @see org.opencms.xml.containerpage.CmsContainerElementBean#hashCode() 274 */ 275 @Override 276 public int hashCode() { 277 278 return m_wrappedElement.hashCode(); 279 } 280 281 /** 282 * @see org.opencms.xml.containerpage.CmsContainerElementBean#initResource(org.opencms.file.CmsObject) 283 */ 284 @Override 285 public void initResource(CmsObject cms) throws CmsException { 286 287 m_wrappedElement.initResource(cms); 288 } 289 290 /** 291 * @see org.opencms.xml.containerpage.CmsContainerElementBean#initSettings(org.opencms.file.CmsObject, org.opencms.xml.containerpage.I_CmsFormatterBean, java.util.Locale, javax.servlet.ServletRequest, java.util.Map) 292 */ 293 @Override 294 public void initSettings( 295 CmsObject cms, 296 I_CmsFormatterBean formatterBean, 297 Locale locale, 298 ServletRequest request, 299 Map<String, String> settingPresets) { 300 301 m_wrappedElement.initSettings(cms, formatterBean, locale, request, settingPresets); 302 } 303 304 /** 305 * @see org.opencms.xml.containerpage.CmsContainerElementBean#isCreateNew() 306 */ 307 @Override 308 public boolean isCreateNew() { 309 310 return m_wrappedElement.isCreateNew(); 311 } 312 313 /** 314 * @see org.opencms.xml.containerpage.CmsContainerElementBean#isGroupContainer(org.opencms.file.CmsObject) 315 */ 316 @Override 317 public boolean isGroupContainer(CmsObject cms) throws CmsException { 318 319 return m_wrappedElement.isGroupContainer(cms); 320 } 321 322 /** 323 * @see org.opencms.xml.containerpage.CmsContainerElementBean#isInheritedContainer(org.opencms.file.CmsObject) 324 */ 325 @Override 326 public boolean isInheritedContainer(CmsObject cms) throws CmsException { 327 328 return m_wrappedElement.isInheritedContainer(cms); 329 } 330 331 /** 332 * @see org.opencms.xml.containerpage.CmsContainerElementBean#isInMemoryOnly() 333 */ 334 @Override 335 public boolean isInMemoryOnly() { 336 337 return m_wrappedElement.isInMemoryOnly(); 338 } 339 340 /** 341 * @see org.opencms.xml.containerpage.CmsContainerElementBean#isReleasedAndNotExpired() 342 */ 343 @Override 344 public boolean isReleasedAndNotExpired() { 345 346 return m_wrappedElement.isReleasedAndNotExpired(); 347 } 348 349 /** 350 * @see org.opencms.xml.containerpage.CmsContainerElementBean#isTemporaryContent() 351 */ 352 @Override 353 public boolean isTemporaryContent() { 354 355 return m_wrappedElement.isTemporaryContent(); 356 } 357 358 /** 359 * @see org.opencms.xml.containerpage.CmsContainerElementBean#removeInstanceId() 360 */ 361 @Override 362 public void removeInstanceId() { 363 364 m_wrappedElement.removeInstanceId(); 365 } 366 367 /** 368 * @see org.opencms.xml.containerpage.CmsContainerElementBean#setFormatterId(org.opencms.util.CmsUUID) 369 */ 370 @Override 371 public void setFormatterId(CmsUUID formatterId) { 372 373 m_wrappedElement.setFormatterId(formatterId); 374 } 375 376 /** 377 * @see org.opencms.xml.containerpage.CmsContainerElementBean#setHistoryFile(org.opencms.file.CmsFile) 378 */ 379 @Override 380 public void setHistoryFile(CmsFile file) { 381 382 m_wrappedElement.setHistoryFile(file); 383 } 384 385 /** 386 * @see org.opencms.xml.containerpage.CmsContainerElementBean#setInheritanceInfo(org.opencms.ade.containerpage.shared.CmsInheritanceInfo) 387 */ 388 @Override 389 public void setInheritanceInfo(CmsInheritanceInfo inheritanceInfo) { 390 391 m_wrappedElement.setInheritanceInfo(inheritanceInfo); 392 } 393 394 /** 395 * @see org.opencms.xml.containerpage.CmsContainerElementBean#setTemporaryFile(org.opencms.file.CmsFile) 396 */ 397 @Override 398 public void setTemporaryFile(CmsFile elementFile) { 399 400 m_wrappedElement.setTemporaryFile(elementFile); 401 } 402 403 /** 404 * @see org.opencms.xml.containerpage.CmsContainerElementBean#toString() 405 */ 406 @Override 407 public String toString() { 408 409 return m_wrappedElement.toString(); 410 } 411 } 412 413 /** 414 * Provides a lazy initialized Map that provides the detail page link as a value when given the name of a 415 * (named) dynamic function or resource type as a key.<p> 416 */ 417 public class CmsDetailLookupTransformer implements Transformer { 418 419 /** The selected prefix. */ 420 private String m_prefix; 421 422 /** 423 * Constructor with a prefix.<p> 424 * 425 * The prefix is used to distinguish between type detail pages and function detail pages.<p> 426 * 427 * @param prefix the prefix to use 428 */ 429 public CmsDetailLookupTransformer(String prefix) { 430 431 m_prefix = prefix; 432 } 433 434 /** 435 * @see org.apache.commons.collections.Transformer#transform(java.lang.Object) 436 */ 437 @Override 438 public Object transform(Object input) { 439 440 String type = m_prefix + String.valueOf(input); 441 CmsADEConfigData config = OpenCms.getADEManager().lookupConfiguration( 442 m_cms, 443 m_cms.addSiteRoot(m_cms.getRequestContext().getUri())); 444 List<CmsDetailPageInfo> detailPages = config.getDetailPagesForType(type); 445 CmsDetailPageInfo detailPage = null; 446 boolean usingDefault = false; 447 if ((detailPages == null) || (detailPages.size() == 0)) { 448 detailPage = config.getDefaultDetailPage(); 449 usingDefault = true; 450 } else { 451 detailPage = detailPages.get(0); 452 } 453 if (detailPage == null) { 454 return "[No detail page configured for type =" + type + "=]"; 455 } 456 457 CmsUUID id = detailPage.getId(); 458 try { 459 CmsResource r = m_cms.readResource(id); 460 String link = OpenCms.getLinkManager().substituteLink(m_cms, r); 461 if (usingDefault) { 462 link = CmsStringUtil.joinPaths(link, (String)input); 463 } 464 return link; 465 } catch (CmsException e) { 466 LOG.warn(e.getLocalizedMessage(), e); 467 return "[Error reading detail page for type =" + type + "=]"; 468 } 469 } 470 } 471 472 /** 473 * The element setting transformer.<p> 474 */ 475 public class SettingsTransformer implements Transformer { 476 477 /** The element formatter config. */ 478 private I_CmsFormatterBean m_formatter; 479 480 /** The configured formatter settings. */ 481 private Map<String, CmsXmlContentProperty> m_formatterSettingsConfig; 482 483 /** The element. */ 484 private CmsContainerElementBean m_transformElement; 485 486 /** 487 * Constructor.<p> 488 * 489 * @param element the element 490 */ 491 SettingsTransformer(CmsContainerElementBean element) { 492 493 m_transformElement = element; 494 m_formatter = getElementFormatter(element); 495 } 496 497 /** 498 * @see org.apache.commons.collections.Transformer#transform(java.lang.Object) 499 */ 500 @Override 501 public Object transform(Object settingName) { 502 503 boolean exists; 504 if (m_formatter != null) { 505 if (m_formatterSettingsConfig == null) { 506 m_formatterSettingsConfig = OpenCms.getADEManager().getFormatterSettings( 507 m_cms, 508 m_formatter, 509 m_transformElement.getResource(), 510 getLocale(), 511 m_request); 512 } 513 exists = m_formatterSettingsConfig.get(settingName) != null; 514 } else { 515 exists = m_transformElement.getSettings().get(settingName) != null; 516 } 517 return new CmsJspElementSettingValueWrapper( 518 CmsJspStandardContextBean.this, 519 m_transformElement.getSettings().get(settingName), 520 exists); 521 } 522 } 523 524 /** 525 * Bean containing a template name and URI.<p> 526 */ 527 public static class TemplateBean { 528 529 /** True if the template context was manually selected. */ 530 private boolean m_forced; 531 532 /** The template name. */ 533 private String m_name; 534 535 /** The template resource. */ 536 private CmsResource m_resource; 537 538 /** The template uri, if no resource is set. */ 539 private String m_uri; 540 541 /** 542 * Creates a new instance.<p> 543 * 544 * @param name the template name 545 * @param resource the template resource 546 */ 547 public TemplateBean(String name, CmsResource resource) { 548 549 m_resource = resource; 550 m_name = name; 551 } 552 553 /** 554 * Creates a new instance with an URI instead of a resoure.<p> 555 * 556 * @param name the template name 557 * @param uri the template uri 558 */ 559 public TemplateBean(String name, String uri) { 560 561 m_name = name; 562 m_uri = uri; 563 } 564 565 /** 566 * Gets the template name.<p> 567 * 568 * @return the template name 569 */ 570 public String getName() { 571 572 return m_name; 573 } 574 575 /** 576 * Gets the template resource.<p> 577 * 578 * @return the template resource 579 */ 580 public CmsResource getResource() { 581 582 return m_resource; 583 } 584 585 /** 586 * Gets the template uri.<p> 587 * 588 * @return the template URI. 589 */ 590 public String getUri() { 591 592 if (m_resource != null) { 593 return m_resource.getRootPath(); 594 } else { 595 return m_uri; 596 } 597 } 598 599 /** 600 * Returns true if the template context was manually selected.<p> 601 * 602 * @return true if the template context was manually selected 603 */ 604 public boolean isForced() { 605 606 return m_forced; 607 } 608 609 /** 610 * Sets the 'forced' flag to a new value.<p> 611 * 612 * @param forced the new value 613 */ 614 public void setForced(boolean forced) { 615 616 m_forced = forced; 617 } 618 619 } 620 621 /** 622 * The meta mappings transformer.<p> 623 */ 624 class MetaLookupTranformer implements Transformer { 625 626 /** 627 * @see org.apache.commons.collections.Transformer#transform(java.lang.Object) 628 */ 629 public Object transform(Object arg0) { 630 631 String result = null; 632 if ((m_metaMappings != null) && m_metaMappings.containsKey(arg0)) { 633 MetaMapping mapping = m_metaMappings.get(arg0); 634 CmsGalleryNameMacroResolver resolver = null; 635 try { 636 CmsResourceFilter filter = getIsEditMode() 637 ? CmsResourceFilter.IGNORE_EXPIRATION 638 : CmsResourceFilter.DEFAULT; 639 CmsResource res = m_cms.readResource(mapping.m_contentId, filter); 640 CmsXmlContent content = CmsXmlContentFactory.unmarshal(m_cms, res, m_request); 641 resolver = new CmsGalleryNameMacroResolver(m_cms, content, getLocale()); 642 if (content.hasLocale(getLocale())) { 643 I_CmsXmlContentValue val = content.getValue(mapping.m_elementXPath, getLocale()); 644 if (val != null) { 645 result = val.getStringValue(m_cms); 646 } 647 } 648 649 } catch (CmsException e) { 650 LOG.error(e.getLocalizedMessage(), e); 651 } 652 if (result == null) { 653 result = mapping.m_defaultValue; 654 } 655 if ((resolver != null) && (result != null)) { 656 result = resolver.resolveMacros(result); 657 } 658 } 659 return result; 660 } 661 662 } 663 664 /** The meta mapping data. */ 665 class MetaMapping { 666 667 /** The mapping content structure id. */ 668 CmsUUID m_contentId; 669 670 /** The default value. */ 671 String m_defaultValue; 672 673 /** The mapping value xpath. */ 674 String m_elementXPath; 675 676 /** The mapping key. */ 677 String m_key; 678 679 /** The mapping order. */ 680 int m_order; 681 } 682 683 /** The attribute name of the cms object.*/ 684 public static final String ATTRIBUTE_CMS_OBJECT = "__cmsObject"; 685 686 /** The attribute name of the standard JSP context bean. */ 687 public static final String ATTRIBUTE_NAME = "cms"; 688 689 /** The logger instance for this class. */ 690 protected static final Log LOG = CmsLog.getLog(CmsJspStandardContextBean.class); 691 692 /** OpenCms user context. */ 693 protected CmsObject m_cms; 694 695 /** The meta mapping configuration. */ 696 Map<String, MetaMapping> m_metaMappings; 697 698 /** The current request. */ 699 ServletRequest m_request; 700 701 /** Lazily initialized map from a category path to all sub-categories of that category. */ 702 private Map<String, CmsJspCategoryAccessBean> m_allSubCategories; 703 704 /** Lazily initialized map from a category path to the path's category object. */ 705 private Map<String, CmsCategory> m_categories; 706 707 /** The container the currently rendered element is part of. */ 708 private CmsContainerBean m_container; 709 710 /** The current detail content resource if available. */ 711 private CmsResource m_detailContentResource; 712 713 /** The detail function page. */ 714 private CmsResource m_detailFunctionPage; 715 716 /** The detail only page references containers that are only displayed in detail view. */ 717 private CmsContainerPageBean m_detailOnlyPage; 718 719 /** Flag to indicate if element was just edited. */ 720 private boolean m_edited; 721 722 /** The currently rendered element. */ 723 private CmsContainerElementBean m_element; 724 725 /** The elements of the current page. */ 726 private Map<String, CmsContainerElementBean> m_elementInstances; 727 728 /** The lazy initialized map which allows access to the dynamic function beans. */ 729 private Map<String, CmsDynamicFunctionBeanWrapper> m_function; 730 731 /** The lazy initialized map for the function detail pages. */ 732 private Map<String, String> m_functionDetailPage; 733 734 /** Indicates if in drag mode. */ 735 private boolean m_isDragMode; 736 737 /** Stores the edit mode info. */ 738 private Boolean m_isEditMode; 739 740 /** Lazily initialized map from the locale to the localized title property. */ 741 private Map<String, String> m_localeTitles; 742 743 /** The currently displayed container page. */ 744 private CmsContainerPageBean m_page; 745 746 /** The current container page resource, lazy initialized. */ 747 private CmsJspResourceWrapper m_pageResource; 748 749 /** The parent containers to the given element instance ids. */ 750 private Map<String, CmsContainerBean> m_parentContainers; 751 752 /** Lazily initialized map from a category path to all categories on that path. */ 753 private Map<String, List<CmsCategory>> m_pathCategories; 754 755 /** Lazily initialized map from the root path of a resource to all categories assigned to the resource. */ 756 private Map<String, CmsJspCategoryAccessBean> m_resourceCategories; 757 758 /** Map from root paths to site relative paths. */ 759 private Map<String, String> m_sitePaths; 760 761 /** The lazy initialized map for the detail pages. */ 762 private Map<String, String> m_typeDetailPage; 763 764 /** The VFS content access bean. */ 765 private CmsJspVfsAccessBean m_vfsBean; 766 767 /** 768 * Creates an empty instance.<p> 769 */ 770 private CmsJspStandardContextBean() { 771 772 // NOOP 773 } 774 775 /** 776 * Creates a new standard JSP context bean. 777 * 778 * @param req the current servlet request 779 */ 780 private CmsJspStandardContextBean(ServletRequest req) { 781 782 CmsFlexController controller = CmsFlexController.getController(req); 783 m_request = req; 784 CmsObject cms; 785 if (controller != null) { 786 cms = controller.getCmsObject(); 787 } else { 788 cms = (CmsObject)req.getAttribute(ATTRIBUTE_CMS_OBJECT); 789 } 790 if (cms == null) { 791 // cms object unavailable - this request was not initialized properly 792 throw new CmsRuntimeException( 793 Messages.get().container(Messages.ERR_MISSING_CMS_CONTROLLER_1, CmsJspBean.class.getName())); 794 } 795 updateCmsObject(cms); 796 797 m_detailContentResource = CmsDetailPageResourceHandler.getDetailResource(req); 798 m_detailFunctionPage = CmsDetailPageResourceHandler.getDetailFunctionPage(req); 799 } 800 801 /** 802 * Creates a new instance of the standard JSP context bean.<p> 803 * 804 * To prevent multiple creations of the bean during a request, the OpenCms request context 805 * attributes are used to cache the created VFS access utility bean.<p> 806 * 807 * @param req the current servlet request 808 * 809 * @return a new instance of the standard JSP context bean 810 */ 811 public static CmsJspStandardContextBean getInstance(ServletRequest req) { 812 813 Object attribute = req.getAttribute(ATTRIBUTE_NAME); 814 CmsJspStandardContextBean result; 815 if ((attribute != null) && (attribute instanceof CmsJspStandardContextBean)) { 816 result = (CmsJspStandardContextBean)attribute; 817 } else { 818 result = new CmsJspStandardContextBean(req); 819 req.setAttribute(ATTRIBUTE_NAME, result); 820 } 821 return result; 822 } 823 824 /** 825 * Returns a copy of this JSP context bean.<p> 826 * 827 * @return a copy of this JSP context bean 828 */ 829 public CmsJspStandardContextBean createCopy() { 830 831 CmsJspStandardContextBean result = new CmsJspStandardContextBean(); 832 result.m_container = m_container; 833 if (m_detailContentResource != null) { 834 result.m_detailContentResource = m_detailContentResource.getCopy(); 835 } 836 result.m_element = m_element; 837 result.setPage(m_page); 838 return result; 839 } 840 841 /** 842 * Returns a caching hash specific to the element, it's properties and the current container width.<p> 843 * 844 * @return the caching hash 845 */ 846 public String elementCachingHash() { 847 848 String result = ""; 849 if (m_element != null) { 850 result = m_element.editorHash(); 851 if (m_container != null) { 852 result += "w:" 853 + m_container.getWidth() 854 + "cName:" 855 + m_container.getName() 856 + "cType:" 857 + m_container.getType(); 858 } 859 } 860 return result; 861 } 862 863 /** 864 * Returns the locales available for the currently requested URI. 865 * 866 * @return the locales available for the currently requested URI. 867 */ 868 public List<Locale> getAvailableLocales() { 869 870 return OpenCms.getLocaleManager().getAvailableLocales(m_cms, getRequestContext().getUri()); 871 } 872 873 /** 874 * Helper for easy instantiation and initialization of custom context beans that returns 875 * an instance of the class specified via <code>className</code>, with the current context already set. 876 * 877 * @param className name of the class to instantiate. Must be a subclass of {@link A_CmsJspCustomContextBean}. 878 * @return an instance of the provided class with the current context already set. 879 */ 880 public Object getBean(String className) { 881 882 try { 883 Class<?> clazz = Class.forName(className); 884 if (A_CmsJspCustomContextBean.class.isAssignableFrom(clazz)) { 885 Constructor<?> constructor = clazz.getConstructor(); 886 Object instance = constructor.newInstance(); 887 Method setContextMethod = clazz.getMethod("setContext", CmsJspStandardContextBean.class); 888 setContextMethod.invoke(instance, this); 889 return instance; 890 } else { 891 throw new Exception(); 892 } 893 } catch (Exception e) { 894 LOG.error(Messages.get().container(Messages.ERR_NO_CUSTOM_BEAN_1, className)); 895 } 896 return null; 897 898 } 899 900 /** 901 * Returns the container the currently rendered element is part of.<p> 902 * 903 * @return the currently the currently rendered element is part of 904 */ 905 public CmsContainerBean getContainer() { 906 907 return m_container; 908 } 909 910 /** 911 * Returns the current detail content, or <code>null</code> if no detail content is requested.<p> 912 * 913 * @return the current detail content, or <code>null</code> if no detail content is requested.<p> 914 */ 915 public CmsJspResourceWrapper getDetailContent() { 916 917 return CmsJspResourceWrapper.wrap(m_cms, m_detailContentResource); 918 } 919 920 /** 921 * Returns the structure id of the current detail content, or <code>null</code> if no detail content is requested.<p> 922 * 923 * @return the structure id of the current detail content, or <code>null</code> if no detail content is requested.<p> 924 */ 925 public CmsUUID getDetailContentId() { 926 927 return m_detailContentResource == null ? null : m_detailContentResource.getStructureId(); 928 } 929 930 /** 931 * Returns the detail content site path, or <code>null</code> if not available.<p> 932 * 933 * @return the detail content site path 934 */ 935 public String getDetailContentSitePath() { 936 937 return ((m_cms == null) || (m_detailContentResource == null)) 938 ? null 939 : m_cms.getSitePath(m_detailContentResource); 940 } 941 942 /** 943 * Returns the detail function page.<p> 944 * 945 * @return the detai function page 946 */ 947 public CmsJspResourceWrapper getDetailFunctionPage() { 948 949 return CmsJspResourceWrapper.wrap(m_cms, m_detailFunctionPage); 950 } 951 952 /** 953 * Returns the detail only page.<p> 954 * 955 * @return the detail only page 956 */ 957 public CmsContainerPageBean getDetailOnlyPage() { 958 959 return m_detailOnlyPage; 960 } 961 962 /** 963 * Returns the currently rendered element.<p> 964 * 965 * @return the currently rendered element 966 */ 967 public CmsContainerElementWrapper getElement() { 968 969 return m_element != null ? new CmsContainerElementWrapper(m_element) : null; 970 } 971 972 /** 973 * Returns a lazy initialized map of wrapped element resources by container name.<p> 974 * 975 * @return the lazy map of element resource wrappers 976 */ 977 public Map<String, List<CmsJspResourceWrapper>> getElementsInContainer() { 978 979 return CmsCollectionsGenericWrapper.createLazyMap(obj -> { 980 if (obj instanceof String) { 981 List<CmsJspResourceWrapper> elements = new ArrayList<>(); 982 CmsContainerBean container = getPage().getContainers().get(obj); 983 if (container != null) { 984 for (CmsContainerElementBean element : container.getElements()) { 985 try { 986 element.initResource(m_cms); 987 elements.add(CmsJspResourceWrapper.wrap(m_cms, element.getResource())); 988 } catch (Exception e) { 989 LOG.error(e.getLocalizedMessage(), e); 990 } 991 } 992 } 993 return elements; 994 } else { 995 return null; 996 } 997 }); 998 999 } 1000 1001 /** 1002 * Returns a lazy initialized map of wrapped element resources by container name suffix.<p> 1003 * So in case there is more than one container where the name end with the given suffix, a joined list of elements is returned.<p> 1004 * 1005 * @return the lazy map of element resource wrappers 1006 */ 1007 public Map<String, List<CmsJspResourceWrapper>> getElementsInContainers() { 1008 1009 return CmsCollectionsGenericWrapper.createLazyMap(obj -> { 1010 if (obj instanceof String) { 1011 List<CmsJspResourceWrapper> elements = new ArrayList<>(); 1012 for (CmsContainerBean container : getPage().getContainers().values()) { 1013 if (container.getName().endsWith("-" + obj)) { 1014 for (CmsContainerElementBean element : container.getElements()) { 1015 try { 1016 element.initResource(m_cms); 1017 elements.add(CmsJspResourceWrapper.wrap(m_cms, element.getResource())); 1018 } catch (Exception e) { 1019 LOG.error(e.getLocalizedMessage(), e); 1020 } 1021 } 1022 } 1023 } 1024 return elements; 1025 } else { 1026 return null; 1027 } 1028 }); 1029 1030 } 1031 1032 /** 1033 * Alternative method name for getReloadMarker(). 1034 * 1035 * @see org.opencms.jsp.util.CmsJspStandardContextBean#getReloadMarker() 1036 * 1037 * @return the reload marker 1038 */ 1039 public String getEnableReload() { 1040 1041 return getReloadMarker(); 1042 } 1043 1044 /** 1045 * Returns a lazy initialized Map which allows access to the dynamic function beans using the JSP EL.<p> 1046 * 1047 * When given a key, the returned map will look up the corresponding dynamic function bean in the module configuration.<p> 1048 * 1049 * @return a lazy initialized Map which allows access to the dynamic function beans using the JSP EL 1050 */ 1051 public Map<String, CmsDynamicFunctionBeanWrapper> getFunction() { 1052 1053 if (m_function == null) { 1054 1055 Transformer transformer = new Transformer() { 1056 1057 @Override 1058 public Object transform(Object input) { 1059 1060 try { 1061 CmsDynamicFunctionBean dynamicFunction = readDynamicFunctionBean((String)input); 1062 CmsDynamicFunctionBeanWrapper wrapper = new CmsDynamicFunctionBeanWrapper( 1063 m_cms, 1064 dynamicFunction); 1065 return wrapper; 1066 1067 } catch (CmsException e) { 1068 LOG.debug(e.getLocalizedMessage(), e); 1069 return new CmsDynamicFunctionBeanWrapper(m_cms, null); 1070 } 1071 } 1072 }; 1073 m_function = CmsCollectionsGenericWrapper.createLazyMap(transformer); 1074 } 1075 return m_function; 1076 1077 } 1078 1079 /** 1080 * Deprecated method to access function detail pages using the EL.<p> 1081 * 1082 * @return a lazy initialized Map that provides the detail page link as a value when given the name of a 1083 * (named) dynamic function as a key 1084 * 1085 * @deprecated use {@link #getFunctionDetailPage()} instead 1086 */ 1087 @Deprecated 1088 public Map<String, String> getFunctionDetail() { 1089 1090 return getFunctionDetailPage(); 1091 } 1092 1093 /** 1094 * Returns a lazy initialized Map that provides the detail page link as a value when given the name of a 1095 * (named) dynamic function as a key.<p> 1096 * 1097 * The provided Map key is assumed to be a String that represents a named dynamic function.<p> 1098 * 1099 * Usage example on a JSP with the JSTL:<pre> 1100 * <a href=${cms.functionDetailPage['search']} /> 1101 * </pre> 1102 * 1103 * @return a lazy initialized Map that provides the detail page link as a value when given the name of a 1104 * (named) dynamic function as a key 1105 * 1106 * @see #getTypeDetailPage() 1107 */ 1108 public Map<String, String> getFunctionDetailPage() { 1109 1110 if (m_functionDetailPage == null) { 1111 m_functionDetailPage = CmsCollectionsGenericWrapper.createLazyMap( 1112 new CmsDetailLookupTransformer(CmsDetailPageInfo.FUNCTION_PREFIX)); 1113 } 1114 return m_functionDetailPage; 1115 } 1116 1117 /** 1118 * Returns a lazy map which creates a wrapper object for a dynamic function format when given an XML content 1119 * as a key.<p> 1120 * 1121 * @return a lazy map for accessing function formats for a content 1122 */ 1123 public Map<CmsJspContentAccessBean, CmsDynamicFunctionFormatWrapper> getFunctionFormatFromContent() { 1124 1125 Transformer transformer = new Transformer() { 1126 1127 @Override 1128 public Object transform(Object contentAccess) { 1129 1130 CmsXmlContent content = (CmsXmlContent)(((CmsJspContentAccessBean)contentAccess).getRawContent()); 1131 CmsDynamicFunctionParser parser = new CmsDynamicFunctionParser(); 1132 CmsDynamicFunctionBean functionBean = null; 1133 try { 1134 functionBean = parser.parseFunctionBean(m_cms, content); 1135 } catch (CmsException e) { 1136 LOG.debug(e.getLocalizedMessage(), e); 1137 return new CmsDynamicFunctionFormatWrapper(m_cms, null); 1138 } 1139 String type = getContainer().getType(); 1140 String width = getContainer().getWidth(); 1141 int widthNum = -1; 1142 try { 1143 widthNum = Integer.parseInt(width); 1144 } catch (NumberFormatException e) { 1145 LOG.debug(e.getLocalizedMessage(), e); 1146 } 1147 CmsDynamicFunctionBean.Format format = functionBean.getFormatForContainer(m_cms, type, widthNum); 1148 CmsDynamicFunctionFormatWrapper wrapper = new CmsDynamicFunctionFormatWrapper(m_cms, format); 1149 return wrapper; 1150 } 1151 }; 1152 return CmsCollectionsGenericWrapper.createLazyMap(transformer); 1153 } 1154 1155 /** 1156 * Checks if the current request should be direct edit enabled. 1157 * Online-, history-requests, previews and temporary files will not be editable.<p> 1158 * 1159 * @return <code>true</code> if the current request should be direct edit enabled 1160 */ 1161 public boolean getIsEditMode() { 1162 1163 if (m_isEditMode == null) { 1164 m_isEditMode = Boolean.valueOf(CmsJspTagEditable.isEditableRequest(m_request)); 1165 } 1166 return m_isEditMode.booleanValue(); 1167 } 1168 1169 /** 1170 * Returns true if the current request is a JSON request.<p> 1171 * 1172 * @return true if we are in a JSON request 1173 */ 1174 public boolean getIsJSONRequest() { 1175 1176 return CmsJsonPartFilter.isJsonRequest(m_request); 1177 } 1178 1179 /** 1180 * Returns if the current project is the online project.<p> 1181 * 1182 * @return <code>true</code> if the current project is the online project 1183 */ 1184 public boolean getIsOnlineProject() { 1185 1186 return m_cms.getRequestContext().getCurrentProject().isOnlineProject(); 1187 } 1188 1189 /** 1190 * Returns the current locale.<p> 1191 * 1192 * @return the current locale 1193 */ 1194 public Locale getLocale() { 1195 1196 return getRequestContext().getLocale(); 1197 } 1198 1199 /** 1200 * Gets a map providing access to the locale variants of the current page.<p> 1201 * 1202 * Note that all available locales for the site / subsite are used as keys, not just the ones for which a locale 1203 * variant actually exists. 1204 * 1205 * Usage in JSPs: ${cms.localeResource['de']] 1206 * 1207 * @return the map from locale strings to locale variant resources 1208 */ 1209 public Map<String, CmsJspResourceWrapper> getLocaleResource() { 1210 1211 Map<String, CmsJspResourceWrapper> result = getPageResource().getLocaleResource(); 1212 List<Locale> locales = CmsLocaleGroupService.getPossibleLocales(m_cms, getPageResource()); 1213 for (Locale locale : locales) { 1214 if (!result.containsKey(locale.toString())) { 1215 result.put(locale.toString(), null); 1216 } 1217 } 1218 return result; 1219 } 1220 1221 /** 1222 * Gets the main locale for the current page's locale group.<p> 1223 * 1224 * @return the main locale for the current page's locale group 1225 */ 1226 public Locale getMainLocale() { 1227 1228 return getPageResource().getMainLocale(); 1229 } 1230 1231 /** 1232 * Returns the meta mappings map.<p> 1233 * 1234 * @return the meta mappings 1235 */ 1236 public Map<String, String> getMeta() { 1237 1238 initMetaMappings(); 1239 return CmsCollectionsGenericWrapper.createLazyMap(new MetaLookupTranformer()); 1240 } 1241 1242 /** 1243 * Returns the currently displayed container page.<p> 1244 * 1245 * @return the currently displayed container page 1246 */ 1247 public CmsContainerPageBean getPage() { 1248 1249 return m_page; 1250 } 1251 1252 /** 1253 * Returns the container page bean for the give page and locale.<p> 1254 * 1255 * @param page the container page resource as id, path or already as resource 1256 * @param locale the content locale as locale or string 1257 * 1258 * @return the container page bean 1259 */ 1260 public CmsContainerPageBean getPage(Object page, Object locale) { 1261 1262 CmsResource pageResource = null; 1263 CmsContainerPageBean result = null; 1264 if (m_cms != null) { 1265 try { 1266 pageResource = CmsJspElFunctions.convertRawResource(m_cms, page); 1267 Locale l = CmsJspElFunctions.convertLocale(locale); 1268 result = getPage(pageResource); 1269 if (result != null) { 1270 CmsADEConfigData adeConfig = OpenCms.getADEManager().lookupConfiguration( 1271 m_cms, 1272 pageResource.getRootPath()); 1273 for (CmsContainerBean container : result.getContainers().values()) { 1274 for (CmsContainerElementBean element : container.getElements()) { 1275 boolean isGroupContainer = element.isGroupContainer(m_cms); 1276 boolean isInheritedContainer = element.isInheritedContainer(m_cms); 1277 I_CmsFormatterBean formatterConfig = null; 1278 if (!isGroupContainer && !isInheritedContainer) { 1279 element.initResource(m_cms); 1280 // ensure that the formatter configuration id is added to the element settings, so it will be persisted on save 1281 formatterConfig = CmsJspTagContainer.getFormatterConfigurationForElement( 1282 m_cms, 1283 element, 1284 adeConfig, 1285 container.getName(), 1286 "", 1287 0); 1288 if (formatterConfig != null) { 1289 element.initSettings(m_cms, formatterConfig, l, m_request, null); 1290 } 1291 } 1292 } 1293 } 1294 } 1295 } catch (Exception e) { 1296 LOG.warn(e.getLocalizedMessage(), e); 1297 } 1298 1299 } 1300 return result; 1301 } 1302 1303 /** 1304 * Returns the current container page resource.<p> 1305 * 1306 * @return the current container page resource 1307 */ 1308 public CmsJspResourceWrapper getPageResource() { 1309 1310 try { 1311 if (m_pageResource == null) { 1312 // get the container page itself, checking the history first 1313 m_pageResource = CmsJspResourceWrapper.wrap( 1314 m_cms, 1315 (CmsResource)CmsHistoryResourceHandler.getHistoryResource(m_request)); 1316 if (m_pageResource == null) { 1317 m_pageResource = CmsJspResourceWrapper.wrap( 1318 m_cms, 1319 m_cms.readResource(m_cms.getRequestContext().getUri())); 1320 } 1321 } 1322 } catch (CmsException e) { 1323 LOG.error(e.getLocalizedMessage(), e); 1324 } 1325 return m_pageResource; 1326 } 1327 1328 /** 1329 * Returns the parent container to the current container if available.<p> 1330 * 1331 * @return the parent container 1332 */ 1333 public CmsContainerBean getParentContainer() { 1334 1335 CmsContainerBean result = null; 1336 if ((getContainer() != null) && (getContainer().getParentInstanceId() != null)) { 1337 result = m_parentContainers.get(getContainer().getParentInstanceId()); 1338 } 1339 return result; 1340 } 1341 1342 /** 1343 * Returns the instance id parent container mapping.<p> 1344 * 1345 * @return the instance id parent container mapping 1346 */ 1347 public Map<String, CmsContainerBean> getParentContainers() { 1348 1349 if (m_parentContainers == null) { 1350 initPageData(); 1351 } 1352 return Collections.unmodifiableMap(m_parentContainers); 1353 } 1354 1355 /** 1356 * Returns the parent element to the current element if available.<p> 1357 * 1358 * @return the parent element or null 1359 */ 1360 public CmsContainerElementBean getParentElement() { 1361 1362 return getParentElement(getElement()); 1363 } 1364 1365 /** 1366 * JSP EL accessor method for retrieving the preview formatters.<p> 1367 * 1368 * @return a lazy map for accessing preview formatters 1369 */ 1370 public Map<String, String> getPreviewFormatter() { 1371 1372 Transformer transformer = new Transformer() { 1373 1374 @Override 1375 public Object transform(Object uri) { 1376 1377 try { 1378 String rootPath = m_cms.getRequestContext().addSiteRoot((String)uri); 1379 CmsResource resource = m_cms.readResource((String)uri); 1380 CmsADEManager adeManager = OpenCms.getADEManager(); 1381 CmsADEConfigData configData = adeManager.lookupConfiguration(m_cms, rootPath); 1382 CmsFormatterConfiguration formatterConfig = configData.getFormatters(m_cms, resource); 1383 if (formatterConfig == null) { 1384 return ""; 1385 } 1386 I_CmsFormatterBean previewFormatter = formatterConfig.getPreviewFormatter(); 1387 if (previewFormatter == null) { 1388 return ""; 1389 } 1390 CmsUUID structureId = previewFormatter.getJspStructureId(); 1391 m_cms.readResource(structureId); 1392 CmsResource formatterResource = m_cms.readResource(structureId); 1393 String formatterSitePath = m_cms.getRequestContext().removeSiteRoot( 1394 formatterResource.getRootPath()); 1395 return formatterSitePath; 1396 } catch (CmsException e) { 1397 LOG.warn(e.getLocalizedMessage(), e); 1398 return ""; 1399 } 1400 } 1401 }; 1402 return CmsCollectionsGenericWrapper.createLazyMap(transformer); 1403 } 1404 1405 /** 1406 * Reads all sub-categories below the provided category. 1407 * @return The map from the provided category to it's sub-categories in a {@link CmsJspCategoryAccessBean}. 1408 */ 1409 public Map<String, CmsJspCategoryAccessBean> getReadAllSubCategories() { 1410 1411 if (null == m_allSubCategories) { 1412 m_allSubCategories = CmsCollectionsGenericWrapper.createLazyMap(new Transformer() { 1413 1414 @Override 1415 public Object transform(Object categoryPath) { 1416 1417 try { 1418 List<CmsCategory> categories = CmsCategoryService.getInstance().readCategories( 1419 m_cms, 1420 (String)categoryPath, 1421 true, 1422 m_cms.getRequestContext().getUri()); 1423 CmsJspCategoryAccessBean result = new CmsJspCategoryAccessBean( 1424 m_cms, 1425 categories, 1426 (String)categoryPath); 1427 return result; 1428 } catch (CmsException e) { 1429 LOG.warn(e.getLocalizedMessage(), e); 1430 return null; 1431 } 1432 } 1433 1434 }); 1435 } 1436 return m_allSubCategories; 1437 } 1438 1439 /** 1440 * Reads the categories assigned to the currently requested URI. 1441 * @return the categories assigned to the currently requested URI. 1442 */ 1443 public CmsJspCategoryAccessBean getReadCategories() { 1444 1445 return getReadResourceCategories().get(getRequestContext().getRootUri()); 1446 } 1447 1448 /** 1449 * Transforms the category path of a category to the category. 1450 * @return a map from root or site path to category. 1451 */ 1452 public Map<String, CmsCategory> getReadCategory() { 1453 1454 if (null == m_categories) { 1455 m_categories = CmsCollectionsGenericWrapper.createLazyMap(new Transformer() { 1456 1457 public Object transform(Object categoryPath) { 1458 1459 try { 1460 CmsCategoryService catService = CmsCategoryService.getInstance(); 1461 return catService.localizeCategory( 1462 m_cms, 1463 catService.readCategory(m_cms, (String)categoryPath, getRequestContext().getUri()), 1464 m_cms.getRequestContext().getLocale()); 1465 } catch (CmsException e) { 1466 LOG.warn(e.getLocalizedMessage(), e); 1467 return null; 1468 } 1469 } 1470 1471 }); 1472 } 1473 return m_categories; 1474 } 1475 1476 /** 1477 * Transforms the category path to the list of all categories on that path.<p> 1478 * 1479 * Example: For path <code>"location/europe/"</code> 1480 * the list <code>[getReadCategory.get("location/"),getReadCategory.get("location/europe/")]</code> 1481 * is returned. 1482 * @return a map from a category path to list of categories on that path. 1483 */ 1484 public Map<String, List<CmsCategory>> getReadPathCategories() { 1485 1486 if (null == m_pathCategories) { 1487 m_pathCategories = CmsCollectionsGenericWrapper.createLazyMap(new Transformer() { 1488 1489 public Object transform(Object categoryPath) { 1490 1491 List<CmsCategory> result = new ArrayList<CmsCategory>(); 1492 1493 String path = (String)categoryPath; 1494 1495 if ((null == path) || (path.length() <= 1)) { 1496 return result; 1497 } 1498 1499 //cut last slash 1500 path = path.substring(0, path.length() - 1); 1501 1502 List<String> pathParts = Arrays.asList(path.split("/")); 1503 1504 String currentPath = ""; 1505 for (String part : pathParts) { 1506 currentPath += part + "/"; 1507 CmsCategory category = getReadCategory().get(currentPath); 1508 if (null != category) { 1509 result.add(category); 1510 } 1511 } 1512 return CmsCategoryService.getInstance().localizeCategories( 1513 m_cms, 1514 result, 1515 m_cms.getRequestContext().getLocale()); 1516 } 1517 1518 }); 1519 } 1520 return m_pathCategories; 1521 } 1522 1523 /** 1524 * Reads the categories assigned to a resource. 1525 * 1526 * @return map from the resource path (root path) to the assigned categories 1527 */ 1528 public Map<String, CmsJspCategoryAccessBean> getReadResourceCategories() { 1529 1530 if (null == m_resourceCategories) { 1531 m_resourceCategories = CmsCollectionsGenericWrapper.createLazyMap(new Transformer() { 1532 1533 public Object transform(Object resourceName) { 1534 1535 try { 1536 CmsResource resource = m_cms.readResource( 1537 getRequestContext().removeSiteRoot((String)resourceName)); 1538 return new CmsJspCategoryAccessBean(m_cms, resource); 1539 } catch (CmsException e) { 1540 LOG.warn(e.getLocalizedMessage(), e); 1541 return null; 1542 } 1543 } 1544 }); 1545 } 1546 return m_resourceCategories; 1547 } 1548 1549 /** 1550 * Returns a HTML comment string that will cause the container page editor to reload the page if the element or its settings 1551 * were edited.<p> 1552 * 1553 * @return the reload marker 1554 */ 1555 public String getReloadMarker() { 1556 1557 if (m_cms.getRequestContext().getCurrentProject().isOnlineProject()) { 1558 return ""; // reload marker is not needed in Online mode 1559 } else { 1560 return CmsGwtConstants.FORMATTER_RELOAD_MARKER; 1561 } 1562 } 1563 1564 /** 1565 * Returns the request context.<p> 1566 * 1567 * @return the request context 1568 */ 1569 public CmsRequestContext getRequestContext() { 1570 1571 return m_cms.getRequestContext(); 1572 } 1573 1574 /** 1575 * Returns the current site.<p> 1576 * 1577 * @return the current site 1578 */ 1579 public CmsSite getSite() { 1580 1581 return OpenCms.getSiteManager().getSiteForSiteRoot(m_cms.getRequestContext().getSiteRoot()); 1582 } 1583 1584 /** 1585 * Transforms root paths to site paths. 1586 * 1587 * @return lazy map from root paths to site paths. 1588 * 1589 * @see CmsRequestContext#removeSiteRoot(String) 1590 */ 1591 public Map<String, String> getSitePath() { 1592 1593 if (m_sitePaths == null) { 1594 m_sitePaths = CmsCollectionsGenericWrapper.createLazyMap(new Transformer() { 1595 1596 public Object transform(Object rootPath) { 1597 1598 if (rootPath instanceof String) { 1599 return getRequestContext().removeSiteRoot((String)rootPath); 1600 } 1601 return null; 1602 } 1603 }); 1604 } 1605 return m_sitePaths; 1606 } 1607 1608 /** 1609 * Returns the subsite path for the currently requested URI.<p> 1610 * 1611 * @return the subsite path 1612 */ 1613 public String getSubSitePath() { 1614 1615 return m_cms.getRequestContext().removeSiteRoot( 1616 OpenCms.getADEManager().getSubSiteRoot(m_cms, m_cms.getRequestContext().getRootUri())); 1617 } 1618 1619 /** 1620 * Returns the system information.<p> 1621 * 1622 * @return the system information 1623 */ 1624 public CmsSystemInfo getSystemInfo() { 1625 1626 return OpenCms.getSystemInfo(); 1627 } 1628 1629 /** 1630 * Gets a bean containing information about the current template.<p> 1631 * 1632 * @return the template information bean 1633 */ 1634 public TemplateBean getTemplate() { 1635 1636 TemplateBean templateBean = getRequestAttribute(CmsTemplateContextManager.ATTR_TEMPLATE_BEAN); 1637 if (templateBean == null) { 1638 templateBean = new TemplateBean("", ""); 1639 } 1640 return templateBean; 1641 } 1642 1643 /** 1644 * Returns the title of a page delivered from OpenCms, usually used for the <code><title></code> tag of 1645 * a HTML page.<p> 1646 * 1647 * If no title information has been found, the empty String "" is returned.<p> 1648 * 1649 * @return the title of the current page 1650 */ 1651 public String getTitle() { 1652 1653 return getLocaleSpecificTitle(null); 1654 1655 } 1656 1657 /** 1658 * Get the title and read the Title property according the provided locale. 1659 * @return The map from locales to the locale specific titles. 1660 */ 1661 public Map<String, String> getTitleLocale() { 1662 1663 if (m_localeTitles == null) { 1664 m_localeTitles = CmsCollectionsGenericWrapper.createLazyMap(new Transformer() { 1665 1666 public Object transform(Object inputLocale) { 1667 1668 Locale locale = null; 1669 if (null != inputLocale) { 1670 if (inputLocale instanceof Locale) { 1671 locale = (Locale)inputLocale; 1672 } else if (inputLocale instanceof String) { 1673 try { 1674 locale = LocaleUtils.toLocale((String)inputLocale); 1675 } catch (IllegalArgumentException | NullPointerException e) { 1676 // do nothing, just go on without locale 1677 } 1678 } 1679 } 1680 return getLocaleSpecificTitle(locale); 1681 } 1682 1683 }); 1684 } 1685 return m_localeTitles; 1686 } 1687 1688 /** 1689 * Returns a lazy initialized Map that provides the detail page link as a value when given the name of a 1690 * resource type as a key.<p> 1691 * 1692 * The provided Map key is assumed to be the name of a resource type that has a detail page configured.<p> 1693 * 1694 * Usage example on a JSP with the JSTL:<pre> 1695 * <a href=${cms.typeDetailPage['bs-blog']} /> 1696 * </pre> 1697 * 1698 * @return a lazy initialized Map that provides the detail page link as a value when given the name of a 1699 * resource type as a key 1700 * 1701 * @see #getFunctionDetailPage() 1702 */ 1703 public Map<String, String> getTypeDetailPage() { 1704 1705 if (m_typeDetailPage == null) { 1706 m_typeDetailPage = CmsCollectionsGenericWrapper.createLazyMap(new CmsDetailLookupTransformer("")); 1707 } 1708 return m_typeDetailPage; 1709 } 1710 1711 /** 1712 * Returns an initialized VFS access bean.<p> 1713 * 1714 * @return an initialized VFS access bean 1715 */ 1716 public CmsJspVfsAccessBean getVfs() { 1717 1718 if (m_vfsBean == null) { 1719 // create a new VVFS access bean 1720 m_vfsBean = CmsJspVfsAccessBean.create(m_cms); 1721 } 1722 return m_vfsBean; 1723 } 1724 1725 /** 1726 * Returns the workplace locale from the current user's settings.<p> 1727 * 1728 * @return returns the workplace locale from the current user's settings 1729 */ 1730 public Locale getWorkplaceLocale() { 1731 1732 return OpenCms.getWorkplaceManager().getWorkplaceLocale(m_cms); 1733 } 1734 1735 /** 1736 * Returns an EL access wrapper map for the given object.<p> 1737 * 1738 * If the object is a {@link CmsResource}, then a {@link CmsJspResourceWrapper} is returned. 1739 * Otherwise the object is wrapped in a {@link CmsJspObjectValueWrapper}.<p> 1740 * 1741 * If the object is already is a wrapper, it is returned unchanged.<p> 1742 * 1743 * @return an EL access wrapper map for the given object 1744 */ 1745 public Map<Object, Object> getWrap() { 1746 1747 return CmsCollectionsGenericWrapper.createLazyMap(obj -> { 1748 1749 if ((obj instanceof A_CmsJspValueWrapper) || (obj instanceof CmsJspResourceWrapper)) { 1750 return obj; 1751 } else if (obj instanceof CmsResource) { 1752 return CmsJspResourceWrapper.wrap(m_cms, (CmsResource)obj); 1753 } else { 1754 return CmsJspObjectValueWrapper.createWrapper(m_cms, obj); 1755 } 1756 }); 1757 } 1758 1759 /** 1760 * Initializes the requested container page.<p> 1761 * 1762 * @throws CmsException in case reading the requested resource fails 1763 */ 1764 public void initPage() throws CmsException { 1765 1766 if ((m_page == null) && (m_cms != null)) { 1767 String requestUri = m_cms.getRequestContext().getUri(); 1768 // get the container page itself, checking the history first 1769 CmsResource pageResource = (CmsResource)CmsHistoryResourceHandler.getHistoryResource(m_request); 1770 if (pageResource == null) { 1771 pageResource = m_cms.readResource(requestUri); 1772 } 1773 m_page = getPage(pageResource); 1774 m_page = CmsTemplateMapper.get(m_request).transformContainerpageBean( 1775 m_cms, 1776 m_page, 1777 pageResource.getRootPath()); 1778 1779 } 1780 } 1781 1782 /** 1783 * Returns <code>true</code in case a detail page is available for the current element.<p> 1784 * 1785 * @return <code>true</code in case a detail page is available for the current element 1786 */ 1787 public boolean isDetailPageAvailable() { 1788 1789 boolean result = false; 1790 if ((m_cms != null) 1791 && (m_element != null) 1792 && !m_element.isInMemoryOnly() 1793 && (m_element.getResource() != null)) { 1794 try { 1795 String detailPage = OpenCms.getADEManager().getDetailPageFinder().getDetailPage( 1796 m_cms, 1797 m_element.getResource().getRootPath(), 1798 m_cms.getRequestContext().getUri(), 1799 null); 1800 result = detailPage != null; 1801 } catch (CmsException e) { 1802 LOG.warn(e.getLocalizedMessage(), e); 1803 } 1804 } 1805 return result; 1806 } 1807 1808 /** 1809 * Returns <code>true</code> if this is a request to a detail resource, <code>false</code> otherwise.<p> 1810 * 1811 * Same as to check if {@link #getDetailContent()} is <code>null</code>.<p> 1812 * 1813 * @return <code>true</code> if this is a request to a detail resource, <code>false</code> otherwise 1814 */ 1815 public boolean isDetailRequest() { 1816 1817 return m_detailContentResource != null; 1818 } 1819 1820 /** 1821 * Returns if the page is in drag mode.<p> 1822 * 1823 * @return if the page is in drag mode 1824 */ 1825 public boolean isDragMode() { 1826 1827 return m_isDragMode; 1828 } 1829 1830 /** 1831 * Returns the flag to indicate if in drag and drop mode.<p> 1832 * 1833 * @return <code>true</code> if in drag and drop mode 1834 */ 1835 public boolean isEdited() { 1836 1837 return m_edited; 1838 } 1839 1840 /** 1841 * Returns if the current element is a model group.<p> 1842 * 1843 * @return <code>true</code> if the current element is a model group 1844 */ 1845 public boolean isModelGroupElement() { 1846 1847 return (m_element != null) && !m_element.isInMemoryOnly() && isModelGroupPage() && m_element.isModelGroup(); 1848 } 1849 1850 /** 1851 * Returns if the current page is used to manage model groups.<p> 1852 * 1853 * @return <code>true</code> if the current page is used to manage model groups 1854 */ 1855 public boolean isModelGroupPage() { 1856 1857 CmsResource page = getPageResource(); 1858 return (page != null) && CmsContainerpageService.isEditingModelGroups(m_cms, page); 1859 1860 } 1861 1862 /** 1863 * Sets the container the currently rendered element is part of.<p> 1864 * 1865 * @param container the container the currently rendered element is part of 1866 */ 1867 public void setContainer(CmsContainerBean container) { 1868 1869 m_container = container; 1870 } 1871 1872 /** 1873 * Sets the detail only page.<p> 1874 * 1875 * @param detailOnlyPage the detail only page to set 1876 */ 1877 public void setDetailOnlyPage(CmsContainerPageBean detailOnlyPage) { 1878 1879 m_detailOnlyPage = detailOnlyPage; 1880 clearPageData(); 1881 } 1882 1883 /** 1884 * Sets if the page is in drag mode.<p> 1885 * 1886 * @param isDragMode if the page is in drag mode 1887 */ 1888 public void setDragMode(boolean isDragMode) { 1889 1890 m_isDragMode = isDragMode; 1891 } 1892 1893 /** 1894 * Sets the flag to indicate if in drag and drop mode.<p> 1895 * 1896 * @param edited <code>true</code> if in drag and drop mode 1897 */ 1898 public void setEdited(boolean edited) { 1899 1900 m_edited = edited; 1901 } 1902 1903 /** 1904 * Sets the currently rendered element.<p> 1905 * 1906 * @param element the currently rendered element to set 1907 */ 1908 public void setElement(CmsContainerElementBean element) { 1909 1910 m_element = element; 1911 } 1912 1913 /** 1914 * Sets the currently displayed container page.<p> 1915 * 1916 * @param page the currently displayed container page to set 1917 */ 1918 public void setPage(CmsContainerPageBean page) { 1919 1920 m_page = page; 1921 clearPageData(); 1922 } 1923 1924 /** 1925 * Updates the internally stored OpenCms user context.<p> 1926 * 1927 * @param cms the new OpenCms user context 1928 */ 1929 public void updateCmsObject(CmsObject cms) { 1930 1931 try { 1932 m_cms = OpenCms.initCmsObject(cms); 1933 } catch (CmsException e) { 1934 LOG.error(e.getLocalizedMessage(), e); 1935 m_cms = cms; 1936 } 1937 } 1938 1939 /** 1940 * Updates the standard context bean from the request.<p> 1941 * 1942 * @param cmsFlexRequest the request from which to update the data 1943 */ 1944 public void updateRequestData(CmsFlexRequest cmsFlexRequest) { 1945 1946 CmsResource detailRes = CmsDetailPageResourceHandler.getDetailResource(cmsFlexRequest); 1947 m_detailContentResource = detailRes; 1948 m_request = cmsFlexRequest; 1949 1950 } 1951 1952 /** 1953 * Returns the formatter configuration to the given element.<p> 1954 * 1955 * @param element the element 1956 * 1957 * @return the formatter configuration 1958 */ 1959 protected I_CmsFormatterBean getElementFormatter(CmsContainerElementBean element) { 1960 1961 if (m_elementInstances == null) { 1962 initPageData(); 1963 } 1964 I_CmsFormatterBean formatter = null; 1965 CmsContainerBean container = m_parentContainers.get(element.getInstanceId()); 1966 if (container == null) { 1967 // use the current container 1968 container = getContainer(); 1969 } 1970 if (container != null) { 1971 String containerName = container.getName(); 1972 Map<String, String> settings = element.getSettings(); 1973 if (settings != null) { 1974 String formatterConfigId = settings.get(CmsFormatterConfig.getSettingsKeyForContainer(containerName)); 1975 if (CmsUUID.isValidUUID(formatterConfigId)) { 1976 formatter = OpenCms.getADEManager().getCachedFormatters(false).getFormatters().get( 1977 new CmsUUID(formatterConfigId)); 1978 } 1979 } 1980 if (formatter == null) { 1981 try { 1982 CmsResource resource = m_cms.readResource(m_cms.getRequestContext().getUri()); 1983 1984 CmsADEConfigData config = OpenCms.getADEManager().lookupConfiguration( 1985 m_cms, 1986 resource.getRootPath()); 1987 CmsFormatterConfiguration formatters = config.getFormatters(m_cms, resource); 1988 int width = -2; 1989 try { 1990 width = Integer.parseInt(container.getWidth()); 1991 } catch (Exception e) { 1992 LOG.debug(e.getLocalizedMessage(), e); 1993 } 1994 formatter = formatters.getDefaultSchemaFormatter(container.getType(), width); 1995 } catch (CmsException e1) { 1996 if (LOG.isWarnEnabled()) { 1997 LOG.warn(e1.getLocalizedMessage(), e1); 1998 } 1999 } 2000 } 2001 } 2002 return formatter; 2003 } 2004 2005 /** 2006 * Returns the title according to the given locale. 2007 * @param locale the locale for which the title should be read. 2008 * @return the title according to the given locale 2009 */ 2010 protected String getLocaleSpecificTitle(Locale locale) { 2011 2012 String result = null; 2013 2014 try { 2015 2016 if (isDetailRequest()) { 2017 // this is a request to a detail page 2018 CmsResource res = getDetailContent(); 2019 CmsFile file = m_cms.readFile(res); 2020 CmsXmlContent content = CmsXmlContentFactory.unmarshal(m_cms, file); 2021 result = content.getHandler().getTitleMapping(m_cms, content, m_cms.getRequestContext().getLocale()); 2022 if (result == null) { 2023 // title not found, maybe no mapping OR not available in the current locale 2024 // read the title of the detail resource as fall back (may contain mapping from another locale) 2025 result = m_cms.readPropertyObject( 2026 res, 2027 CmsPropertyDefinition.PROPERTY_TITLE, 2028 false, 2029 locale).getValue(); 2030 } 2031 } 2032 if (result == null) { 2033 // read the title of the requested resource as fall back 2034 result = m_cms.readPropertyObject( 2035 m_cms.getRequestContext().getUri(), 2036 CmsPropertyDefinition.PROPERTY_TITLE, 2037 true, 2038 locale).getValue(); 2039 } 2040 } catch (CmsException e) { 2041 LOG.debug(e.getLocalizedMessage(), e); 2042 } 2043 if (CmsStringUtil.isEmptyOrWhitespaceOnly(result)) { 2044 result = ""; 2045 } 2046 2047 return result; 2048 } 2049 2050 /** 2051 * Returns the parent element if available.<p> 2052 * 2053 * @param element the element 2054 * 2055 * @return the parent element or null 2056 */ 2057 protected CmsContainerElementBean getParentElement(CmsContainerElementBean element) { 2058 2059 if (m_elementInstances == null) { 2060 initPageData(); 2061 } 2062 CmsContainerElementBean parent = null; 2063 CmsContainerBean cont = m_parentContainers.get(element.getInstanceId()); 2064 if ((cont != null) && cont.isNestedContainer()) { 2065 parent = m_elementInstances.get(cont.getParentInstanceId()); 2066 } 2067 return parent; 2068 } 2069 2070 /** 2071 * Reads a dynamic function bean, given its name in the module configuration.<p> 2072 * 2073 * @param configuredName the name of the dynamic function in the module configuration 2074 * @return the dynamic function bean for the dynamic function configured under that name 2075 * 2076 * @throws CmsException if something goes wrong 2077 */ 2078 protected CmsDynamicFunctionBean readDynamicFunctionBean(String configuredName) throws CmsException { 2079 2080 CmsADEConfigData config = OpenCms.getADEManager().lookupConfiguration( 2081 m_cms, 2082 m_cms.addSiteRoot(m_cms.getRequestContext().getUri())); 2083 CmsFunctionReference functionRef = config.getFunctionReference(configuredName); 2084 if (functionRef == null) { 2085 return null; 2086 } 2087 CmsDynamicFunctionParser parser = new CmsDynamicFunctionParser(); 2088 CmsResource functionResource = m_cms.readResource(functionRef.getStructureId()); 2089 CmsDynamicFunctionBean result = parser.parseFunctionBean(m_cms, functionResource); 2090 return result; 2091 } 2092 2093 /** 2094 * Adds the mappings of the given formatter configuration.<p> 2095 * 2096 * @param formatterBean the formatter bean 2097 * @param elementId the element content structure id 2098 * @param resolver The macro resolver used on key and default value of the mappings 2099 * @param isDetailContent in case of a detail content 2100 */ 2101 private void addMappingsForFormatter( 2102 I_CmsFormatterBean formatterBean, 2103 CmsUUID elementId, 2104 CmsMacroResolver resolver, 2105 boolean isDetailContent) { 2106 2107 if ((formatterBean != null) && (formatterBean.getMetaMappings() != null)) { 2108 for (CmsMetaMapping map : formatterBean.getMetaMappings()) { 2109 String key = map.getKey(); 2110 key = resolver.resolveMacros(key); 2111 // the detail content mapping overrides other mappings 2112 if (isDetailContent 2113 || !m_metaMappings.containsKey(key) 2114 || (m_metaMappings.get(key).m_order <= map.getOrder())) { 2115 MetaMapping mapping = new MetaMapping(); 2116 mapping.m_key = key; 2117 mapping.m_elementXPath = map.getElement(); 2118 mapping.m_defaultValue = resolver.resolveMacros(map.getDefaultValue()); 2119 mapping.m_order = map.getOrder(); 2120 mapping.m_contentId = elementId; 2121 m_metaMappings.put(key, mapping); 2122 } 2123 } 2124 } 2125 } 2126 2127 /** 2128 * Clears the page element data.<p> 2129 */ 2130 private void clearPageData() { 2131 2132 m_elementInstances = null; 2133 m_parentContainers = null; 2134 } 2135 2136 /** 2137 * Returns the container page bean for the give resource.<p> 2138 * 2139 * @param pageResource the resource 2140 * 2141 * @return the container page bean 2142 * 2143 * @throws CmsException in case reading the page bean fails 2144 */ 2145 private CmsContainerPageBean getPage(CmsResource pageResource) throws CmsException { 2146 2147 CmsContainerPageBean result = null; 2148 if ((pageResource != null) && CmsResourceTypeXmlContainerPage.isContainerPage(pageResource)) { 2149 CmsXmlContainerPage xmlContainerPage = CmsXmlContainerPageFactory.unmarshal(m_cms, pageResource, m_request); 2150 result = xmlContainerPage.getContainerPage(m_cms); 2151 CmsModelGroupHelper modelHelper = new CmsModelGroupHelper( 2152 m_cms, 2153 OpenCms.getADEManager().lookupConfiguration(m_cms, pageResource.getRootPath()), 2154 CmsJspTagEditable.isEditableRequest(m_request) && (m_request instanceof HttpServletRequest) 2155 ? CmsADESessionCache.getCache((HttpServletRequest)m_request, m_cms) 2156 : null, 2157 CmsContainerpageService.isEditingModelGroups(m_cms, pageResource)); 2158 result = modelHelper.readModelGroups(xmlContainerPage.getContainerPage(m_cms)); 2159 } 2160 return result; 2161 } 2162 2163 /** 2164 * Convenience method for getting a request attribute without an explicit cast.<p> 2165 * 2166 * @param name the attribute name 2167 * @return the request attribute 2168 */ 2169 @SuppressWarnings("unchecked") 2170 private <A> A getRequestAttribute(String name) { 2171 2172 Object attribute = m_request.getAttribute(name); 2173 2174 return attribute != null ? (A)attribute : null; 2175 } 2176 2177 /** 2178 * Initializes the mapping configuration.<p> 2179 */ 2180 private void initMetaMappings() { 2181 2182 if (m_metaMappings == null) { 2183 m_metaMappings = new HashMap<String, MetaMapping>(); 2184 try { 2185 initPage(); 2186 CmsMacroResolver resolver = new CmsMacroResolver(); 2187 resolver.setKeepEmptyMacros(true); 2188 resolver.setCmsObject(m_cms); 2189 resolver.setMessages(OpenCms.getWorkplaceManager().getMessages(getLocale())); 2190 CmsResourceFilter filter = getIsEditMode() 2191 ? CmsResourceFilter.IGNORE_EXPIRATION 2192 : CmsResourceFilter.DEFAULT; 2193 for (CmsContainerBean container : m_page.getContainers().values()) { 2194 for (CmsContainerElementBean element : container.getElements()) { 2195 String settingsKey = CmsFormatterConfig.getSettingsKeyForContainer(container.getName()); 2196 String formatterConfigId = element.getSettings() != null 2197 ? element.getSettings().get(settingsKey) 2198 : null; 2199 I_CmsFormatterBean formatterBean = null; 2200 if (CmsUUID.isValidUUID(formatterConfigId)) { 2201 formatterBean = OpenCms.getADEManager().getCachedFormatters( 2202 m_cms.getRequestContext().getCurrentProject().isOnlineProject()).getFormatters().get( 2203 new CmsUUID(formatterConfigId)); 2204 } 2205 if ((formatterBean != null) 2206 && formatterBean.useMetaMappingsForNormalElements() 2207 && m_cms.existsResource(element.getId(), filter)) { 2208 addMappingsForFormatter(formatterBean, element.getId(), resolver, false); 2209 } 2210 2211 } 2212 } 2213 if (getDetailContentId() != null) { 2214 try { 2215 CmsResource detailContent = m_cms.readResource( 2216 getDetailContentId(), 2217 CmsResourceFilter.ignoreExpirationOffline(m_cms)); 2218 CmsFormatterConfiguration config = OpenCms.getADEManager().lookupConfiguration( 2219 m_cms, 2220 m_cms.getRequestContext().getRootUri()).getFormatters(m_cms, detailContent); 2221 for (I_CmsFormatterBean formatter : config.getDetailFormatters()) { 2222 addMappingsForFormatter(formatter, getDetailContentId(), resolver, true); 2223 } 2224 } catch (CmsException e) { 2225 LOG.error( 2226 Messages.get().getBundle().key( 2227 Messages.ERR_READING_REQUIRED_RESOURCE_1, 2228 getDetailContentId()), 2229 e); 2230 } 2231 } 2232 } catch (Exception e) { 2233 LOG.error(e.getLocalizedMessage(), e); 2234 } 2235 } 2236 } 2237 2238 /** 2239 * Initializes the page element data.<p> 2240 */ 2241 private void initPageData() { 2242 2243 m_elementInstances = new HashMap<String, CmsContainerElementBean>(); 2244 m_parentContainers = new HashMap<String, CmsContainerBean>(); 2245 if (m_page != null) { 2246 for (CmsContainerBean container : m_page.getContainers().values()) { 2247 for (CmsContainerElementBean element : container.getElements()) { 2248 m_elementInstances.put(element.getInstanceId(), element); 2249 m_parentContainers.put(element.getInstanceId(), container); 2250 try { 2251 if (element.isGroupContainer(m_cms) || element.isInheritedContainer(m_cms)) { 2252 List<CmsContainerElementBean> children; 2253 if (element.isGroupContainer(m_cms)) { 2254 children = CmsJspTagContainer.getGroupContainerElements( 2255 m_cms, 2256 element, 2257 m_request, 2258 container.getType()); 2259 } else { 2260 children = CmsJspTagContainer.getInheritedContainerElements(m_cms, element); 2261 } 2262 for (CmsContainerElementBean childElement : children) { 2263 m_elementInstances.put(childElement.getInstanceId(), childElement); 2264 m_parentContainers.put(childElement.getInstanceId(), container); 2265 } 2266 } 2267 } catch (CmsException e) { 2268 LOG.error(e.getLocalizedMessage(), e); 2269 } 2270 } 2271 } 2272 // also add detail only data 2273 if (m_detailOnlyPage != null) { 2274 for (CmsContainerBean container : m_detailOnlyPage.getContainers().values()) { 2275 for (CmsContainerElementBean element : container.getElements()) { 2276 m_elementInstances.put(element.getInstanceId(), element); 2277 m_parentContainers.put(element.getInstanceId(), container); 2278 } 2279 } 2280 } 2281 } 2282 } 2283 2284}