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.file.CmsObject; 032import org.opencms.file.CmsProject; 033import org.opencms.file.CmsRequestContext; 034import org.opencms.file.CmsResource; 035import org.opencms.file.CmsResourceFilter; 036import org.opencms.file.CmsUser; 037import org.opencms.file.types.CmsResourceTypeXmlContent; 038import org.opencms.file.types.CmsResourceTypeXmlPage; 039import org.opencms.i18n.CmsLocaleGroup; 040import org.opencms.jsp.CmsJspResourceWrapper; 041import org.opencms.jsp.util.CmsJspValueTransformers.CmsLocalePropertyLoaderTransformer; 042import org.opencms.jsp.util.CmsJspValueTransformers.CmsPropertyLoaderTransformer; 043import org.opencms.main.CmsException; 044import org.opencms.main.CmsLog; 045import org.opencms.main.OpenCms; 046import org.opencms.security.CmsPermissionSet; 047import org.opencms.security.CmsPermissionViolationException; 048import org.opencms.util.CmsCollectionsGenericWrapper; 049import org.opencms.util.CmsStringUtil; 050 051import java.util.Collections; 052import java.util.HashMap; 053import java.util.List; 054import java.util.Locale; 055import java.util.Map; 056 057import org.apache.commons.collections.Transformer; 058import org.apache.commons.logging.Log; 059 060/** 061 * Provides utility methods that allow convenient access to the OpenCms VFS, 062 * indented to be used from a JSP with the JSTL or EL.<p> 063 * 064 * @since 7.0.2 065 * 066 * @see CmsJspContentAccessBean 067 */ 068public final class CmsJspVfsAccessBean { 069 070 /** 071 * Transformer that loads a resource from the OpenCms VFS, 072 * the input is used as String for the resource name to read.<p> 073 */ 074 public class CmsAvailableLocaleLoaderTransformer implements Transformer { 075 076 /** 077 * @see org.apache.commons.collections.Transformer#transform(java.lang.Object) 078 */ 079 public Object transform(Object input) { 080 081 List<Locale> result; 082 // read the available locales 083 result = OpenCms.getLocaleManager().getAvailableLocales(getCmsObject(), String.valueOf(input)); 084 return result; 085 } 086 } 087 088 /** 089 * Provides Booleans that indicate if a specified resource exists in the OpenCms VFS, 090 * the input is used as String for the resource name to read.<p> 091 */ 092 public class CmsExistsResourceTransformer implements Transformer { 093 094 /** 095 * @see org.apache.commons.collections.Transformer#transform(java.lang.Object) 096 */ 097 public Object transform(Object input) { 098 099 return Boolean.valueOf(getReadResource().get(input) != null); 100 } 101 } 102 103 /** 104 * Provides Booleans that indicate if a specified resource exists in the OpenCms VFS 105 * and is of type XML content or XML page, 106 * the input is used as String for the resource name to read.<p> 107 */ 108 public class CmsExistsXmlTransformer implements Transformer { 109 110 /** 111 * @see org.apache.commons.collections.Transformer#transform(java.lang.Object) 112 */ 113 public Object transform(Object input) { 114 115 // first read the resource using the lazy map 116 CmsJspResourceWrapper resource = getReadResource().get(input); 117 return Boolean.valueOf( 118 (resource != null) 119 && (CmsResourceTypeXmlPage.isXmlPage(resource) 120 || CmsResourceTypeXmlContent.isXmlContent(resource))); 121 } 122 } 123 124 /** 125 * Transformer that loads a resource permission from the OpenCms VFS, 126 * the input is used as String for the resource name to read the permissions for.<p> 127 */ 128 public class CmsPermissionsLoaderTransformer implements Transformer { 129 130 /** 131 * @see org.apache.commons.collections.Transformer#transform(java.lang.Object) 132 */ 133 public Object transform(Object input) { 134 135 CmsPermissionSet result; 136 try { 137 // read the requested resource permissions 138 result = getCmsObject().getPermissions((String)input); 139 } catch (CmsException e) { 140 // unable to read resource, return null 141 result = null; 142 } 143 return result; 144 } 145 } 146 147 /** 148 * Transformer that a properties of a resource from the OpenCms VFS, 149 * the input is used as String for the property name to read.<p> 150 */ 151 public class CmsPropertyLoaderSingleTransformer implements Transformer { 152 153 /** The resource where the properties are read from. */ 154 private CmsResource m_resource; 155 156 /** Indicates if properties should be searched when loaded. */ 157 private boolean m_search; 158 159 /** 160 * Creates a new property loading Transformer.<p> 161 * 162 * @param resource the resource where the properties are read from 163 * @param search indicates if properties should be searched when loaded 164 */ 165 public CmsPropertyLoaderSingleTransformer(CmsResource resource, boolean search) { 166 167 m_resource = resource; 168 m_search = search; 169 } 170 171 /** 172 * @see org.apache.commons.collections.Transformer#transform(java.lang.Object) 173 */ 174 public Object transform(Object input) { 175 176 String result; 177 try { 178 // read the properties of the requested resource 179 result = getCmsObject().readPropertyObject(m_resource, String.valueOf(input), m_search).getValue(); 180 } catch (CmsException e) { 181 // in case of any error we assume the property does not exist 182 result = null; 183 } 184 return result; 185 } 186 } 187 188 /** 189 * Transformer that loads a resource from the OpenCms VFS, 190 * the input is used as String for the resource name to read.<p> 191 */ 192 public class CmsResourceLoaderTransformer implements Transformer { 193 194 /** 195 * @see org.apache.commons.collections.Transformer#transform(java.lang.Object) 196 */ 197 public Object transform(Object input) { 198 199 CmsJspResourceWrapper result; 200 try { 201 // read the requested resource 202 result = CmsJspElFunctions.convertResource(getCmsObject(), input); 203 } catch (CmsException e) { 204 // unable to read resource, return null 205 result = null; 206 } 207 return result; 208 } 209 } 210 211 /** 212 * Transformer that loads properties of a resource from the OpenCms VFS with another lazy map, 213 * the input is used as String for the resource name to read.<p> 214 */ 215 public class CmsResourceLocalePropertyLoaderTransformer implements Transformer { 216 217 /** Indicates if properties should be searched when loaded. */ 218 private boolean m_search; 219 220 /** 221 * Creates a new property loading Transformer.<p> 222 * 223 * @param search indicates if properties should be searched when loaded 224 */ 225 public CmsResourceLocalePropertyLoaderTransformer(boolean search) { 226 227 m_search = search; 228 } 229 230 /** 231 * @see org.apache.commons.collections.Transformer#transform(java.lang.Object) 232 */ 233 public Object transform(Object input) { 234 235 Map<String, String> result = null; 236 // first read the resource using the lazy map 237 CmsJspResourceWrapper resource = getReadResource().get(input); 238 if (resource != null) { 239 result = CmsCollectionsGenericWrapper.createLazyMap( 240 new CmsLocalePropertyLoaderTransformer(getCmsObject(), resource, m_search)); 241 } 242 // result may still be null 243 return (result == null) ? Collections.EMPTY_MAP : result; 244 } 245 } 246 247 /** 248 * Transformer that loads properties of a resource from the OpenCms VFS with another lazy map, 249 * the input is used as String for the resource name to read.<p> 250 */ 251 public class CmsResourcePropertyLoaderTransformer implements Transformer { 252 253 /** Indicates if properties should be searched when loaded. */ 254 private boolean m_search; 255 256 /** 257 * Creates a new property loading Transformer.<p> 258 * 259 * @param search indicates if properties should be searched when loaded 260 */ 261 public CmsResourcePropertyLoaderTransformer(boolean search) { 262 263 m_search = search; 264 } 265 266 /** 267 * @see org.apache.commons.collections.Transformer#transform(java.lang.Object) 268 */ 269 public Object transform(Object input) { 270 271 Map<String, String> result = null; 272 // first read the resource using the lazy map 273 CmsJspResourceWrapper resource = getReadResource().get(input); 274 if (resource != null) { 275 result = CmsCollectionsGenericWrapper.createLazyMap( 276 new CmsPropertyLoaderTransformer(getCmsObject(), resource, m_search)); 277 } 278 // result may still be null 279 return (result == null) ? Collections.EMPTY_MAP : result; 280 } 281 } 282 283 /** 284 * Transformer that calculates links to resources in the OpenCms VFS, 285 * the input is used as String for the resource name to use as link target.<p> 286 * 287 * This is using the same logic as 288 * {@link org.opencms.jsp.CmsJspTagLink#linkTagAction(String, javax.servlet.ServletRequest)}.<p> 289 */ 290 public class CmsVfsLinkTransformer implements Transformer { 291 292 /** 293 * @see org.apache.commons.collections.Transformer#transform(java.lang.Object) 294 */ 295 public Object transform(Object input) { 296 297 return A_CmsJspValueWrapper.substituteLink(getCmsObject(), String.valueOf(input)); 298 } 299 } 300 301 /** 302 * Provides XML content access beans for VFS resources.<p> 303 */ 304 public class CmsXmlContentAccessTransformer implements Transformer { 305 306 /** 307 * @see org.apache.commons.collections.Transformer#transform(java.lang.Object) 308 */ 309 public Object transform(Object input) { 310 311 CmsJspContentAccessBean result = null; 312 // first read the resource using the lazy map 313 CmsJspResourceWrapper resource = getReadResource().get(input); 314 if ((resource != null) 315 && (CmsResourceTypeXmlPage.isXmlPage(resource) || CmsResourceTypeXmlContent.isXmlContent(resource))) { 316 // make sure we have a resource that really is an XML content 317 result = new CmsJspContentAccessBean(getCmsObject(), resource); 318 } 319 return result; 320 } 321 } 322 323 /** Request context attribute for indicating the model file for a create resource operation. */ 324 public static final String ATTRIBUTE_VFS_ACCESS_BEAN = CmsJspVfsAccessBean.class.getName() + ".VFS_ACCESS_BEAN"; 325 326 /** Logger instance for this class. */ 327 private static final Log LOG = CmsLog.getLog(CmsJspVfsAccessBean.class); 328 329 /** The OpenCms context of the current user. */ 330 protected CmsObject m_cms; 331 332 /** Contains booleans that indicate if a resource exists in the VFS. */ 333 private Map<String, Boolean> m_existsResource; 334 335 /** Contains booleans that indicate if a resource exists and is an XML content. */ 336 private Map<String, Boolean> m_existsXml; 337 338 /** Links calculated for the OpenCms VFS. */ 339 private Map<String, String> m_links; 340 341 /** Resource permissions loaded from the OpenCms VFS. */ 342 private Map<String, CmsPermissionSet> m_permissions; 343 344 /** Properties loaded from the OpenCms VFS. */ 345 private Map<String, Map<String, String>> m_properties; 346 347 /** Properties loaded locale specific from the OpenCms VFS. */ 348 private Map<String, Map<String, Map<String, String>>> m_propertiesLocale; 349 350 /** Properties loaded from the OpenCms VFS with search. */ 351 private Map<String, Map<String, String>> m_propertiesSearch; 352 353 /** Properties loaded locale specific from the OpenCms VFS with search. */ 354 private Map<String, Map<String, Map<String, String>>> m_propertiesSearchLocale; 355 356 /** Available locales as determined by the {@link org.opencms.i18n.CmsLocaleManager}. */ 357 private Map<String, List<Locale>> m_availableLocales; 358 359 /** Resources loaded from the OpenCms VFS. */ 360 private Map<String, CmsJspResourceWrapper> m_resources; 361 362 /** XML contents read from the VFS. */ 363 private Map<String, CmsJspContentAccessBean> m_xmlContent; 364 365 /** 366 * Creates a new context bean using the OpenCms context of the current user.<p> 367 * 368 * @param cms the OpenCms context of the current user 369 */ 370 private CmsJspVfsAccessBean(CmsObject cms) { 371 372 m_cms = cms; 373 } 374 375 /** 376 * Creates a new instance of the JSP VFS access utility bean.<p> 377 * 378 * To prevent multiple creations of the bean during a request, the OpenCms request context 379 * attributes are used to cache the created VFS access utility bean.<p> 380 * 381 * @param cms the current OpenCms user context 382 * 383 * @return a new instance of the JSP VFS access utility bean 384 */ 385 public static CmsJspVfsAccessBean create(CmsObject cms) { 386 387 CmsJspVfsAccessBean result; 388 Object attribute = cms.getRequestContext().getAttribute(ATTRIBUTE_VFS_ACCESS_BEAN); 389 if (attribute != null) { 390 result = (CmsJspVfsAccessBean)attribute; 391 } else { 392 result = new CmsJspVfsAccessBean(cms); 393 cms.getRequestContext().setAttribute(ATTRIBUTE_VFS_ACCESS_BEAN, result); 394 } 395 return result; 396 } 397 398 /** 399 * Returns a lazily generated map from site paths of resources to the available locales for the resource. 400 * 401 * @return a lazily generated map from site paths of resources to the available locales for the resource. 402 */ 403 public Map<String, List<Locale>> getAvailableLocales() { 404 405 if (m_availableLocales == null) { 406 // create lazy map only on demand 407 m_availableLocales = CmsCollectionsGenericWrapper.createLazyMap(new CmsAvailableLocaleLoaderTransformer()); 408 } 409 return m_availableLocales; 410 } 411 412 /** 413 * Returns the OpenCms user context this bean was initialized with.<p> 414 * 415 * @return the OpenCms user context this bean was initialized with 416 */ 417 public CmsObject getCmsObject() { 418 419 return m_cms; 420 } 421 422 /** 423 * Short form for {@link #getRequestContext()}.<p> 424 * 425 * Usage example on a JSP with the EL:<pre> 426 * The current URI is: ${cms:vfs(pageContext).context.uri} 427 * </pre> 428 * 429 * @return the OpenCms request context of the current user this bean was initialized with 430 * 431 * @see #getRequestContext() 432 */ 433 public CmsRequestContext getContext() { 434 435 return getRequestContext(); 436 } 437 438 /** 439 * Returns the current project from the context.<p> 440 * 441 * Usage example on a JSP with the EL:<pre> 442 * The current project name is: ${cms:vfs(pageContext).currentProject.name} 443 * </pre> 444 * 445 * @return the current project 446 */ 447 public CmsProject getCurrentProject() { 448 449 return m_cms.getRequestContext().getCurrentProject(); 450 } 451 452 /** 453 * Returns the current user from the context.<p> 454 * 455 * Usage example on a JSP with the EL:<pre> 456 * The current user name is: ${cms:vfs(pageContext).currentUser.name} 457 * </pre> 458 * 459 * @return the current user 460 */ 461 public CmsUser getCurrentUser() { 462 463 return m_cms.getRequestContext().getCurrentUser(); 464 } 465 466 /** 467 * Short form for {@link #getExistsResource()}.<p> 468 * 469 * Usage example on a JSP with the EL / JSTL:<pre> 470 * <c:if test="${cms:vfs(pageContext).exists['/checkme.html']}" > 471 * The resource "/checkme.html" exists. 472 * </c:if> 473 * </pre> 474 * 475 * @return a map that lazily reads resources from the OpenCms VFS 476 * 477 * @see #getExistsResource() 478 */ 479 public Map<String, Boolean> getExists() { 480 481 return getExistsResource(); 482 } 483 484 /** 485 * Returns a map that lazily checks if a resources exists in the OpenCms VFS.<p> 486 * 487 * Usage example on a JSP with the EL / JSTL:<pre> 488 * <c:if test="${cms:vfs(pageContext).existsResource['/checkme.html']}" > 489 * The resource "/checkme.html" exists. 490 * </c:if> 491 * </pre> 492 * 493 * Usage example on a JSP with the <code><cms:contentaccess></code> tag:<pre> 494 * <cms:contentload ... > 495 * <cms:contentaccess var="content" /> 496 * <c:if test="${content.vfs.existsResource['/checkme.html']}" > 497 * The resource "/checkme.html" exists. 498 * </c:if> 499 * </cms:contentload></pre> 500 * 501 * @return a map that lazily checks if a resources exists in the OpenCms VFS 502 * 503 * @see #getExists() for a short form of this method 504 */ 505 public Map<String, Boolean> getExistsResource() { 506 507 if (m_existsResource == null) { 508 // create lazy map only on demand 509 m_existsResource = CmsCollectionsGenericWrapper.createLazyMap(new CmsExistsResourceTransformer()); 510 } 511 return m_existsResource; 512 } 513 514 /** 515 * Returns a map that lazily checks if a resources exists in the VFS and is of type XML content or XML page.<p> 516 * 517 * Usage example on a JSP with the EL / JSTL:<pre> 518 * <c:if test="${cms:vfs(pageContext).existsXml['/text.xml']}" > 519 * The resource "/text.xml" exists and is an XML document. 520 * </c:if> 521 * </pre> 522 * 523 * @return a map that lazily checks if a resources exists in the VFS and is of type XML content or XML page 524 */ 525 public Map<String, Boolean> getExistsXml() { 526 527 if (m_existsXml == null) { 528 // create lazy map only on demand 529 m_existsXml = CmsCollectionsGenericWrapper.createLazyMap(new CmsExistsXmlTransformer()); 530 } 531 return m_existsXml; 532 } 533 534 /** 535 * Flushes the internal caches of this VFS access bean.<p> 536 * 537 * The VFS access bean uses lazy initialized Maps for all access, but once a value has been 538 * read it is cached in the Map and not read again from the VFS. This means the lazy Maps 539 * act as another layer of cache to the VFS.<p> 540 * 541 * The VFS access bean instance itself is cached in the OpenCms request context attributes of the {@link CmsObject}, 542 * see {@link #create(CmsObject)}. Normally there is a new {@link CmsObject} created for 543 * all incoming requests, so the live-time of the VFS access bean is short. 544 * In that case the caching of the lazy Maps should improve performance and not be an issue. 545 * However, in rare cases an instance of a {@link CmsObject} may be kept for a long time in 546 * some custom code. In theses cases flushing the caches of the lazy Maps manually may be required, otherwise 547 * the Map caches may be out of sync with the VFS. 548 * 549 * @return always returns <code>true</code> 550 */ 551 public boolean getFlushCaches() { 552 553 m_resources = null; 554 m_properties = null; 555 m_propertiesSearch = null; 556 557 return true; 558 } 559 560 /** 561 * Returns a map that lazily calculates links to files in the OpenCms VFS, 562 * which have been adjusted according to the web application path and the 563 * OpenCms static export rules.<p> 564 * 565 * Please note that the target is always assumed to be in the OpenCms VFS, so you can't use 566 * this method for links external to OpenCms.<p> 567 * 568 * Relative links are converted to absolute links, using the current element URI as base.<p> 569 * 570 * Relative links are converted to absolute links, using the current OpenCms request context URI as base.<p> 571 * 572 * Usage example on a JSP with the EL:<pre> 573 * Link to the "/index.html" file: ${cms:vfs(pageContext).link['/index.html']} 574 * </pre> 575 * 576 * Usage example on a JSP with the <code><cms:contentaccess></code> tag:<pre> 577 * <cms:contentload ... > 578 * <cms:contentaccess var="content" /> 579 * Link to the "/index.html" file: ${content.vfs.link['/index.html']} 580 * </cms:contentload></pre> 581 * 582 * @return a map that lazily calculates links to resources in the OpenCms VFS 583 * 584 * @see org.opencms.jsp.CmsJspActionElement#link(String) 585 * @see org.opencms.jsp.CmsJspTagLink#linkTagAction(String, javax.servlet.ServletRequest) 586 */ 587 public Map<String, String> getLink() { 588 589 if (m_links == null) { 590 // create lazy map only on demand 591 m_links = CmsCollectionsGenericWrapper.createLazyMap(new CmsVfsLinkTransformer()); 592 } 593 return m_links; 594 } 595 596 /** 597 * Gets a lazy loading map used to access locale variants of a resource with a given path.<p> 598 * 599 * Usage in JSP: ${myvfsaccessbeaninstance.localeResource['/foo/bar/index.html']['de']} 600 * 601 * @return the lazy loading map 602 */ 603 public Map<String, Map<String, CmsJspResourceWrapper>> getLocaleResource() { 604 605 return CmsCollectionsGenericWrapper.createLazyMap(new Transformer() { 606 607 @SuppressWarnings("synthetic-access") 608 public Object transform(Object arg) { 609 610 if (!(arg instanceof String)) { 611 return new HashMap<String, CmsJspResourceWrapper>(); 612 } 613 String path = (String)arg; 614 try { 615 CmsResource res = m_cms.readResource(path); 616 CmsJspResourceWrapper wrapper = CmsJspResourceWrapper.wrap(m_cms, res); 617 return wrapper.getLocaleResource(); 618 } catch (Exception e) { 619 LOG.warn(e.getLocalizedMessage(), e); 620 return new HashMap<String, CmsJspResourceWrapper>(); 621 } 622 } 623 624 }); 625 } 626 627 /** 628 * Returns a lazy loading map used to detect the main locale of a resource which is part of a locale group.<p> 629 * 630 * Usage in JSPs: ${myvfsaccessbeaninstance.mainLocale['/foo/index.html']} 631 * 632 * @return the lazy loading map 633 */ 634 public Map<String, Locale> getMainLocale() { 635 636 return CmsCollectionsGenericWrapper.createLazyMap(new Transformer() { 637 638 @SuppressWarnings("synthetic-access") 639 public Object transform(Object arg) { 640 641 if (!(arg instanceof String)) { 642 return null; 643 } 644 String path = (String)arg; 645 try { 646 CmsResource res = m_cms.readResource(path); 647 CmsLocaleGroup localeGroup = m_cms.getLocaleGroupService().readLocaleGroup(res); 648 return localeGroup.getMainLocale(); 649 } catch (Exception e) { 650 LOG.warn(e.getLocalizedMessage(), e); 651 return null; 652 } 653 } 654 }); 655 } 656 657 /** 658 * Returns the parent folder of a resource.<p> 659 * 660 * This assumes the parameter is either a CmsResource, or a String representing a file name. 661 * If the parameter is a CmsResource, the result will be relative to the current site.</p> 662 * 663 * @return the parent folder of a resource 664 * 665 * @param obj a CmsResource or a String representing a resource name 666 * 667 * @see CmsResource#getParentFolder(String) 668 * @see org.opencms.jsp.CmsJspResourceWrapper#getSitePathParentFolder() 669 */ 670 public String getParentFolder(Object obj) { 671 672 String result; 673 if (obj instanceof CmsResource) { 674 result = CmsResource.getParentFolder(m_cms.getRequestContext().getSitePath((CmsResource)obj)); 675 } else { 676 result = CmsResource.getParentFolder(String.valueOf(obj)); 677 } 678 return result; 679 } 680 681 /** 682 * Returns the directory level of a resource.<p> 683 * 684 * This assumes the parameter is either a CmsResource, or a String representing a file name. 685 * If the parameter is a CmsResource, the result will be relative to the current site.</p> 686 * 687 * The root folder "/" has level 0, 688 * a folder "/foo/" would have level 1, 689 * a folder "/foo/bar/" level 2 etc.<p> 690 * 691 * @param obj a CmsResource or a String representing a resource name 692 * 693 * @return the directory level of a resource 694 * 695 * @see CmsResource#getPathLevel(String) 696 * @see org.opencms.jsp.CmsJspResourceWrapper#getSitePathLevel() 697 */ 698 public int getPathLevel(Object obj) { 699 700 int result; 701 if (obj instanceof CmsResource) { 702 result = CmsResource.getPathLevel(m_cms.getRequestContext().getSitePath((CmsResource)obj)); 703 } else { 704 result = CmsResource.getPathLevel(String.valueOf(obj)); 705 } 706 return result; 707 } 708 709 /** 710 * Short form for {@link #getReadPermissions()}.<p> 711 * 712 * Usage example on a JSP with the EL:<pre> 713 * Permission string of the "/index.html" resource: ${cms:vfs(pageContext).readPermissions['/index.html'].permissionString} 714 * </pre> 715 * 716 * Usage example on a JSP with the <code><cms:contentaccess></code> tag:<pre> 717 * <cms:contentload ... > 718 * <cms:contentaccess var="content" /> 719 * Permission string of the "/index.html" resource: ${content.vfs.readPermissions['/index.html'].permissionString} 720 * </cms:contentload></pre> 721 * 722 * @return a map that lazily reads resource permissions from the OpenCms VFS 723 * 724 * @see #getReadPermissions() 725 */ 726 public Map<String, CmsPermissionSet> getPermissions() { 727 728 return getReadPermissions(); 729 } 730 731 /** 732 * Short form for {@link #getReadProperties()}.<p> 733 * 734 * Usage example on a JSP with the EL:<pre> 735 * Title property of the "/index.html" resource: ${cms:vfs(pageContext).property['/index.html']['Title']} 736 * </pre> 737 * 738 * @return a map that lazily reads all resource properties from the OpenCms VFS, without search 739 * 740 * @see #getReadProperties() 741 */ 742 public Map<String, Map<String, String>> getProperty() { 743 744 return getReadProperties(); 745 } 746 747 /** 748 * Short form for {@link #getReadPropertiesLocale()}.<p> 749 * 750 * Usage example on a JSP with the EL:<pre> 751 * Title property of the "/index.html" resource for locale "de": ${cms:vfs(pageContext).property['/index.html']['de']['Title']} 752 * </pre> 753 * 754 * @return a map that lazily reads all resource properties from the OpenCms VFS, without search 755 * 756 * @see #getReadPropertiesLocale() 757 */ 758 public Map<String, Map<String, Map<String, String>>> getPropertyLocale() { 759 760 return getReadPropertiesLocale(); 761 } 762 763 /** 764 * Short form for {@link #getReadPropertiesSearch()}.<p> 765 * 766 * Usage example on a JSP with the EL:<pre> 767 * Title property of the "/index.html" resource (searched): ${cms:vfs(pageContext).propertySearch['/index.html']['Title']} 768 * </pre> 769 * 770 * @return a map that lazily reads all resource properties from the OpenCms VFS, with search 771 * 772 * @see #getReadPropertiesSearch() 773 */ 774 public Map<String, Map<String, String>> getPropertySearch() { 775 776 return getReadPropertiesSearch(); 777 } 778 779 /** 780 * Short form for {@link #getReadPropertiesSearchLocale()}.<p> 781 * 782 * Usage example on a JSP with the EL:<pre> 783 * Title property of the "/index.html" resource (searched) for locale "de": ${cms:vfs(pageContext).propertySearch['/index.html']['de']['Title']} 784 * </pre> 785 * 786 * @return a map that lazily reads all resource properties from the OpenCms VFS, with search 787 * 788 * @see #getReadPropertiesSearchLocale() 789 */ 790 public Map<String, Map<String, Map<String, String>>> getPropertySearchLocale() { 791 792 return getReadPropertiesSearchLocale(); 793 } 794 795 /** 796 * Returns a map that lazily reads resource permissions from the OpenCms VFS.<p> 797 * 798 * Usage example on a JSP with the EL:<pre> 799 * Permission string of the "/index.html" resource: ${cms:vfs(pageContext).readPermissions['/index.html'].permissionString} 800 * </pre> 801 * 802 * Usage example on a JSP with the <code><cms:contentaccess></code> tag:<pre> 803 * <cms:contentload ... > 804 * <cms:contentaccess var="content" /> 805 * Permission string of the "/index.html" resource: ${content.vfs.readPermissions['/index.html'].permissionString} 806 * </cms:contentload></pre> 807 * 808 * @return a map that lazily reads resource permissions from the OpenCms VFS 809 * 810 * @see #getPermissions() for a short form of this method 811 */ 812 public Map<String, CmsPermissionSet> getReadPermissions() { 813 814 if (m_permissions == null) { 815 // create lazy map only on demand 816 m_permissions = CmsCollectionsGenericWrapper.createLazyMap(new CmsPermissionsLoaderTransformer()); 817 } 818 return m_permissions; 819 } 820 821 /** 822 * Returns a map that lazily reads all resource properties from the OpenCms VFS, without search.<p> 823 * 824 * Usage example on a JSP with the EL:<pre> 825 * Title property of the "/index.html" resource: ${cms:vfs(pageContext).readProperties['/index.html']['Title']} 826 * </pre> 827 * 828 * Usage example on a JSP with the <code><cms:contentaccess></code> tag:<pre> 829 * <cms:contentload ... > 830 * <cms:contentaccess var="content" /> 831 * Title property of the "/index.html" resource: ${content.vfs.readProperties['/index.html']['Title']} 832 * </cms:contentload></pre> 833 * 834 * @return a map that lazily reads all resource properties from the OpenCms VFS, without search 835 * 836 * @see #getProperty() for a short form of this method 837 */ 838 public Map<String, Map<String, String>> getReadProperties() { 839 840 if (m_properties == null) { 841 // create lazy map only on demand 842 m_properties = CmsCollectionsGenericWrapper.createLazyMap(new CmsResourcePropertyLoaderTransformer(false)); 843 } 844 return m_properties; 845 } 846 847 /** 848 * Returns a map that lazily reads all resource properties from the OpenCms VFS, without search.<p> 849 * 850 * Usage example on a JSP with the EL:<pre> 851 * Title property of the "/index.html" resource for locale "de": ${cms:vfs(pageContext).readProperties['/index.html']['de']['Title']} 852 * </pre> 853 * 854 * Usage example on a JSP with the <code><cms:contentaccess></code> tag:<pre> 855 * <cms:contentload ... > 856 * <cms:contentaccess var="content" /> 857 * Title property of the "/index.html" resource: ${content.vfs.readProperties['/index.html']['Title']} 858 * </cms:contentload></pre> 859 * 860 * @return a map that lazily reads all resource properties from the OpenCms VFS, without search 861 * 862 * @see #getProperty() for a short form of this method 863 */ 864 public Map<String, Map<String, Map<String, String>>> getReadPropertiesLocale() { 865 866 if (m_propertiesLocale == null) { 867 // create lazy map only on demand 868 m_propertiesLocale = CmsCollectionsGenericWrapper.createLazyMap( 869 new CmsResourceLocalePropertyLoaderTransformer(false)); 870 } 871 return m_propertiesLocale; 872 } 873 874 /** 875 * Returns a map that lazily reads all resource properties from the OpenCms VFS, with search.<p> 876 * 877 * Usage example on a JSP with the EL:<pre> 878 * Title property of the "/index.html" resource (searched): ${cms:vfs(pageContext).readPropertiesSearch['/index.html']['Title']} 879 * </pre> 880 * 881 * Usage example on a JSP with the <code><cms:contentaccess></code> tag:<pre> 882 * <cms:contentload ... > 883 * <cms:contentaccess var="content" /> 884 * Title property of the "/index.html" resource (searched): ${content.vfs.readPropertiesSearch['/index.html']['Title']} 885 * </cms:contentload></pre> 886 * 887 * @return a map that lazily reads all resource properties from the OpenCms VFS, with search 888 * 889 * @see #getPropertySearch() for a short form of this method 890 */ 891 public Map<String, Map<String, String>> getReadPropertiesSearch() { 892 893 if (m_propertiesSearch == null) { 894 // create lazy map only on demand 895 m_propertiesSearch = CmsCollectionsGenericWrapper.createLazyMap( 896 new CmsResourcePropertyLoaderTransformer(true)); 897 } 898 return m_propertiesSearch; 899 } 900 901 /** 902 * Returns a map that lazily reads all resource properties from the OpenCms VFS, with search and provides locale specific access to them.<p> 903 * 904 * Usage example on a JSP with the EL:<pre> 905 * Title property of the "/index.html" resource (searched): ${cms:vfs(pageContext).readPropertiesSearch['/index.html']['Title']} 906 * </pre> 907 * 908 * Usage example on a JSP with the <code><cms:contentaccess></code> tag:<pre> 909 * <cms:contentload ... > 910 * <cms:contentaccess var="content" /> 911 * Title property of the "/index.html" resource (searched) for locale "de": ${content.vfs.readPropertiesSearchLocale['/index.html']['de']['Title']} 912 * </cms:contentload></pre> 913 * 914 * @return a map that lazily reads all resource properties from the OpenCms VFS, with search 915 * 916 * @see #getPropertySearch() for a short form of this method 917 */ 918 public Map<String, Map<String, Map<String, String>>> getReadPropertiesSearchLocale() { 919 920 if (m_propertiesSearchLocale == null) { 921 // create lazy map only on demand 922 m_propertiesSearchLocale = CmsCollectionsGenericWrapper.createLazyMap( 923 new CmsResourceLocalePropertyLoaderTransformer(true)); 924 } 925 return m_propertiesSearchLocale; 926 } 927 928 /** 929 * Returns a map that lazily reads resources from the OpenCms VFS.<p> 930 * 931 * Usage example on a JSP with the EL:<pre> 932 * Root path of the "/index.html" resource: ${cms:vfs(pageContext).readResource['/index.html'].rootPath} 933 * </pre> 934 * 935 * Usage example on a JSP with the <code><cms:contentaccess></code> tag:<pre> 936 * <cms:contentload ... > 937 * <cms:contentaccess var="content" /> 938 * Root path of the "/index.html" resource: ${content.vfs.readResource['/index.html'].rootPath} 939 * </cms:contentload></pre> 940 * 941 * @return a map that lazily reads resources from the OpenCms VFS 942 * 943 * @see #getResource() for a short form of this method 944 */ 945 public Map<String, CmsJspResourceWrapper> getReadResource() { 946 947 if (m_resources == null) { 948 // create lazy map only on demand 949 m_resources = CmsCollectionsGenericWrapper.createLazyMap(new CmsResourceLoaderTransformer()); 950 } 951 return m_resources; 952 } 953 954 /** 955 * Returns a map that lazily reads XML documents from the OpenCms VFS that are wrapped using a 956 * {@link CmsJspContentAccessBean}.<p> 957 * 958 * Usage example on a JSP with the EL:<pre> 959 * Title of "/text.xml": ${cms:vfs(pageContext).readXml['/text.xml'].value['Title']} 960 * </pre> 961 * 962 * @return a map that lazily reads wrapped XML documents from the OpenCms VFS 963 * 964 * @see #getXml() for a short form of this method 965 */ 966 public Map<String, CmsJspContentAccessBean> getReadXml() { 967 968 if (m_xmlContent == null) { 969 // create lazy map only on demand 970 m_xmlContent = CmsCollectionsGenericWrapper.createLazyMap(new CmsXmlContentAccessTransformer()); 971 } 972 return m_xmlContent; 973 } 974 975 /** 976 * Returns the OpenCms request context the current user this bean was initialized with.<p> 977 * 978 * Usage example on a JSP with the EL:<pre> 979 * The current URI is: ${cms:vfs(pageContext).requestContext.uri} 980 * </pre> 981 * 982 * @return the OpenCms request context the current user this bean was initialized with 983 * 984 * @see #getContext() for a short form of this method 985 */ 986 public CmsRequestContext getRequestContext() { 987 988 return m_cms.getRequestContext(); 989 } 990 991 /** 992 * Short form for {@link #getReadResource()}.<p> 993 * 994 * Usage example on a JSP with the EL:<pre> 995 * Root path of the "/index.html" resource: ${cms:vfs(pageContext).resource['/index.html'].rootPath} 996 * </pre> 997 * 998 * @return a map that lazily reads resources from the OpenCms VFS 999 * 1000 * @see #getReadResource() 1001 */ 1002 public Map<String, CmsJspResourceWrapper> getResource() { 1003 1004 return getReadResource(); 1005 } 1006 1007 /** 1008 * Returns the resource name extension if present.<p> 1009 * 1010 * This assumes the parameter is either a CmsResource, or a String representing a resource name.</p> 1011 * 1012 * The extension will always be lower case.<p> 1013 * 1014 * @param obj a CmsResource or a String representing a resource name 1015 * 1016 * @return the extension or <code>null</code> if not available 1017 * 1018 * @see CmsResource#getExtension(String) 1019 * @see org.opencms.jsp.CmsJspResourceWrapper#getResourceExtension() 1020 */ 1021 public String getResourceExtension(Object obj) { 1022 1023 String result; 1024 if (obj instanceof CmsResource) { 1025 result = CmsResource.getExtension(((CmsResource)obj).getRootPath()); 1026 } else { 1027 result = CmsResource.getExtension(String.valueOf(obj)); 1028 } 1029 return result; 1030 } 1031 1032 /** 1033 * Returns the name of a resource without the path information.<p> 1034 * 1035 * This assumes the parameter is either a CmsResource, or a String representing a resource name.<p> 1036 * 1037 * The resource name of a file is the name of the file. 1038 * The resource name of a folder is the folder name with trailing "/". 1039 * The resource name of the root folder is <code>/</code>.<p> 1040 * 1041 * @param obj a CmsResource or a String representing a resource name 1042 * 1043 * @return the name of a resource without the path information 1044 * 1045 * @see CmsResource#getName() 1046 * @see org.opencms.jsp.CmsJspResourceWrapper#getResourceName() 1047 */ 1048 public String getResourceName(Object obj) { 1049 1050 String result; 1051 if (obj instanceof CmsResource) { 1052 result = ((CmsResource)obj).getName(); 1053 } else { 1054 result = CmsResource.getName(String.valueOf(obj)); 1055 } 1056 return result; 1057 } 1058 1059 /** 1060 * Short form for {@link #getReadXml()}.<p> 1061 * 1062 * Usage example on a JSP with the EL:<pre> 1063 * Title of "/text.xml": ${cms:vfs(pageContext).xml['/text.xml'].value['Title']} 1064 * </pre> 1065 * 1066 * @return a map that lazily reads wrapped XML documents from the OpenCms VFS 1067 * 1068 * @see #getReadXml() 1069 */ 1070 public Map<String, CmsJspContentAccessBean> getXml() { 1071 1072 return getReadXml(); 1073 } 1074 1075 /** 1076 * Returns true if the user has no read permissions for the given path. 1077 * 1078 * @param path the path of a resource 1079 * 1080 * @return true if the user has no read permissions for the path 1081 */ 1082 public boolean hasNoReadPermissions(String path) { 1083 1084 try { 1085 m_cms.readResource(path, CmsResourceFilter.IGNORE_EXPIRATION); 1086 } catch (CmsPermissionViolationException e) { 1087 return true; 1088 } catch (Exception e) { 1089 return false; 1090 } 1091 return false; 1092 } 1093 1094 /** 1095 * Reads the resources in the given folder.<p> 1096 * 1097 * @param resourcePath the site path to the folder 1098 * 1099 * @return the resources 1100 * 1101 * @throws CmsException in case reading the resources fails 1102 */ 1103 public List<CmsJspResourceWrapper> readFilesInFolder(String resourcePath) throws CmsException { 1104 1105 return CmsJspElFunctions.convertResourceList(m_cms, m_cms.getFilesInFolder(resourcePath)); 1106 } 1107 1108 /** 1109 * Reads the resources in the given folder using the provided filter.<p> 1110 * 1111 * @param resourcePath the site path to the folder 1112 * @param filterString a comma separated list of resource type names 1113 * 1114 * @return the resources 1115 * 1116 * @throws CmsException in case reading the resources fails 1117 */ 1118 public List<CmsJspResourceWrapper> readFilesInFolder(String resourcePath, String filterString) throws CmsException { 1119 1120 CmsResourceFilter filter = CmsResourceFilter.DEFAULT; 1121 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(filterString)) { 1122 String[] types = filterString.split(","); 1123 for (String type : types) { 1124 if (OpenCms.getResourceManager().hasResourceType(type)) { 1125 filter.addRequireType(OpenCms.getResourceManager().getResourceType(type)); 1126 } 1127 } 1128 } 1129 return CmsJspElFunctions.convertResourceList(m_cms, m_cms.getFilesInFolder(resourcePath, filter)); 1130 } 1131 1132 /** 1133 * Reads the sub site folder resource.<p> 1134 * 1135 * @param path the current site path 1136 * 1137 * @return the folder resource 1138 * 1139 * @throws CmsException in case reading the resource fails 1140 */ 1141 public CmsJspResourceWrapper readSubsiteFor(String path) throws CmsException { 1142 1143 CmsADEConfigData config = OpenCms.getADEManager().lookupConfiguration( 1144 m_cms, 1145 m_cms.getRequestContext().addSiteRoot(path)); 1146 return CmsJspResourceWrapper.wrap( 1147 m_cms, 1148 m_cms.readResource(m_cms.getRequestContext().removeSiteRoot(config.getBasePath()))); 1149 } 1150}