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.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 this(cms, type, startLevel, endLevel, resource, param, null); 164 } 165 166 /** 167 * Base constructor.<p> 168 * 169 * @param cms the current users OpenCms context to build the navigation for 170 * @param type the navigation type to generate 171 * @param startLevel the optional start level 172 * @param endLevel the optional end level 173 * @param resource the optional resource for the navigation 174 * @param param the optional parameter for the navigation 175 * @param locale the locale, for which Properties should be read. 176 */ 177 public CmsJspNavigationBean( 178 CmsObject cms, 179 CmsJspTagNavigation.Type type, 180 int startLevel, 181 int endLevel, 182 String resource, 183 String param, 184 Locale locale) { 185 186 m_cms = cms; 187 m_builder = new CmsJspNavBuilder(m_cms, locale); 188 m_type = type; 189 m_startLevel = startLevel; 190 m_endLevel = endLevel; 191 m_resource = resource; 192 m_param = param; 193 } 194 195 /** 196 * Returns the navigation element of the currently requested uri.<p> 197 * 198 * @return the navigation element of the currently requested uri 199 */ 200 public CmsJspNavElement getCurrent() { 201 202 if (m_current == null) { 203 m_current = m_builder.getNavigationForResource(); 204 } 205 return m_current; 206 } 207 208 /** 209 * Returns a lazy initialized Map that provides Booleans that 210 * indicate if a given navigation uri is currently active.<p> 211 * 212 * The provided Map key is assumed to be a String that represents an absolute VFS path.<p> 213 * 214 * Usage example on a JSP with the JSTL:<pre> 215 * <cms:navigation type="treeForFolder" startLevel="1" endLevel="3" var="nav" /> 216 * <c:forEach var="entry" items="${nav.items}" ... > 217 * ... 218 * <c:if test="${nav.isActive[entry.resourceName]}" > 219 * This is the currently active navigation entry 220 * </c:if> 221 * </c:forEach></pre> 222 * 223 * @return a lazy initialized Map that provides Booleans that 224 * indicate if a given navigation uri is currently active 225 */ 226 public Map<String, Boolean> getIsActive() { 227 228 if (m_isActive == null) { 229 m_isActive = CmsCollectionsGenericWrapper.createLazyMap(new CmsIsActiveTransformer()); 230 } 231 return m_isActive; 232 } 233 234 /** 235 * Returns a lazy initialized Map that provides Booleans that 236 * indicate if the given navigation URI is a parent element of the current URI.<p> 237 * 238 * The provided Map key is assumed to be a String that represents an absolute VFS path.<p> 239 * 240 * Usage example on a JSP with the JSTL:<pre> 241 * <cms:navigation type="treeForFolder" startLevel="1" endLevel="3" var="nav" /> 242 * <c:forEach var="entry" items="${nav.items}" ... > 243 * ... 244 * <c:if test="${nav.isParent[entry.resourceName]}" > 245 * The currently active navigation entry is a parent of the currently requested URI 246 * </c:if> 247 * </c:forEach></pre> 248 * 249 * @return a lazy initialized Map that provides Booleans that 250 * indicate if the given navigation URI is a parent element of the current URI 251 */ 252 public Map<String, Boolean> getIsParent() { 253 254 if (m_isParent == null) { 255 m_isParent = CmsCollectionsGenericWrapper.createLazyMap(new CmsIsParentTransformer()); 256 } 257 return m_isParent; 258 } 259 260 /** 261 * Returns the list of selected navigation elements.<p> 262 * 263 * @return the list of selected navigation elements 264 */ 265 public List<CmsJspNavElement> getItems() { 266 267 if (m_items == null) { 268 switch (m_type) { 269 // calculate the results based on the given parameters 270 case forFolder: 271 if (m_startLevel == Integer.MIN_VALUE) { 272 // no start level set 273 if (m_resource == null) { 274 m_items = m_builder.getNavigationForFolder(); 275 } else { 276 m_items = m_builder.getNavigationForFolder(m_resource); 277 } 278 } else { 279 // start level is set 280 if (m_resource == null) { 281 m_items = m_builder.getNavigationForFolder(m_startLevel); 282 } else { 283 m_items = m_builder.getNavigationForFolder(m_resource, m_startLevel); 284 } 285 } 286 break; 287 case forSite: 288 if (m_resource == null) { 289 m_items = m_builder.getSiteNavigation(); 290 } else { 291 m_items = m_builder.getSiteNavigation(m_resource, m_endLevel); 292 } 293 break; 294 case breadCrumb: 295 if (m_resource != null) { 296 // resource is set 297 m_items = m_builder.getNavigationBreadCrumb( 298 m_resource, 299 m_startLevel, 300 m_endLevel, 301 Boolean.valueOf(m_param).booleanValue()); 302 } else { 303 if (m_startLevel == Integer.MIN_VALUE) { 304 // default start level is zero 305 m_items = m_builder.getNavigationBreadCrumb(0, Boolean.valueOf(m_param).booleanValue()); 306 } else { 307 if (m_endLevel != Integer.MIN_VALUE) { 308 m_items = m_builder.getNavigationBreadCrumb(m_startLevel, m_endLevel); 309 } else { 310 m_items = m_builder.getNavigationBreadCrumb( 311 m_startLevel, 312 Boolean.valueOf(m_param).booleanValue()); 313 } 314 } 315 } 316 break; 317 case treeForFolder: 318 if (m_resource == null) { 319 m_items = m_builder.getNavigationTreeForFolder(m_startLevel, m_endLevel); 320 } else { 321 m_items = m_builder.getNavigationTreeForFolder(m_resource, m_startLevel, m_endLevel); 322 } 323 break; 324 case forResource: 325 default: 326 List<CmsJspNavElement> items = new ArrayList<CmsJspNavElement>(1); 327 if (m_resource == null) { 328 items.add(m_builder.getNavigationForResource()); 329 } else { 330 items.add(m_builder.getNavigationForResource(m_resource)); 331 } 332 m_items = items; 333 break; 334 } 335 } 336 return m_items; 337 } 338}