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.CmsProperty; 031import org.opencms.flex.CmsFlexController; 032import org.opencms.i18n.CmsLocaleManager; 033import org.opencms.jsp.decorator.CmsHtmlDecorator; 034import org.opencms.jsp.decorator.I_CmsDecoratorConfiguration; 035import org.opencms.main.CmsLog; 036import org.opencms.util.CmsStringUtil; 037 038import java.util.Iterator; 039import java.util.List; 040import java.util.Locale; 041 042import javax.servlet.ServletRequest; 043import javax.servlet.jsp.JspException; 044import javax.servlet.jsp.tagext.BodyTagSupport; 045 046import org.apache.commons.logging.Log; 047 048/** 049 * Implements the <code><cms:decorate></cms:decorate></code> 050 * tag to decorate HTML content with configurated decoration maps.<p> 051 * 052 * @since 6.1.3 053 */ 054public class CmsJspTagDecorate extends BodyTagSupport { 055 056 /** The name of the default decorator configuration. */ 057 public static final String DEFAULT_DECORATOR_CONFIGURATION = "org.opencms.jsp.decorator.CmsDecoratorConfiguration"; 058 059 /** The property to store the decorator classname .*/ 060 public static final String PROPERTY_CATEGORY = "category"; 061 062 /** The log object for this class. */ 063 private static final Log LOG = CmsLog.getLog(CmsJspTagDecorate.class); 064 065 /** Serial version UID required for safe serialization. */ 066 private static final long serialVersionUID = 3072561342127379294L; 067 068 /** Indicates the parse action should be disabled to allow inline editing in the container page editor. */ 069 private boolean m_allowInlineEdit; 070 071 /** The configuration. */ 072 private String m_file; 073 074 /** The decoration locale. */ 075 private String m_locale; 076 077 /** List of upper case tag name strings of tags that should not be auto-corrected if closing divs are missing. */ 078 private List<String> m_noAutoCloseTags; 079 080 /** 081 * Internal action method.<p> 082 * 083 * DEcorates a HTMl content block.<p> 084 * 085 * @param content the content to be decorated 086 * @param configFile the config file 087 * @param locale the locale to use for decoration or NOLOCALE if not locale should be used 088 * @param req the current request 089 * 090 * @return the decorated content 091 */ 092 public String decorateTagAction(String content, String configFile, String locale, ServletRequest req) { 093 094 try { 095 Locale loc = null; 096 CmsFlexController controller = CmsFlexController.getController(req); 097 if (CmsStringUtil.isEmpty(locale)) { 098 loc = controller.getCmsObject().getRequestContext().getLocale(); 099 } else { 100 loc = CmsLocaleManager.getLocale(locale); 101 } 102 103 // read the decorator configurator class 104 CmsProperty decoratorClass = controller.getCmsObject().readPropertyObject( 105 configFile, 106 PROPERTY_CATEGORY, 107 false); 108 String decoratorClassName = decoratorClass.getValue(); 109 if (CmsStringUtil.isEmpty(decoratorClassName)) { 110 decoratorClassName = DEFAULT_DECORATOR_CONFIGURATION; 111 } 112 113 String encoding = controller.getCmsObject().getRequestContext().getEncoding(); 114 // use the correct decorator configurator and initialize it 115 I_CmsDecoratorConfiguration config = (I_CmsDecoratorConfiguration)Class.forName( 116 decoratorClassName).newInstance(); 117 config.init(controller.getCmsObject(), configFile, loc); 118 119 CmsHtmlDecorator decorator = new CmsHtmlDecorator(controller.getCmsObject(), config); 120 121 decorator.setNoAutoCloseTags(m_noAutoCloseTags); 122 return decorator.doDecoration(content, encoding); 123 } catch (Exception e) { 124 if (LOG.isErrorEnabled()) { 125 LOG.error(Messages.get().getBundle().key(Messages.ERR_PROCESS_TAG_1, "decoration"), e); 126 } 127 return content; 128 } 129 } 130 131 /** 132 * @see javax.servlet.jsp.tagext.Tag#doEndTag() 133 * @return EVAL_PAGE 134 * @throws JspException in case something goes wrong 135 */ 136 @Override 137 public int doEndTag() throws JspException { 138 139 ServletRequest req = pageContext.getRequest(); 140 if (m_allowInlineEdit && CmsJspTagEditable.isEditableRequest(req)) { 141 // during inline editing the content should not be parsed 142 try { 143 getBodyContent().writeOut(pageContext.getOut()); 144 release(); 145 } catch (Exception ex) { 146 release(); 147 if (LOG.isErrorEnabled()) { 148 LOG.error(Messages.get().getBundle().key(Messages.ERR_PROCESS_TAG_1, "decoration"), ex); 149 } 150 // this is severe 151 throw new JspException(ex); 152 } 153 } else { 154 // This will always be true if the page is called through OpenCms 155 if (CmsFlexController.isCmsRequest(req)) { 156 try { 157 String content = decorateTagAction(getBodyContent().getString(), getFile(), getLocale(), req); 158 getBodyContent().clear(); 159 getBodyContent().print(content); 160 getBodyContent().writeOut(pageContext.getOut()); 161 162 } catch (Exception ex) { 163 if (LOG.isErrorEnabled()) { 164 LOG.error(Messages.get().getBundle().key(Messages.ERR_PROCESS_TAG_1, "decoration"), ex); 165 } 166 throw new JspException(ex); 167 } 168 } 169 } 170 return EVAL_PAGE; 171 } 172 173 /** 174 * Returns the file name.<p> 175 * 176 * @return the file name 177 */ 178 public String getFile() { 179 180 return m_file; 181 } 182 183 /** 184 * Returns the locale name.<p> 185 * 186 * @return the locale name 187 */ 188 public String getLocale() { 189 190 return m_locale; 191 } 192 193 /** 194 * Getter for the attribute "noAutoCloseTags" of the <cms:parse> tag.<p> 195 * 196 * Returns a <code>String</code> that consists of the comma-separated upper case tag names for which this 197 * tag will not correct missing closing tags. <p> 198 * 199 * 200 * @return a String that consists of the comma-separated upper case tag names for which this 201 * tag will not correct missing closing tags. 202 */ 203 public String getNoAutoCloseTags() { 204 205 StringBuffer result = new StringBuffer(); 206 if ((m_noAutoCloseTags != null) && (m_noAutoCloseTags.size() > 0)) { 207 Iterator<String> it = m_noAutoCloseTags.iterator(); 208 while (it.hasNext()) { 209 result.append(it.next()).append(','); 210 } 211 } 212 return result.toString(); 213 } 214 215 /** 216 * Returns if the parse action should be disabled to allow inline editing in the container page editor.<p> 217 * 218 * @return <code>true</code> if the parse action should be disabled to allow inline editing in the container page editor 219 */ 220 public boolean isAllowInlineEdit() { 221 222 return m_allowInlineEdit; 223 } 224 225 /** 226 * Sets if the parse action should be disabled to allow inline editing in the container page editor.<p> 227 * 228 * @param allowInlineEdit <code>true</code> to allow inline editing 229 */ 230 public void setAllowInlineEdit(boolean allowInlineEdit) { 231 232 m_allowInlineEdit = allowInlineEdit; 233 } 234 235 /** 236 * Sets the file name.<p> 237 * 238 * @param file the file name 239 */ 240 public void setFile(String file) { 241 242 if (file != null) { 243 m_file = file.toLowerCase(); 244 } else { 245 m_file = null; 246 } 247 } 248 249 /** 250 * Sets the locale name.<p> 251 * 252 * @param locale the locale name 253 */ 254 public void setLocale(String locale) { 255 256 m_locale = locale; 257 } 258 259 /** 260 * Setter for the attribute "noAutoCloseTags" of the <cms:parse> tag.<p> 261 * 262 * Awaits a <code>String</code> that consists of the comma-separated upper case tag names for which this 263 * tag should not correct missing closing tags.<p> 264 * 265 * @param noAutoCloseTagList a <code>String</code> that consists of the comma-separated upper case tag names for which this 266 * tag should not correct missing closing tags. 267 */ 268 public void setNoAutoCloseTags(String noAutoCloseTagList) { 269 270 m_noAutoCloseTags = CmsStringUtil.splitAsList(noAutoCloseTagList, ','); 271 272 } 273}