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 * Gets a list of resources with relations pointing to them from this resources, as resource wrappers. 519 * 520 * @return the list of resource wrappers 521 */ 522 public List<CmsJspResourceWrapper> getOutgoingRelations() { 523 524 if (m_outgoingRelations == null) { 525 m_outgoingRelations = getRelatedResources(RELATIONS_OUT); 526 } 527 return m_outgoingRelations; 528 } 529 530 /** 531 * Gets a list of resources with relations pointing to them from this resources, as resource wrappers. 532 * 533 * Only gets resources with the given type. 534 * 535 * @param typeName the name of the type to filter 536 * @return the list of resource wrappers 537 */ 538 539 public List<CmsJspResourceWrapper> getOutgoingRelations(String typeName) { 540 541 return getOutgoingRelations().stream().filter(res -> res.getTypeName().equals(typeName)).collect( 542 Collectors.toList()); 543 } 544 545 /** 546 * Returns the parent folder of this resource in the current site.<p> 547 * 548 * The parent folder of a file is the folder of the file. 549 * The parent folder of a folder is the parent folder of the folder. 550 * The parent folder of the root folder is <code>null</code>.<p> 551 * 552 * @return the parent folder of this resource in the current site 553 * 554 * @see #getSitePathParentFolder() 555 * @see CmsResource#getParentFolder(String) 556 * @see org.opencms.jsp.util.CmsJspVfsAccessBean#getParentFolder(Object) 557 */ 558 public CmsJspResourceWrapper getParentFolder() { 559 560 if (m_parentFolder == null) { 561 String parentFolder = getSitePathParentFolder(); 562 if (parentFolder != null) { 563 m_parentFolder = readResource(getSitePathParentFolder()); 564 } 565 } 566 return m_parentFolder; 567 } 568 569 /** 570 * Returns all parent folder of this resource in the current site as a list.<p> 571 * 572 * First resource in the list will be the direct parent folder of this resource, 573 * the last element will be the site root folder.<p> 574 * 575 * @return all parent folder of this resource in the current site as a list 576 */ 577 public List<CmsJspResourceWrapper> getParentFolders() { 578 579 if (m_parentFolders == null) { 580 m_parentFolders = new ArrayList<CmsJspResourceWrapper>(); 581 CmsJspResourceWrapper parentFolder = getParentFolder(); 582 while (parentFolder != null) { 583 m_parentFolders.add(parentFolder); 584 parentFolder = parentFolder.getParentFolder(); 585 } 586 } 587 return m_parentFolders; 588 } 589 590 /** 591 * Returns the direct properties of this resource in a map.<p> 592 * 593 * This is without "search", so it will not include inherited properties from the parent folders.<p> 594 * 595 * @return the direct properties of this resource in a map 596 */ 597 public Map<String, String> getProperty() { 598 599 if (m_properties == null) { 600 try { 601 List<CmsProperty> properties = m_cms.readPropertyObjects(this, false); 602 m_properties = CmsProperty.toMap(properties); 603 } catch (CmsException e) { 604 if (LOG.isDebugEnabled()) { 605 LOG.debug(e.getMessage(), e); 606 } 607 } 608 } 609 return m_properties; 610 } 611 612 /** 613 * Returns the direct properties of this resource in a map for a given locale.<p> 614 * 615 * This is without "search", so it will not include inherited properties from the parent folders.<p> 616 * 617 * @return the direct properties of this resource in a map for a given locale 618 */ 619 public Map<String, Map<String, String>> getPropertyLocale() { 620 621 if (m_propertiesLocale == null) { 622 m_propertiesLocale = CmsCollectionsGenericWrapper.createLazyMap( 623 new CmsLocalePropertyLoaderTransformer(getCmsObject(), this, false)); 624 // result may still be null 625 return (m_propertiesLocale == null) ? Collections.EMPTY_MAP : m_propertiesLocale; 626 } 627 return m_propertiesLocale; 628 } 629 630 /** 631 * Returns the searched properties of this resource in a map for a given locale.<p> 632 * 633 * This is with "search", so it will include inherited properties from the parent folders.<p> 634 * 635 * @return the direct properties of this resource in a map for a given locale 636 */ 637 public Map<String, Map<String, String>> getPropertyLocaleSearch() { 638 639 if (m_propertiesLocaleSearch == null) { 640 m_propertiesLocaleSearch = CmsCollectionsGenericWrapper.createLazyMap( 641 new CmsLocalePropertyLoaderTransformer(getCmsObject(), this, true)); 642 // result may still be null 643 return (m_propertiesLocaleSearch == null) ? Collections.EMPTY_MAP : m_propertiesLocaleSearch; 644 } 645 return m_propertiesLocaleSearch; 646 } 647 648 /** 649 * Returns the searched properties of this resource in a map.<p> 650 * 651 * This is with "search", so it will include inherited properties from the parent folders.<p> 652 * 653 * @return the direct properties of this resource in a map 654 */ 655 public Map<String, String> getPropertySearch() { 656 657 if (m_propertiesSearch == null) { 658 try { 659 List<CmsProperty> properties = m_cms.readPropertyObjects(this, true); 660 m_propertiesSearch = CmsProperty.toMap(properties); 661 } catch (CmsException e) { 662 if (LOG.isDebugEnabled()) { 663 LOG.debug(e.getMessage(), e); 664 } 665 } 666 } 667 return m_propertiesSearch; 668 } 669 670 /** 671 * Returns the OpenCms user request context this resource was initialized with.<p> 672 * 673 * @return the OpenCms user request context this resource was initialized with 674 */ 675 public CmsRequestContext getRequestContext() { 676 677 return m_cms.getRequestContext(); 678 } 679 680 /** 681 * Returns this resources name extension (if present).<p> 682 * 683 * The extension will always be lower case.<p> 684 * 685 * @return the extension or <code>null</code> if not available 686 * 687 * @see CmsResource#getExtension(String) 688 * @see org.opencms.jsp.util.CmsJspVfsAccessBean#getResourceExtension(Object) 689 */ 690 public String getResourceExtension() { 691 692 return getExtension(); 693 } 694 695 /** 696 * Returns the name of this resource without the path information.<p> 697 * 698 * The resource name of a file is the name of the file. 699 * The resource name of a folder is the folder name with trailing "/". 700 * The resource name of the root folder is <code>/</code>.<p> 701 * 702 * @return the name of this resource without the path information 703 * 704 * @see CmsResource#getName() 705 * @see org.opencms.jsp.util.CmsJspVfsAccessBean#getResourceName(Object) 706 */ 707 public String getResourceName() { 708 709 return getName(); 710 } 711 712 /** 713 * Returns the folder name of this resource from the root site.<p> 714 * 715 * In case this resource already is a {@link CmsFolder}, the folder path is returned without modification. 716 * In case it is a {@link CmsFile}, the parent folder name of the file is returned.<p> 717 * 718 * @return the folder name of this resource from the root site 719 */ 720 public String getRootPathFolder() { 721 722 String result; 723 if (isFile()) { 724 result = getRootPathParentFolder(); 725 } else { 726 result = getRootPath(); 727 } 728 return result; 729 } 730 731 /** 732 * Returns the directory level of a resource from the root site.<p> 733 * 734 * The root folder "/" has level 0, 735 * a folder "/foo/" would have level 1, 736 * a folder "/foo/bar/" level 2 etc.<p> 737 * 738 * @return the directory level of a resource from the root site 739 * 740 * @see CmsResource#getPathLevel(String) 741 */ 742 public int getRootPathLevel() { 743 744 return getPathLevel(getRootPath()); 745 } 746 747 /** 748 * Returns the parent folder of this resource from the root site.<p> 749 * 750 * @return the parent folder of this resource from the root site 751 * 752 * @see CmsResource#getParentFolder(String) 753 */ 754 public String getRootPathParentFolder() { 755 756 return getParentFolder(getRootPath()); 757 } 758 759 /** 760 * Returns the current site path to this resource.<p> 761 * 762 * @return the current site path to this resource 763 * 764 * @see org.opencms.file.CmsRequestContext#getSitePath(CmsResource) 765 */ 766 public String getSitePath() { 767 768 if (m_sitePath == null) { 769 m_sitePath = m_cms.getRequestContext().getSitePath(this); 770 } 771 772 return m_sitePath; 773 } 774 775 /** 776 * Returns the folder name of this resource in the current site.<p> 777 * 778 * In case this resource already is a {@link CmsFolder}, the folder path is returned without modification. 779 * In case it is a {@link CmsFile}, the parent folder name of the file is returned.<p> 780 * 781 * @return the folder name of this resource in the current site 782 */ 783 public String getSitePathFolder() { 784 785 String result; 786 if (isFile()) { 787 result = getSitePathParentFolder(); 788 } else { 789 result = getSitePath(); 790 } 791 return result; 792 } 793 794 /** 795 * Returns the directory level of a resource in the current site.<p> 796 * 797 * The root folder "/" has level 0, 798 * a folder "/foo/" would have level 1, 799 * a folder "/foo/bar/" level 2 etc.<p> 800 * 801 * @return the directory level of a resource in the current site 802 * 803 * @see CmsResource#getPathLevel(String) 804 * @see org.opencms.jsp.util.CmsJspVfsAccessBean#getPathLevel(Object) 805 */ 806 public int getSitePathLevel() { 807 808 return getPathLevel(getSitePath()); 809 } 810 811 /** 812 * Returns the parent folder of this resource in the current site.<p> 813 * 814 * The parent folder of a file is the folder of the file. 815 * The parent folder of a folder is the parent folder of the folder. 816 * The parent folder of the root folder is <code>null</code>.<p> 817 * 818 * @return the parent folder of this resource in the current site 819 * 820 * @see CmsResource#getParentFolder(String) 821 * @see org.opencms.jsp.util.CmsJspVfsAccessBean#getParentFolder(Object) 822 */ 823 public String getSitePathParentFolder() { 824 825 return getParentFolder(getSitePath()); 826 } 827 828 /** 829 * Returns a scaled image bean from the wrapped value.<p> 830 * 831 * In case the value does not point to an image resource, <code>null</code> is returned. 832 * 833 * @return the scaled image bean 834 */ 835 public CmsJspImageBean getToImage() { 836 837 if (m_imageBean == null) { 838 m_imageBean = new CmsJspImageBean(getCmsObject(), this, null); 839 } 840 return m_imageBean; 841 } 842 843 /** 844 * Returns this resource wrapper.<p> 845 * 846 * This is included because in case {@link org.opencms.jsp.util.CmsJspStandardContextBean#getWrap()} is used, the result may be 847 * either a {@link org.opencms.jsp.util.CmsJspObjectValueWrapper} or a {@link CmsJspResourceWrapper}. 848 * Using {@link #getToResource()} on the result will always return a resource wrapper this way.<p> 849 * 850 * @return this resource wrapper 851 * 852 * @see org.opencms.jsp.util.CmsJspStandardContextBean#getWrap() 853 * @see org.opencms.jsp.util.CmsJspObjectValueWrapper#getToResource() 854 */ 855 public CmsJspResourceWrapper getToResource() { 856 857 return this; 858 } 859 860 /** 861 * Returns an XML content access bean created for this resource.<p> 862 * 863 * In case this resource is not an XML content, <code>null</code> is returned.<p> 864 * 865 * @return an XML content access bean created for this resource 866 * 867 * @see #getIsXml() 868 */ 869 public CmsJspContentAccessBean getToXml() { 870 871 if ((m_xml == null) && getIsXml()) { 872 m_xml = new CmsJspContentAccessBean(m_cms, this); 873 } 874 return m_xml; 875 } 876 877 /** 878 * Returns the resource type name.<p> 879 * 880 * @return the resource type name 881 */ 882 public String getTypeName() { 883 884 if (m_typeName == null) { 885 try { 886 m_typeName = OpenCms.getResourceManager().getResourceType(getTypeId()).getTypeName(); 887 } catch (CmsLoaderException e) { 888 // this should never happen, and anyway it is logged in the resource manage already 889 } 890 } 891 return m_typeName; 892 } 893 894 /** 895 * Returns an XML content access bean created for this resource.<p> 896 * 897 * In case this resource is not an XML content, <code>null</code> is returned.<p> 898 * 899 * @return an XML content access bean created for this resource 900 * 901 * @see #getToXml() 902 * @see #getIsXml() 903 */ 904 public CmsJspContentAccessBean getXml() { 905 906 return getToXml(); 907 } 908 909 /** 910 * @see CmsResource#hashCode() 911 * @see java.lang.Object#hashCode() 912 */ 913 @Override 914 public int hashCode() { 915 916 if (getStructureId() != null) { 917 return getStructureId().hashCode(); 918 } 919 920 return CmsUUID.getNullUUID().hashCode(); 921 } 922 923 /** 924 * Returns <code>true</code> in case this resource is child resource of the provided resource which is assumed to be a folder.<p> 925 * 926 * @param resource the resource to check 927 * 928 * @return <code>true</code> in case this resource is child resource of the provided resource which is assumed to be a folder 929 */ 930 public boolean isChildResourceOf(CmsResource resource) { 931 932 return (resource != null) 933 && resource.isFolder() 934 && !(getStructureId().equals(resource.getStructureId())) 935 && ((getRootPath().indexOf(resource.getRootPath()) == 0)); 936 } 937 938 /** 939 * 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> 940 * 941 * No check is performed to see if the provided site path resource actually exists.<p> 942 * 943 * @param sitePath the resource to check 944 * 945 * @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 946 */ 947 public boolean isChildResourceOf(String sitePath) { 948 949 return (sitePath != null) 950 && ((getSitePath().indexOf(sitePath) == 0)) 951 && (sitePath.length() < getSitePath().length()); 952 } 953 954 /** 955 * Returns <code>true</code> in case this resource is a parent folder of the provided resource.<p> 956 * 957 * @param resource the resource to check 958 * 959 * @return <code>true</code> in case this resource is a parent folder of the provided resource 960 */ 961 public boolean isParentFolderOf(CmsResource resource) { 962 963 return (resource != null) 964 && isFolder() 965 && !(getStructureId().equals(resource.getStructureId())) 966 && ((resource.getRootPath().indexOf(getRootPath()) == 0)); 967 } 968 969 /** 970 * Returns <code>true</code> in case this resource is a parent folder of the provided resource path in the current site.<p> 971 * 972 * No check is performed to see if the provided site path resource actually exists.<p> 973 * 974 * @param sitePath the path to check 975 * 976 * @return <code>true</code> in case this resource is a parent folder of the provided resource path in the current site 977 */ 978 public boolean isParentFolderOf(String sitePath) { 979 980 return (sitePath != null) 981 && isFolder() 982 && ((sitePath.indexOf(getSitePath()) == 0)) 983 && (sitePath.length() > getSitePath().length()); 984 } 985 986 /** 987 * Helper method for getting the related resources for this resource, with a given resource filter. 988 * 989 * @param out - true for outgoing relations, false for incoming relations 990 * @return the list of related resources 991 */ 992 private List<CmsJspResourceWrapper> getRelatedResources(boolean out) { 993 994 CmsObject cms = getCmsObject(); 995 List<CmsJspResourceWrapper> result = new ArrayList<>(); 996 try { 997 CmsRelationFilter filter = out 998 ? CmsRelationFilter.relationsFromStructureId(getStructureId()) 999 : CmsRelationFilter.relationsToStructureId(getStructureId()); 1000 List<CmsRelation> relations = cms.readRelations(filter); 1001 for (CmsRelation rel : relations) { 1002 try { 1003 CmsResource other = out 1004 ? rel.getTarget(cms, CmsResourceFilter.DEFAULT) 1005 : rel.getSource(cms, CmsResourceFilter.DEFAULT); 1006 result.add(wrap(cms, other)); 1007 } catch (CmsException e) { 1008 LOG.warn(e.getLocalizedMessage(), e); 1009 } 1010 } 1011 } catch (Exception e) { 1012 LOG.error(e.getLocalizedMessage(), e); 1013 } 1014 return result; 1015 } 1016 1017 /** 1018 * Reads a resource, suppressing possible exceptions.<p> 1019 * 1020 * @param sitePath the site path of the resource to read. 1021 * 1022 * @return the resource of <code>null</code> on case an exception occurred while reading 1023 */ 1024 private CmsJspResourceWrapper readResource(String sitePath) { 1025 1026 CmsJspResourceWrapper result = null; 1027 try { 1028 result = new CmsJspResourceWrapper(m_cms, m_cms.readResource(sitePath)); 1029 } catch (CmsException e) { 1030 if (LOG.isDebugEnabled()) { 1031 LOG.debug(e.getMessage(), e); 1032 } 1033 } 1034 return result; 1035 } 1036}