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; 029 030import org.opencms.file.CmsFile; 031import org.opencms.file.CmsFolder; 032import org.opencms.file.CmsObject; 033import org.opencms.file.CmsProperty; 034import org.opencms.file.CmsPropertyDefinition; 035import org.opencms.file.CmsRequestContext; 036import org.opencms.file.CmsResource; 037import org.opencms.file.CmsResourceFilter; 038import org.opencms.file.types.CmsResourceTypeXmlContent; 039import org.opencms.file.types.CmsResourceTypeXmlPage; 040import org.opencms.i18n.CmsLocaleGroup; 041import org.opencms.jsp.util.CmsJspCategoryAccessBean; 042import org.opencms.jsp.util.CmsJspContentAccessBean; 043import org.opencms.jsp.util.CmsJspImageBean; 044import org.opencms.jsp.util.CmsJspValueTransformers.CmsLocalePropertyLoaderTransformer; 045import org.opencms.loader.CmsLoaderException; 046import org.opencms.main.CmsException; 047import org.opencms.main.CmsLog; 048import org.opencms.main.OpenCms; 049import org.opencms.relations.CmsRelation; 050import org.opencms.relations.CmsRelationFilter; 051import org.opencms.security.CmsSecurityException; 052import org.opencms.util.CmsCollectionsGenericWrapper; 053import org.opencms.util.CmsUUID; 054 055import java.util.ArrayList; 056import java.util.Collections; 057import java.util.HashMap; 058import java.util.List; 059import java.util.Locale; 060import java.util.Map; 061import java.util.stream.Collectors; 062 063import org.apache.commons.logging.Log; 064 065/** 066 * Wrapper subclass of CmsResource with some convenience methods.<p> 067 */ 068public class CmsJspResourceWrapper extends CmsResource { 069 070 /** Logger instance for this class. */ 071 @SuppressWarnings("unused") 072 private static final Log LOG = CmsLog.getLog(CmsJspResourceWrapper.class); 073 074 /** Serial version id. */ 075 private static final long serialVersionUID = 1L; 076 077 /** Parameter value used to select outgoing relations. */ 078 public static final boolean RELATIONS_OUT = true; 079 080 /** Parameter value used to select incoming relations. */ 081 public static final boolean RELATIONS_IN = false; 082 083 /** All resources that are sources of incoming relations. */ 084 public List<CmsJspResourceWrapper> m_incomingRelations; 085 086 /** All resources that are targets of outgoing relations. */ 087 public List<CmsJspResourceWrapper> m_outgoingRelations; 088 089 /** All parent folder of this resource in the current site as a list. */ 090 public List<CmsJspResourceWrapper> m_parentFolders; 091 092 /** The category access bean for this resource. */ 093 private CmsJspCategoryAccessBean m_categories; 094 095 /** The CMS context. */ 096 private CmsObject m_cms; 097 098 /** The resource / file content as a String. */ 099 private String m_content; 100 101 /** The file object for this resource. */ 102 private CmsFile m_file; 103 104 /** Image bean instance created from this resource. */ 105 private CmsJspImageBean m_imageBean; 106 107 /** Stores if this resource is an XML content or not. */ 108 private Boolean m_isXml; 109 110 /** The set of locale variants. */ 111 private Map<String, CmsJspResourceWrapper> m_localeResources; 112 113 /** The main locale. */ 114 private Locale m_mainLocale; 115 116 /** The navigation builder for this resource. */ 117 private CmsJspNavBuilder m_navBuilder; 118 119 /** The navigation info element for this resource. */ 120 private CmsJspNavElement m_navigation; 121 122 /** The default file of this resource, assumed that this resource is a folder. */ 123 private CmsJspResourceWrapper m_navigationDefaultFile; 124 125 /** The navigation info elements in this resource, assuming that this resource is a folder. */ 126 private List<CmsJspNavElement> m_navigationForFolder; 127 128 /** The parent folder of this resource in the current site. */ 129 private CmsJspResourceWrapper m_parentFolder; 130 131 /** Properties of this resource. */ 132 private Map<String, String> m_properties; 133 134 /** Locale properties of this resource. */ 135 private Map<String, Map<String, String>> m_propertiesLocale; 136 137 /** Locale properties of this resource with search. */ 138 private Map<String, Map<String, String>> m_propertiesLocaleSearch; 139 140 /** Properties of this resource with search. */ 141 private Map<String, String> m_propertiesSearch; 142 143 /** The calculated site path of the resource. */ 144 private String m_sitePath; 145 146 /** The type name of the resource. */ 147 private String m_typeName; 148 149 /** The XML content access bean. */ 150 private CmsJspContentAccessBean m_xml; 151 152 /** 153 * Creates a new instance.<p> 154 * 155 * @param cms the current CMS context 156 * @param res the resource to wrap 157 */ 158 private CmsJspResourceWrapper(CmsObject cms, CmsResource res) { 159 160 super( 161 res.getStructureId(), 162 res.getResourceId(), 163 res.getRootPath(), 164 res.getTypeId(), 165 res.isFolder(), 166 res.getFlags(), 167 res.getProjectLastModified(), 168 res.getState(), 169 res.getDateCreated(), 170 res.getUserCreated(), 171 res.getDateLastModified(), 172 res.getUserLastModified(), 173 res.getDateReleased(), 174 res.getDateExpired(), 175 res.getSiblingCount(), 176 res.getLength(), 177 res.getDateContent(), 178 res.getVersion()); 179 m_cms = cms; 180 m_file = null; 181 m_content = ""; 182 } 183 184 /** 185 * Factory method to create a new {@link CmsJspResourceWrapper} instance from a {@link CmsResource}.<p> 186 * 187 * In case the parameter resource already is a wrapped resource AND the OpenCms request context is 188 * the same as the provided context, the parameter object is returned.<p> 189 * 190 * @param cms the current CMS context 191 * @param res the resource to wrap 192 * 193 * @return a new instance of a {@link CmsJspResourceWrapper} 194 */ 195 public static CmsJspResourceWrapper wrap(CmsObject cms, CmsResource res) { 196 197 CmsJspResourceWrapper result = null; 198 if ((cms != null) && (res != null)) { 199 if (res instanceof CmsJspResourceWrapper) { 200 CmsJspResourceWrapper wrapper = (CmsJspResourceWrapper)res; 201 if (cms.getRequestContext().getSiteRoot().equals(wrapper.getRequestContext().getSiteRoot())) { 202 result = wrapper; 203 } else { 204 result = new CmsJspResourceWrapper(cms, res); 205 } 206 } else { 207 result = new CmsJspResourceWrapper(cms, res); 208 } 209 } 210 return result; 211 } 212 213 /** 214 * Two resources are considered equal in case their structure id is equal.<p> 215 * 216 * @see CmsResource#equals(java.lang.Object) 217 */ 218 @Override 219 public boolean equals(Object obj) { 220 221 if (obj == null) { 222 return false; 223 } 224 225 if (obj == this) { 226 return true; 227 } 228 if (obj instanceof CmsResource) { 229 return ((CmsResource)obj).getStructureId().equals(getStructureId()); 230 } 231 return false; 232 } 233 234 /** 235 * Returns the categories assigned to this resource.<p> 236 * 237 * @return the categories assigned to this resource 238 */ 239 public CmsJspCategoryAccessBean getCategories() { 240 241 if (m_categories == null) { 242 m_categories = new CmsJspCategoryAccessBean(m_cms, this); 243 } 244 return m_categories; 245 } 246 247 /** 248 * Returns the OpenCms user context this resource was initialized with.<p> 249 * 250 * @return the OpenCms user context this resource was initialized with 251 */ 252 public CmsObject getCmsObject() { 253 254 return m_cms; 255 } 256 257 /** 258 * Returns the content of the file as a String.<p> 259 * 260 * @return the content of the file as a String 261 */ 262 public String getContent() { 263 264 if ((m_content.length() == 0) && (getFile() != null)) { 265 m_content = new String(getFile().getContents()); 266 } 267 return m_content; 268 } 269 270 /** 271 * Returns this resources name extension (if present).<p> 272 * 273 * The extension will always be lower case.<p> 274 * 275 * @return the extension or <code>null</code> if not available 276 * 277 * @see CmsResource#getExtension(String) 278 * @see org.opencms.jsp.util.CmsJspVfsAccessBean#getResourceExtension(Object) 279 */ 280 public String getExtension() { 281 282 return getExtension(getRootPath()); 283 } 284 285 /** 286 * Returns the full file object for this resource.<p> 287 * 288 * @return the full file object for this resource 289 */ 290 public CmsFile getFile() { 291 292 if ((m_file == null) && !isFolder()) { 293 try { 294 m_file = m_cms.readFile(this); 295 } catch (CmsException e) { 296 // this should not happen since we are updating from a resource object 297 } 298 } 299 return m_file; 300 } 301 302 /** 303 * Returns the folder of this resource.<p> 304 * 305 * In case this resource already is a {@link CmsFolder}, it is returned without modification. 306 * In case it is a {@link CmsFile}, the parent folder of the file is returned.<p> 307 * 308 * @return the folder of this resource 309 * 310 * @see #getSitePathFolder() 311 */ 312 public CmsJspResourceWrapper getFolder() { 313 314 CmsJspResourceWrapper result; 315 if (isFolder()) { 316 result = this; 317 } else { 318 result = readResource(getSitePathFolder()); 319 } 320 return result; 321 } 322 323 /** 324 * Gets a list of resource wrappers for resources with relations pointing to this resource. 325 * 326 * @return the list of resource wrappers 327 */ 328 public List<CmsJspResourceWrapper> getIncomingRelations() { 329 330 if (m_incomingRelations == null) { 331 m_incomingRelations = getRelatedResources(RELATIONS_IN); 332 } 333 return m_incomingRelations; 334 } 335 336 /** 337 * Gets a list of resource wrappers for resources with relations pointing to this resource, for a specific type. 338 * 339 * @param typeName name of the type to filter 340 * @return the list of resource wrappers 341 */ 342 public List<CmsJspResourceWrapper> getIncomingRelations(String typeName) { 343 344 return getIncomingRelations().stream().filter(res -> res.getTypeName().equals(typeName)).collect( 345 Collectors.toList()); 346 } 347 348 /** 349 * Returns <code>true</code> in case this resource is an image in the VFS.<p> 350 * 351 * @return <code>true</code> in case this resource is an image in the VFS 352 */ 353 public boolean getIsImage() { 354 355 return getToImage().isImage(); 356 } 357 358 /** 359 * Returns <code>true</code> in case this resource is an XML content.<p> 360 * 361 * @return <code>true</code> in case this resource is an XML content 362 */ 363 public boolean getIsXml() { 364 365 if (m_isXml == null) { 366 m_isXml = Boolean.valueOf( 367 CmsResourceTypeXmlPage.isXmlPage(this) || CmsResourceTypeXmlContent.isXmlContent(this)); 368 } 369 return m_isXml.booleanValue(); 370 } 371 372 /** 373 * Returns a substituted link to this resource.<p> 374 * 375 * @return the link 376 */ 377 public String getLink() { 378 379 return OpenCms.getLinkManager().substituteLinkForUnknownTarget( 380 m_cms, 381 m_cms.getRequestContext().getSitePath(this)); 382 } 383 384 /** 385 * Returns a map of the locale group for the current resource, with locale strings as keys.<p> 386 * 387 * @return a map with locale strings as keys and resource wrappers for the corresponding locale variants 388 */ 389 public Map<String, CmsJspResourceWrapper> getLocaleResource() { 390 391 if (m_localeResources != null) { 392 return m_localeResources; 393 } 394 try { 395 CmsLocaleGroup localeGroup = m_cms.getLocaleGroupService().readLocaleGroup(this); 396 Map<Locale, CmsResource> resourcesByLocale = localeGroup.getResourcesByLocale(); 397 Map<String, CmsJspResourceWrapper> result = new HashMap<>(); 398 for (Map.Entry<Locale, CmsResource> entry : resourcesByLocale.entrySet()) { 399 result.put(entry.getKey().toString(), CmsJspResourceWrapper.wrap(m_cms, entry.getValue())); 400 } 401 m_localeResources = result; 402 return result; 403 } catch (CmsException e) { 404 return new HashMap<String, CmsJspResourceWrapper>(); 405 } 406 } 407 408 /** 409 * Returns the main locale for this resource.<p> 410 * 411 * @return the main locale for this resource 412 */ 413 public Locale getMainLocale() { 414 415 if (m_mainLocale != null) { 416 return m_mainLocale; 417 } 418 try { 419 CmsLocaleGroup localeGroup = m_cms.getLocaleGroupService().readLocaleGroup(this); 420 m_mainLocale = localeGroup.getMainLocale(); 421 return m_mainLocale; 422 } catch (CmsException e) { 423 return null; 424 } 425 } 426 427 /** 428 * Returns the mime type for this resource.<p> 429 * 430 * In case no valid mime type can be determined from the file extension, <code>text/plain</code> is returned.<p> 431 * 432 * @return the mime type for this resource 433 */ 434 public String getMimeType() { 435 436 return OpenCms.getResourceManager().getMimeType(getRootPath(), null, "text/plain"); 437 } 438 439 /** 440 * Returns the navigation builder for this resource.<p> 441 * 442 * This will be initialized with this resource as default URI.<p> 443 * 444 * @return the navigation builder for this resource 445 */ 446 public CmsJspNavBuilder getNavBuilder() { 447 448 if (m_navBuilder == null) { 449 m_navBuilder = new CmsJspNavBuilder(); 450 m_navBuilder.init(m_cms, null, getSitePath()); 451 } 452 return m_navBuilder; 453 } 454 455 /** 456 * Returns the navigation info element for this resource.<p> 457 * 458 * @return the navigation info element for this resource 459 */ 460 public CmsJspNavElement getNavigation() { 461 462 if (m_navigation == null) { 463 m_navigation = getNavBuilder().getNavigationForResource(); 464 } 465 return m_navigation; 466 } 467 468 /** 469 * Returns the default resource for this resource.<p> 470 * 471 * If this resource is a file, then this file is returned.<p> 472 * 473 * Otherwise, in case this resource is a folder:<br> 474 * <ol> 475 * <li>the {@link CmsPropertyDefinition#PROPERTY_DEFAULT_FILE} is checked, and 476 * <li>if still no file could be found, the configured default files in the 477 * <code>opencms-vfs.xml</code> configuration are iterated until a match is 478 * found, and 479 * <li>if still no file could be found, <code>null</code> is returned 480 * </ol> 481 * 482 * @return the default file for the given folder 483 * 484 * @see CmsObject#readDefaultFile(CmsResource, CmsResourceFilter) 485 */ 486 public CmsJspResourceWrapper getNavigationDefaultFile() { 487 488 if (m_navigationDefaultFile == null) { 489 if (isFolder()) { 490 try { 491 m_navigationDefaultFile = wrap(m_cms, m_cms.readDefaultFile(this, CmsResourceFilter.DEFAULT)); 492 } catch (CmsSecurityException e) { 493 if (LOG.isDebugEnabled()) { 494 LOG.debug(e.getMessage(), e); 495 } 496 } 497 } 498 } else { 499 m_navigationDefaultFile = this; 500 } 501 return m_navigationDefaultFile; 502 } 503 504 /** 505 * Returns the navigation info elements in this resource, assuming that this resource is a folder.<p> 506 * 507 * @return the navigation info elements in this resource, assuming that this resource is a folder 508 */ 509 public List<CmsJspNavElement> getNavigationForFolder() { 510 511 if (m_navigationForFolder == null) { 512 m_navigationForFolder = getNavBuilder().getNavigationForFolder(); 513 } 514 return m_navigationForFolder; 515 } 516 517 /** 518 * Returns the substituted online link to this resource.<p> 519 * 520 * @return the link 521 */ 522 public String getOnlineLink() { 523 524 return OpenCms.getLinkManager().getOnlineLink(m_cms, m_cms.getRequestContext().getSitePath(this)); 525 } 526 527 /** 528 * Gets a list of resources with relations pointing to them from this resources, as resource wrappers. 529 * 530 * @return the list of resource wrappers 531 */ 532 public List<CmsJspResourceWrapper> getOutgoingRelations() { 533 534 if (m_outgoingRelations == null) { 535 m_outgoingRelations = getRelatedResources(RELATIONS_OUT); 536 } 537 return m_outgoingRelations; 538 } 539 540 /** 541 * Gets a list of resources with relations pointing to them from this resources, as resource wrappers. 542 * 543 * Only gets resources with the given type. 544 * 545 * @param typeName the name of the type to filter 546 * @return the list of resource wrappers 547 */ 548 549 public List<CmsJspResourceWrapper> getOutgoingRelations(String typeName) { 550 551 return getOutgoingRelations().stream().filter(res -> res.getTypeName().equals(typeName)).collect( 552 Collectors.toList()); 553 } 554 555 /** 556 * Returns the parent folder of this resource in the current site.<p> 557 * 558 * The parent folder of a file is the folder of the file. 559 * The parent folder of a folder is the parent folder of the folder. 560 * The parent folder of the root folder is <code>null</code>.<p> 561 * 562 * @return the parent folder of this resource in the current site 563 * 564 * @see #getSitePathParentFolder() 565 * @see CmsResource#getParentFolder(String) 566 * @see org.opencms.jsp.util.CmsJspVfsAccessBean#getParentFolder(Object) 567 */ 568 public CmsJspResourceWrapper getParentFolder() { 569 570 if (m_parentFolder == null) { 571 String parentFolder = getSitePathParentFolder(); 572 if (parentFolder != null) { 573 m_parentFolder = readResource(getSitePathParentFolder()); 574 } 575 } 576 return m_parentFolder; 577 } 578 579 /** 580 * Returns all parent folder of this resource in the current site as a list.<p> 581 * 582 * First resource in the list will be the direct parent folder of this resource, 583 * the last element will be the site root folder.<p> 584 * 585 * @return all parent folder of this resource in the current site as a list 586 */ 587 public List<CmsJspResourceWrapper> getParentFolders() { 588 589 if (m_parentFolders == null) { 590 m_parentFolders = new ArrayList<CmsJspResourceWrapper>(); 591 CmsJspResourceWrapper parentFolder = getParentFolder(); 592 while (parentFolder != null) { 593 m_parentFolders.add(parentFolder); 594 parentFolder = parentFolder.getParentFolder(); 595 } 596 } 597 return m_parentFolders; 598 } 599 600 /** 601 * Returns the direct properties of this resource in a map.<p> 602 * 603 * This is without "search", so it will not include inherited properties from the parent folders.<p> 604 * 605 * @return the direct properties of this resource in a map 606 */ 607 public Map<String, String> getProperty() { 608 609 if (m_properties == null) { 610 try { 611 List<CmsProperty> properties = m_cms.readPropertyObjects(this, false); 612 m_properties = CmsProperty.toMap(properties); 613 } catch (CmsException e) { 614 if (LOG.isDebugEnabled()) { 615 LOG.debug(e.getMessage(), e); 616 } 617 } 618 } 619 return m_properties; 620 } 621 622 /** 623 * Returns the direct properties of this resource in a map for a given locale.<p> 624 * 625 * This is without "search", so it will not include inherited properties from the parent folders.<p> 626 * 627 * @return the direct properties of this resource in a map for a given locale 628 */ 629 public Map<String, Map<String, String>> getPropertyLocale() { 630 631 if (m_propertiesLocale == null) { 632 m_propertiesLocale = CmsCollectionsGenericWrapper.createLazyMap( 633 new CmsLocalePropertyLoaderTransformer(getCmsObject(), this, false)); 634 // result may still be null 635 return (m_propertiesLocale == null) ? Collections.EMPTY_MAP : m_propertiesLocale; 636 } 637 return m_propertiesLocale; 638 } 639 640 /** 641 * Returns the searched properties of this resource in a map for a given locale.<p> 642 * 643 * This is with "search", so it will include inherited properties from the parent folders.<p> 644 * 645 * @return the direct properties of this resource in a map for a given locale 646 */ 647 public Map<String, Map<String, String>> getPropertyLocaleSearch() { 648 649 if (m_propertiesLocaleSearch == null) { 650 m_propertiesLocaleSearch = CmsCollectionsGenericWrapper.createLazyMap( 651 new CmsLocalePropertyLoaderTransformer(getCmsObject(), this, true)); 652 // result may still be null 653 return (m_propertiesLocaleSearch == null) ? Collections.EMPTY_MAP : m_propertiesLocaleSearch; 654 } 655 return m_propertiesLocaleSearch; 656 } 657 658 /** 659 * Returns the searched properties of this resource in a map.<p> 660 * 661 * This is with "search", so it will include inherited properties from the parent folders.<p> 662 * 663 * @return the direct properties of this resource in a map 664 */ 665 public Map<String, String> getPropertySearch() { 666 667 if (m_propertiesSearch == null) { 668 try { 669 List<CmsProperty> properties = m_cms.readPropertyObjects(this, true); 670 m_propertiesSearch = CmsProperty.toMap(properties); 671 } catch (CmsException e) { 672 if (LOG.isDebugEnabled()) { 673 LOG.debug(e.getMessage(), e); 674 } 675 } 676 } 677 return m_propertiesSearch; 678 } 679 680 /** 681 * Returns the OpenCms user request context this resource was initialized with.<p> 682 * 683 * @return the OpenCms user request context this resource was initialized with 684 */ 685 public CmsRequestContext getRequestContext() { 686 687 return m_cms.getRequestContext(); 688 } 689 690 /** 691 * Returns this resources name extension (if present).<p> 692 * 693 * The extension will always be lower case.<p> 694 * 695 * @return the extension or <code>null</code> if not available 696 * 697 * @see CmsResource#getExtension(String) 698 * @see org.opencms.jsp.util.CmsJspVfsAccessBean#getResourceExtension(Object) 699 */ 700 public String getResourceExtension() { 701 702 return getExtension(); 703 } 704 705 /** 706 * Returns the name of this resource without the path information.<p> 707 * 708 * The resource name of a file is the name of the file. 709 * The resource name of a folder is the folder name with trailing "/". 710 * The resource name of the root folder is <code>/</code>.<p> 711 * 712 * @return the name of this resource without the path information 713 * 714 * @see CmsResource#getName() 715 * @see org.opencms.jsp.util.CmsJspVfsAccessBean#getResourceName(Object) 716 */ 717 public String getResourceName() { 718 719 return getName(); 720 } 721 722 /** 723 * Returns the folder name of this resource from the root site.<p> 724 * 725 * In case this resource already is a {@link CmsFolder}, the folder path is returned without modification. 726 * In case it is a {@link CmsFile}, the parent folder name of the file is returned.<p> 727 * 728 * @return the folder name of this resource from the root site 729 */ 730 public String getRootPathFolder() { 731 732 String result; 733 if (isFile()) { 734 result = getRootPathParentFolder(); 735 } else { 736 result = getRootPath(); 737 } 738 return result; 739 } 740 741 /** 742 * Returns the directory level of a resource from the root site.<p> 743 * 744 * The root folder "/" has level 0, 745 * a folder "/foo/" would have level 1, 746 * a folder "/foo/bar/" level 2 etc.<p> 747 * 748 * @return the directory level of a resource from the root site 749 * 750 * @see CmsResource#getPathLevel(String) 751 */ 752 public int getRootPathLevel() { 753 754 return getPathLevel(getRootPath()); 755 } 756 757 /** 758 * Returns the parent folder of this resource from the root site.<p> 759 * 760 * @return the parent folder of this resource from the root site 761 * 762 * @see CmsResource#getParentFolder(String) 763 */ 764 public String getRootPathParentFolder() { 765 766 return getParentFolder(getRootPath()); 767 } 768 769 /** 770 * Returns the current site path to this resource.<p> 771 * 772 * @return the current site path to this resource 773 * 774 * @see org.opencms.file.CmsRequestContext#getSitePath(CmsResource) 775 */ 776 public String getSitePath() { 777 778 if (m_sitePath == null) { 779 m_sitePath = m_cms.getRequestContext().getSitePath(this); 780 } 781 782 return m_sitePath; 783 } 784 785 /** 786 * Returns the folder name of this resource in the current site.<p> 787 * 788 * In case this resource already is a {@link CmsFolder}, the folder path is returned without modification. 789 * In case it is a {@link CmsFile}, the parent folder name of the file is returned.<p> 790 * 791 * @return the folder name of this resource in the current site 792 */ 793 public String getSitePathFolder() { 794 795 String result; 796 if (isFile()) { 797 result = getSitePathParentFolder(); 798 } else { 799 result = getSitePath(); 800 } 801 return result; 802 } 803 804 /** 805 * Returns the directory level of a resource in the current site.<p> 806 * 807 * The root folder "/" has level 0, 808 * a folder "/foo/" would have level 1, 809 * a folder "/foo/bar/" level 2 etc.<p> 810 * 811 * @return the directory level of a resource in the current site 812 * 813 * @see CmsResource#getPathLevel(String) 814 * @see org.opencms.jsp.util.CmsJspVfsAccessBean#getPathLevel(Object) 815 */ 816 public int getSitePathLevel() { 817 818 return getPathLevel(getSitePath()); 819 } 820 821 /** 822 * Returns the parent folder of this resource in the current site.<p> 823 * 824 * The parent folder of a file is the folder of the file. 825 * The parent folder of a folder is the parent folder of the folder. 826 * The parent folder of the root folder is <code>null</code>.<p> 827 * 828 * @return the parent folder of this resource in the current site 829 * 830 * @see CmsResource#getParentFolder(String) 831 * @see org.opencms.jsp.util.CmsJspVfsAccessBean#getParentFolder(Object) 832 */ 833 public String getSitePathParentFolder() { 834 835 return getParentFolder(getSitePath()); 836 } 837 838 /** 839 * Returns a scaled image bean from the wrapped value.<p> 840 * 841 * In case the value does not point to an image resource, <code>null</code> is returned. 842 * 843 * @return the scaled image bean 844 */ 845 public CmsJspImageBean getToImage() { 846 847 if (m_imageBean == null) { 848 m_imageBean = new CmsJspImageBean(getCmsObject(), this, null); 849 } 850 return m_imageBean; 851 } 852 853 /** 854 * Returns this resource wrapper.<p> 855 * 856 * This is included because in case {@link org.opencms.jsp.util.CmsJspStandardContextBean#getWrap()} is used, the result may be 857 * either a {@link org.opencms.jsp.util.CmsJspObjectValueWrapper} or a {@link CmsJspResourceWrapper}. 858 * Using {@link #getToResource()} on the result will always return a resource wrapper this way.<p> 859 * 860 * @return this resource wrapper 861 * 862 * @see org.opencms.jsp.util.CmsJspStandardContextBean#getWrap() 863 * @see org.opencms.jsp.util.CmsJspObjectValueWrapper#getToResource() 864 */ 865 public CmsJspResourceWrapper getToResource() { 866 867 return this; 868 } 869 870 /** 871 * Returns an XML content access bean created for this resource.<p> 872 * 873 * In case this resource is not an XML content, <code>null</code> is returned.<p> 874 * 875 * @return an XML content access bean created for this resource 876 * 877 * @see #getIsXml() 878 */ 879 public CmsJspContentAccessBean getToXml() { 880 881 if ((m_xml == null) && getIsXml()) { 882 m_xml = new CmsJspContentAccessBean(m_cms, this); 883 } 884 return m_xml; 885 } 886 887 /** 888 * Returns the resource type name.<p> 889 * 890 * @return the resource type name 891 */ 892 public String getTypeName() { 893 894 if (m_typeName == null) { 895 try { 896 m_typeName = OpenCms.getResourceManager().getResourceType(getTypeId()).getTypeName(); 897 } catch (CmsLoaderException e) { 898 // this should never happen, and anyway it is logged in the resource manage already 899 } 900 } 901 return m_typeName; 902 } 903 904 /** 905 * Returns an XML content access bean created for this resource.<p> 906 * 907 * In case this resource is not an XML content, <code>null</code> is returned.<p> 908 * 909 * @return an XML content access bean created for this resource 910 * 911 * @see #getToXml() 912 * @see #getIsXml() 913 */ 914 public CmsJspContentAccessBean getXml() { 915 916 return getToXml(); 917 } 918 919 /** 920 * @see CmsResource#hashCode() 921 * @see java.lang.Object#hashCode() 922 */ 923 @Override 924 public int hashCode() { 925 926 if (getStructureId() != null) { 927 return getStructureId().hashCode(); 928 } 929 930 return CmsUUID.getNullUUID().hashCode(); 931 } 932 933 /** 934 * Returns <code>true</code> in case this resource is child resource of the provided resource which is assumed to be a folder.<p> 935 * 936 * @param resource the resource to check 937 * 938 * @return <code>true</code> in case this resource is child resource of the provided resource which is assumed to be a folder 939 */ 940 public boolean isChildResourceOf(CmsResource resource) { 941 942 return (resource != null) 943 && resource.isFolder() 944 && !(getStructureId().equals(resource.getStructureId())) 945 && ((getRootPath().indexOf(resource.getRootPath()) == 0)); 946 } 947 948 /** 949 * Returns <code>true</code> in case this resource is child resource of the provided resource path which is assumed to be a folder in the current site.<p> 950 * 951 * No check is performed to see if the provided site path resource actually exists.<p> 952 * 953 * @param sitePath the resource to check 954 * 955 * @return <code>true</code> in case this resource is child resource of the provided resource path which is assumed to be a folder in the current site 956 */ 957 public boolean isChildResourceOf(String sitePath) { 958 959 return (sitePath != null) 960 && ((getSitePath().indexOf(sitePath) == 0)) 961 && (sitePath.length() < getSitePath().length()); 962 } 963 964 /** 965 * Returns <code>true</code> in case this resource is a parent folder of the provided resource.<p> 966 * 967 * @param resource the resource to check 968 * 969 * @return <code>true</code> in case this resource is a parent folder of the provided resource 970 */ 971 public boolean isParentFolderOf(CmsResource resource) { 972 973 return (resource != null) 974 && isFolder() 975 && !(getStructureId().equals(resource.getStructureId())) 976 && ((resource.getRootPath().indexOf(getRootPath()) == 0)); 977 } 978 979 /** 980 * Returns <code>true</code> in case this resource is a parent folder of the provided resource path in the current site.<p> 981 * 982 * No check is performed to see if the provided site path resource actually exists.<p> 983 * 984 * @param sitePath the path to check 985 * 986 * @return <code>true</code> in case this resource is a parent folder of the provided resource path in the current site 987 */ 988 public boolean isParentFolderOf(String sitePath) { 989 990 return (sitePath != null) 991 && isFolder() 992 && ((sitePath.indexOf(getSitePath()) == 0)) 993 && (sitePath.length() > getSitePath().length()); 994 } 995 996 /** 997 * Helper method for getting the related resources for this resource, with a given resource filter. 998 * 999 * @param out - true for outgoing relations, false for incoming relations 1000 * @return the list of related resources 1001 */ 1002 private List<CmsJspResourceWrapper> getRelatedResources(boolean out) { 1003 1004 CmsObject cms = getCmsObject(); 1005 List<CmsJspResourceWrapper> result = new ArrayList<>(); 1006 try { 1007 CmsRelationFilter filter = out 1008 ? CmsRelationFilter.relationsFromStructureId(getStructureId()) 1009 : CmsRelationFilter.relationsToStructureId(getStructureId()); 1010 List<CmsRelation> relations = cms.readRelations(filter); 1011 for (CmsRelation rel : relations) { 1012 try { 1013 CmsResource other = out 1014 ? rel.getTarget(cms, CmsResourceFilter.DEFAULT) 1015 : rel.getSource(cms, CmsResourceFilter.DEFAULT); 1016 result.add(wrap(cms, other)); 1017 } catch (CmsException e) { 1018 LOG.warn(e.getLocalizedMessage(), e); 1019 } 1020 } 1021 } catch (Exception e) { 1022 LOG.error(e.getLocalizedMessage(), e); 1023 } 1024 return result; 1025 } 1026 1027 /** 1028 * Reads a resource, suppressing possible exceptions.<p> 1029 * 1030 * @param sitePath the site path of the resource to read. 1031 * 1032 * @return the resource of <code>null</code> on case an exception occurred while reading 1033 */ 1034 private CmsJspResourceWrapper readResource(String sitePath) { 1035 1036 CmsJspResourceWrapper result = null; 1037 try { 1038 result = new CmsJspResourceWrapper(m_cms, m_cms.readResource(sitePath)); 1039 } catch (CmsException e) { 1040 if (LOG.isDebugEnabled()) { 1041 LOG.debug(e.getMessage(), e); 1042 } 1043 } 1044 return result; 1045 } 1046}