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 GmbH & Co. KG, 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.CmsObject; 031import org.opencms.flex.CmsFlexController; 032import org.opencms.i18n.CmsLocaleManager; 033import org.opencms.main.CmsException; 034import org.opencms.main.CmsLog; 035import org.opencms.main.OpenCms; 036import org.opencms.staticexport.CmsLinkManager; 037import org.opencms.util.CmsStringUtil; 038 039import java.util.Locale; 040 041import javax.servlet.ServletRequest; 042import javax.servlet.jsp.JspException; 043import javax.servlet.jsp.tagext.BodyTagSupport; 044 045import org.apache.commons.logging.Log; 046 047/** 048 * Implements the <code><cms:link>[filename]</cms:link></code> 049 * tag to add OpenCms managed links to a JSP page, required for link 050 * management and the static 051 * export to work properly.<p> 052 * 053 * @since 6.0.0 054 */ 055public class CmsJspTagLink extends BodyTagSupport { 056 057 /** The log object for this class. */ 058 private static final Log LOG = CmsLog.getLog(CmsJspTagLink.class); 059 060 /** Serial version UID required for safe serialization. */ 061 private static final long serialVersionUID = -2361021288258405388L; 062 063 /** The optional base URI to create the link from. */ 064 private String m_baseUri; 065 066 /** The target detail page path. */ 067 private String m_detailPage; 068 069 /** The optional locale attribute. */ 070 private Locale m_locale; 071 072 /** 073 * Returns a link to a file in the OpenCms VFS 074 * that has been adjusted according to the web application path and the 075 * OpenCms static export rules.<p> 076 * 077 * The current OpenCms user context URI will be used as source of the link.</p> 078 * 079 * Since OpenCms version 7.0.2, you can also use this method in case you are not sure 080 * if the link is internal or external, as 081 * {@link CmsLinkManager#substituteLinkForUnknownTarget(org.opencms.file.CmsObject, String)} 082 * is used to calculate the link target.<p> 083 * 084 * Relative links are converted to absolute links, using the current element URI as base.<p> 085 * 086 * @param target the link that should be calculated, can be relative or absolute 087 * @param req the current request 088 * 089 * @return the target link adjusted according to the web application path and the OpenCms static export rules 090 * 091 * @see org.opencms.staticexport.CmsLinkManager#substituteLinkForUnknownTarget(org.opencms.file.CmsObject, String) 092 */ 093 public static String linkTagAction(String target, ServletRequest req) { 094 095 return linkTagAction(target, req, null); 096 } 097 098 /** 099 * Returns a link to a file in the OpenCms VFS 100 * that has been adjusted according to the web application path and the 101 * OpenCms static export rules.<p> 102 * 103 * If the <code>baseUri</code> parameter is provided, this will be treated as the source of the link, 104 * if this is <code>null</code> then the current OpenCms user context URI will be used as source.</p> 105 * 106 * Relative links are converted to absolute links, using the current element URI as base.<p> 107 * 108 * @param target the link that should be calculated, can be relative or absolute 109 * @param req the current request 110 * @param baseUri the base URI for the link source 111 * 112 * @return the target link adjusted according to the web application path and the OpenCms static export rules 113 * 114 * @see #linkTagAction(String, ServletRequest) 115 * 116 * @since 8.0.3 117 */ 118 public static String linkTagAction(String target, ServletRequest req, String baseUri) { 119 120 return linkTagAction(target, req, baseUri, null); 121 } 122 123 /** 124 * Returns a link to a file in the OpenCms VFS 125 * that has been adjusted according to the web application path and the 126 * OpenCms static export rules.<p> 127 * 128 * <p>If the <code>baseUri</code> parameter is provided, this will be treated as the source of the link, 129 * if this is <code>null</code> then the current OpenCms user context URI will be used as source.</p> 130 * 131 * <p>If the <code>locale</code> parameter is provided, the locale in the request context will be switched 132 * to the provided locale. This influences only the behavior of the 133 * {@link org.opencms.staticexport.CmsLocalePrefixLinkSubstitutionHandler}.</p> 134 * 135 * 136 * Relative links are converted to absolute links, using the current element URI as base.<p> 137 * 138 * @param target the link that should be calculated, can be relative or absolute 139 * @param req the current request 140 * @param baseUri the base URI for the link source 141 * @param locale the locale for which the link should be created (see {@link org.opencms.staticexport.CmsLocalePrefixLinkSubstitutionHandler} 142 * 143 * @return the target link adjusted according to the web application path and the OpenCms static export rules 144 * 145 * @see #linkTagAction(String, ServletRequest) 146 * 147 * @since 8.0.3 148 */ 149 public static String linkTagAction(String target, ServletRequest req, String baseUri, Locale locale) { 150 151 return linkTagAction(target, req, baseUri, null, locale); 152 } 153 154 /** 155 * Returns a link to a file in the OpenCms VFS 156 * that has been adjusted according to the web application path and the 157 * OpenCms static export rules.<p> 158 * 159 * <p>If the <code>baseUri</code> parameter is provided, this will be treated as the source of the link, 160 * if this is <code>null</code> then the current OpenCms user context URI will be used as source.</p> 161 * 162 * <p>If the <code>locale</code> parameter is provided, the locale in the request context will be switched 163 * to the provided locale. This influences only the behavior of the 164 * {@link org.opencms.staticexport.CmsLocalePrefixLinkSubstitutionHandler}.</p> 165 * 166 * 167 * Relative links are converted to absolute links, using the current element URI as base.<p> 168 * 169 * @param target the link that should be calculated, can be relative or absolute 170 * @param req the current request 171 * @param baseUri the base URI for the link source 172 * @param detailPage the target detail page, in case of linking to a specific detail page 173 * @param locale the locale for which the link should be created (see {@link org.opencms.staticexport.CmsLocalePrefixLinkSubstitutionHandler} 174 * 175 * @return the target link adjusted according to the web application path and the OpenCms static export rules 176 * 177 * @see #linkTagAction(String, ServletRequest) 178 * 179 * @since 8.0.3 180 */ 181 public static String linkTagAction( 182 String target, 183 ServletRequest req, 184 String baseUri, 185 String detailPage, 186 Locale locale) { 187 188 CmsFlexController controller = CmsFlexController.getController(req); 189 // be sure the link is absolute 190 String uri = CmsLinkManager.getAbsoluteUri(target, controller.getCurrentRequest().getElementUri()); 191 CmsObject cms = controller.getCmsObject(); 192 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(baseUri) || (null != locale)) { 193 try { 194 cms = OpenCms.initCmsObject(cms); 195 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(baseUri)) { 196 cms.getRequestContext().setUri(baseUri); 197 } 198 if (null != locale) { 199 cms.getRequestContext().setLocale(locale); 200 } 201 } catch (CmsException e) { 202 // should not happen, if it does we can't do anything useful and will just keep the original object 203 LOG.debug(e.getLocalizedMessage(), e); 204 } 205 } 206 // generate the link 207 return OpenCms.getLinkManager().substituteLinkForUnknownTarget(cms, uri, detailPage, false); 208 } 209 210 /** 211 * @see javax.servlet.jsp.tagext.Tag#doEndTag() 212 * 213 * @return EVAL_PAGE 214 * 215 * @throws JspException in case something goes wrong 216 */ 217 @Override 218 public int doEndTag() throws JspException { 219 220 ServletRequest req = pageContext.getRequest(); 221 222 // This will always be true if the page is called through OpenCms 223 if (CmsFlexController.isCmsRequest(req)) { 224 try { 225 // Get link-string from the body and reset body 226 String link = getBodyContent().getString(); 227 getBodyContent().clear(); 228 // Calculate the link substitution 229 String newlink = linkTagAction(link, req, getBaseUri(), getDetailPage(), m_locale); 230 // Write the result back to the page 231 getBodyContent().print(newlink); 232 getBodyContent().writeOut(pageContext.getOut()); 233 234 } catch (Exception ex) { 235 if (LOG.isErrorEnabled()) { 236 LOG.error(Messages.get().getBundle().key(Messages.ERR_PROCESS_TAG_1, "link"), ex); 237 } 238 throw new JspException(ex); 239 } 240 } 241 return EVAL_PAGE; 242 } 243 244 /** 245 * Returns the base URI used to create the link target.<p> 246 * 247 * @return the base URI used to create the link target 248 */ 249 public String getBaseUri() { 250 251 return m_baseUri; 252 } 253 254 /** 255 * Returns the target detail page path.<p> 256 * 257 * @return the target detail page path 258 */ 259 public String getDetailPage() { 260 261 return m_detailPage; 262 } 263 264 /** 265 * @see javax.servlet.jsp.tagext.Tag#release() 266 */ 267 @Override 268 public void release() { 269 270 super.release(); 271 } 272 273 /** 274 * Sets the base URI used to create the link target.<p> 275 * 276 * @param baseUri the base URI used to create the link target 277 */ 278 public void setBaseUri(String baseUri) { 279 280 m_baseUri = baseUri; 281 } 282 283 /** 284 * Sets the target detail page path.<p> 285 * 286 * @param detailPage the target detail page path 287 */ 288 public void setDetailPage(String detailPage) { 289 290 m_detailPage = detailPage; 291 } 292 293 /** 294 * Sets the locale for the link to create. 295 * 296 * @param localeName name of the locale, e.g. "en", "en_US", ... 297 */ 298 public void setLocale(String localeName) { 299 300 m_locale = CmsLocaleManager.getLocale(localeName); 301 } 302 303}