001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (https://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: https://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: https://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.file.CmsObject; 031import org.opencms.file.CmsResource; 032import org.opencms.jsp.CmsJspNavBuilder; 033import org.opencms.jsp.CmsJspNavElement; 034import org.opencms.jsp.CmsJspTagNavigation; 035import org.opencms.main.CmsException; 036import org.opencms.util.CmsCollectionsGenericWrapper; 037 038import java.util.ArrayList; 039import java.util.List; 040import java.util.Locale; 041import java.util.Map; 042 043import org.apache.commons.collections.Transformer; 044 045/** 046 * Allows access to the OpenCms navigation information in combination with the 047 * <code><cms:navigation></code> tag.<p> 048 * 049 * @since 8.0 050 * 051 * @see org.opencms.jsp.CmsJspTagContentAccess 052 */ 053public class CmsJspNavigationBean { 054 055 /** 056 * Provides a Map with Booleans that 057 * indicate if the given URI is the currently active element in the navigation.<p> 058 */ 059 public class CmsIsActiveTransformer implements Transformer { 060 061 /** 062 * @see org.apache.commons.collections.Transformer#transform(java.lang.Object) 063 */ 064 public Object transform(Object input) { 065 066 String resourceName = (String)input; 067 Boolean result = Boolean.FALSE; 068 if (CmsResource.isFolder(resourceName)) { 069 try { 070 CmsResource defaultFile = m_cms.readDefaultFile(resourceName); 071 if ((defaultFile != null) 072 && m_cms.getRequestContext().getSitePath(defaultFile).equals( 073 m_cms.getRequestContext().getUri())) { 074 result = Boolean.TRUE; 075 } 076 } catch (@SuppressWarnings("unused") CmsException e) { 077 // error reading resource, result is false 078 } 079 } else { 080 result = Boolean.valueOf(m_cms.getRequestContext().getUri().equals(resourceName)); 081 } 082 083 return result; 084 } 085 } 086 087 /** 088 * Provides a Map with Booleans that 089 * indicate if the given navigation URI is a parent element of the current URI.<p> 090 */ 091 public class CmsIsParentTransformer implements Transformer { 092 093 /** 094 * @see org.apache.commons.collections.Transformer#transform(java.lang.Object) 095 */ 096 public Object transform(Object input) { 097 098 String resourceName = null; 099 if (input instanceof CmsJspNavElement) { 100 CmsJspNavElement navElement = (CmsJspNavElement)input; 101 if (navElement.getResource() != null) { 102 resourceName = m_cms.getSitePath(navElement.getResource()); 103 } else { 104 resourceName = navElement.getResourceName(); 105 } 106 } else { 107 resourceName = String.valueOf(input); 108 } 109 return Boolean.valueOf(m_cms.getRequestContext().getUri().startsWith(resourceName)); 110 } 111 } 112 113 /** The navigation builder. */ 114 protected CmsJspNavBuilder m_builder; 115 116 /** The OpenCms user context. */ 117 protected CmsObject m_cms; 118 119 /** The navigation element of the currently requested uri. */ 120 protected CmsJspNavElement m_current; 121 122 /** The optional end level for the navigation. */ 123 protected int m_endLevel; 124 125 /** Indicates if a given navigation uri is currently active. */ 126 protected Map<String, Boolean> m_isActive; 127 128 /** Indicates if the given navigation URI is a parent element of the current URI. */ 129 protected Map<String, Boolean> m_isParent; 130 131 /** The result items from the navigation. */ 132 protected List<CmsJspNavElement> m_items; 133 134 /** The optional parameter for the navigation. */ 135 protected String m_param; 136 137 /** The optional resource for the navigation. */ 138 protected String m_resource; 139 140 /** The optional start level for the navigation. */ 141 protected int m_startLevel; 142 143 /** The selected navigation type. */ 144 protected CmsJspTagNavigation.Type m_type; 145 146 /** 147 * Base constructor.<p> 148 * 149 * @param cms the current users OpenCms context to build the navigation for 150 * @param type the navigation type to generate 151 * @param startLevel the optional start level 152 * @param endLevel the optional end level 153 * @param resource the optional resource for the navigation 154 * @param param the optional parameter for the navigation 155 */ 156 public CmsJspNavigationBean( 157 CmsObject cms, 158 CmsJspTagNavigation.Type type, 159 int startLevel, 160 int endLevel, 161 String resource, 162 String param) { 163 164 this(cms, type, startLevel, endLevel, resource, param, null); 165 } 166 167 /** 168 * Base constructor.<p> 169 * 170 * @param cms the current users OpenCms context to build the navigation for 171 * @param type the navigation type to generate 172 * @param startLevel the optional start level 173 * @param endLevel the optional end level 174 * @param resource the optional resource for the navigation 175 * @param param the optional parameter for the navigation 176 * @param locale the locale, for which Properties should be read. 177 */ 178 public CmsJspNavigationBean( 179 CmsObject cms, 180 CmsJspTagNavigation.Type type, 181 int startLevel, 182 int endLevel, 183 String resource, 184 String param, 185 Locale locale) { 186 187 m_cms = cms; 188 m_builder = new CmsJspNavBuilder(m_cms, locale); 189 m_type = type; 190 m_startLevel = startLevel; 191 m_endLevel = endLevel; 192 m_resource = resource; 193 m_param = param; 194 } 195 196 /** 197 * Returns the navigation element of the currently requested uri.<p> 198 * 199 * @return the navigation element of the currently requested uri 200 */ 201 public CmsJspNavElement getCurrent() { 202 203 if (m_current == null) { 204 m_current = m_builder.getNavigationForResource(); 205 } 206 return m_current; 207 } 208 209 /** 210 * Returns a lazy initialized Map that provides Booleans that 211 * indicate if a given navigation uri is currently active.<p> 212 * 213 * The provided Map key is assumed to be a String that represents an absolute VFS path.<p> 214 * 215 * Usage example on a JSP with the JSTL:<pre> 216 * <cms:navigation type="treeForFolder" startLevel="1" endLevel="3" var="nav" /> 217 * <c:forEach var="entry" items="${nav.items}" ... > 218 * ... 219 * <c:if test="${nav.isActive[entry.resourceName]}" > 220 * This is the currently active navigation entry 221 * </c:if> 222 * </c:forEach></pre> 223 * 224 * @return a lazy initialized Map that provides Booleans that 225 * indicate if a given navigation uri is currently active 226 */ 227 public Map<String, Boolean> getIsActive() { 228 229 if (m_isActive == null) { 230 m_isActive = CmsCollectionsGenericWrapper.createLazyMap(new CmsIsActiveTransformer()); 231 } 232 return m_isActive; 233 } 234 235 /** 236 * Returns a lazy initialized Map that provides Booleans that 237 * indicate if the given navigation URI is a parent element of the current URI.<p> 238 * 239 * The provided Map key is assumed to be a String that represents an absolute VFS path.<p> 240 * 241 * Usage example on a JSP with the JSTL:<pre> 242 * <cms:navigation type="treeForFolder" startLevel="1" endLevel="3" var="nav" /> 243 * <c:forEach var="entry" items="${nav.items}" ... > 244 * ... 245 * <c:if test="${nav.isParent[entry.resourceName]}" > 246 * The currently active navigation entry is a parent of the currently requested URI 247 * </c:if> 248 * </c:forEach></pre> 249 * 250 * @return a lazy initialized Map that provides Booleans that 251 * indicate if the given navigation URI is a parent element of the current URI 252 */ 253 public Map<String, Boolean> getIsParent() { 254 255 if (m_isParent == null) { 256 m_isParent = CmsCollectionsGenericWrapper.createLazyMap(new CmsIsParentTransformer()); 257 } 258 return m_isParent; 259 } 260 261 /** 262 * Returns the list of selected navigation elements.<p> 263 * 264 * @return the list of selected navigation elements 265 */ 266 public List<CmsJspNavElement> getItems() { 267 268 if (m_items == null) { 269 switch (m_type) { 270 // calculate the results based on the given parameters 271 case forFolder: 272 if (m_startLevel == Integer.MIN_VALUE) { 273 // no start level set 274 if (m_resource == null) { 275 m_items = m_builder.getNavigationForFolder(); 276 } else { 277 m_items = m_builder.getNavigationForFolder(m_resource); 278 } 279 } else { 280 // start level is set 281 if (m_resource == null) { 282 m_items = m_builder.getNavigationForFolder(m_startLevel); 283 } else { 284 m_items = m_builder.getNavigationForFolder(m_resource, m_startLevel); 285 } 286 } 287 break; 288 case forSite: 289 if (m_resource == null) { 290 m_items = m_builder.getSiteNavigation(); 291 } else { 292 m_items = m_builder.getSiteNavigation(m_resource, m_endLevel); 293 } 294 break; 295 case breadCrumb: 296 if (m_resource != null) { 297 // resource is set 298 m_items = m_builder.getNavigationBreadCrumb( 299 m_resource, 300 m_startLevel, 301 m_endLevel, 302 Boolean.valueOf(m_param).booleanValue()); 303 } else { 304 if (m_startLevel == Integer.MIN_VALUE) { 305 // default start level is zero 306 m_items = m_builder.getNavigationBreadCrumb(0, Boolean.valueOf(m_param).booleanValue()); 307 } else { 308 if (m_endLevel != Integer.MIN_VALUE) { 309 m_items = m_builder.getNavigationBreadCrumb(m_startLevel, m_endLevel); 310 } else { 311 m_items = m_builder.getNavigationBreadCrumb( 312 m_startLevel, 313 Boolean.valueOf(m_param).booleanValue()); 314 } 315 } 316 } 317 break; 318 case treeForFolder: 319 if (m_resource == null) { 320 m_items = m_builder.getNavigationTreeForFolder(m_startLevel, m_endLevel); 321 } else { 322 m_items = m_builder.getNavigationTreeForFolder(m_resource, m_startLevel, m_endLevel); 323 } 324 break; 325 case forResource: 326 default: 327 List<CmsJspNavElement> items = new ArrayList<CmsJspNavElement>(1); 328 if (m_resource == null) { 329 items.add(m_builder.getNavigationForResource()); 330 } else { 331 items.add(m_builder.getNavigationForResource(m_resource)); 332 } 333 m_items = items; 334 break; 335 } 336 } 337 return m_items; 338 } 339}