001: /*
002: * File : $Source: /usr/local/cvs/opencms/src/org/opencms/jsp/CmsJspTagParse.java,v $
003: * Date : $Date: 2008-02-27 12:05:34 $
004: * Version: $Revision: 1.8 $
005: *
006: * This library is part of OpenCms -
007: * the Open Source Content Management System
008: *
009: * Copyright (c) 2002 - 2008 Alkacon Software GmbH (http://www.alkacon.com)
010: *
011: * This library is free software; you can redistribute it and/or
012: * modify it under the terms of the GNU Lesser General Public
013: * License as published by the Free Software Foundation; either
014: * version 2.1 of the License, or (at your option) any later version.
015: *
016: * This library is distributed in the hope that it will be useful,
017: * but WITHOUT ANY WARRANTY; without even the implied warranty of
018: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
019: * Lesser General Public License for more details.
020: *
021: * For further information about Alkacon Software GmbH, please see the
022: * company website: http://www.alkacon.com
023: *
024: * For further information about OpenCms, please see the
025: * project website: http://www.opencms.org
026: *
027: * You should have received a copy of the GNU Lesser General Public
028: * License along with this library; if not, write to the Free Software
029: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
030: */
031:
032: package org.opencms.jsp;
033:
034: import org.opencms.file.CmsObject;
035: import org.opencms.file.CmsRequestContext;
036: import org.opencms.flex.CmsFlexController;
037: import org.opencms.jsp.parse.A_CmsConfiguredHtmlParser;
038: import org.opencms.main.CmsException;
039: import org.opencms.main.CmsLog;
040: import org.opencms.main.OpenCms;
041: import org.opencms.util.CmsStringUtil;
042:
043: import java.io.PrintWriter;
044: import java.io.StringWriter;
045: import java.util.Iterator;
046: import java.util.List;
047:
048: import javax.servlet.ServletRequest;
049: import javax.servlet.jsp.JspException;
050: import javax.servlet.jsp.PageContext;
051: import javax.servlet.jsp.tagext.BodyTagSupport;
052:
053: import org.apache.commons.logging.Log;
054:
055: import org.htmlparser.util.ParserException;
056:
057: /**
058: * Implements the <code><cms:parse></cms:parse></code> tag to allow parsing of nested
059: * HTML with the {@link org.opencms.jsp.parse.A_CmsConfiguredHtmlParser}} implementation specified by the "parserClass" attribute.
060: * <p>
061: *
062: * @author Achim Westermann
063: *
064: * @version $Revision: 1.8 $
065: *
066: * @since 6.1.3
067: */
068: public class CmsJspTagParse extends BodyTagSupport {
069:
070: /**
071: * The name of the mandatory Tag attribute for the visitor class an instance of will be guided
072: * throught the body content.
073: */
074: public static final String ATT_VISITOR_CLASS = "parserClass";
075:
076: /** Tag name constant for log output. */
077: public static final String TAG_NAME = "parse";
078:
079: /** The log object for this class. */
080: private static final Log LOG = CmsLog.getLog(CmsJspTagParse.class);
081:
082: /** Serial version UID required for safe serialization. */
083: private static final long serialVersionUID = -6541745426202242240L;
084:
085: /** The visitor / parser class name to use. */
086: private String m_configuredParserClassname;
087:
088: /** List of upper case tag name strings of tags that should not be auto-corrected if closing divs are missing. */
089: private List m_noAutoCloseTags;
090:
091: /** The attribute value of the param attribute. */
092: private String m_param = "";
093:
094: /**
095: * @see javax.servlet.jsp.tagext.Tag#doEndTag()
096: *
097: * @return EVAL_PAGE
098: *
099: * @throws JspException in case something goes wrong
100: */
101: public int doEndTag() throws JspException {
102:
103: ServletRequest req = pageContext.getRequest();
104: A_CmsConfiguredHtmlParser parser;
105:
106: // This will always be true if the page is called through OpenCms
107: if (CmsFlexController.isCmsRequest(req)) {
108: String content = "";
109: try {
110: if (CmsStringUtil.isEmpty(m_configuredParserClassname)) {
111: if (LOG.isErrorEnabled()) {
112: LOG
113: .error(Messages
114: .get()
115: .getBundle()
116: .key(
117: Messages.GUI_ERR_TAG_ATTRIBUTE_MISSING_2,
118: new Object[] {
119: TAG_NAME,
120: ATT_VISITOR_CLASS }));
121: }
122:
123: }
124: // wrong attribute visitorClass -> content will remain empty, but no exception is
125: // thrown
126: try {
127: // load
128: Class cl = Class
129: .forName(m_configuredParserClassname);
130: // Instantiate
131: Object instance = cl.newInstance();
132: // cast
133: parser = (A_CmsConfiguredHtmlParser) instance;
134: parser.setParam(m_param);
135: // cms object:
136: CmsFlexController controller = CmsFlexController
137: .getController(req);
138: CmsObject cms = controller.getCmsObject();
139: parser.setCmsObject(cms);
140: content = parseTagAction(getBodyContent()
141: .getString(), pageContext, parser);
142:
143: } catch (Exception e) {
144: if (LOG.isErrorEnabled()) {
145: LOG
146: .error(
147: Messages
148: .get()
149: .getBundle()
150: .key(
151: Messages.GUI_ERR_TAG_ATTRIBUTE_INVALID_3,
152: new Object[] {
153: TAG_NAME,
154: ATT_VISITOR_CLASS,
155: A_CmsConfiguredHtmlParser.class
156: .getName() }),
157: e);
158: }
159: e.printStackTrace(System.err);
160: }
161:
162: } finally {
163: try {
164: getBodyContent().clear();
165: getBodyContent().print(content);
166: getBodyContent().writeOut(pageContext.getOut());
167: if (OpenCms.getSystemInfo()
168: .isTagsReleaseAfterEndTag()) {
169: // need to release manually, JSP container may not call release as required (happens with Tomcat)
170: release();
171: }
172:
173: } catch (Exception ex) {
174: if (OpenCms.getSystemInfo()
175: .isTagsReleaseAfterEndTag()) {
176: // need to release manually, JSP container may not call release as required (happens with Tomcat)
177: release();
178: }
179: if (LOG.isErrorEnabled()) {
180: LOG.error(Messages.get().getBundle().key(
181: Messages.ERR_PROCESS_TAG_1, TAG_NAME),
182: ex);
183: }
184: // this is severe
185: throw new JspException(ex);
186: }
187:
188: }
189:
190: }
191: return EVAL_PAGE;
192: }
193:
194: /**
195: * Getter for the attribute "noAutoCloseTags" of the <cms:parse> tag.<p>
196: *
197: * Returns a <code>String</code> that consists of the comma-separated upper case tag names for which this
198: * tag will not correct missing closing tags. <p>
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)
207: && (m_noAutoCloseTags.size() > 0)) {
208: Iterator it = m_noAutoCloseTags.iterator();
209: while (it.hasNext()) {
210: result.append(it.next()).append(',');
211: }
212: }
213: return result.toString();
214: }
215:
216: /**
217: * Returns the param.<p>
218: *
219: * @return the param
220: */
221: public String getParam() {
222:
223: return m_param;
224: }
225:
226: /**
227: * Returns the fully qualified class name of the {@link A_CmsConfiguredHtmlParser} class to use
228: * for parsing.<p>
229: *
230: * @return the parserrClass
231: */
232: public String getParserClass() {
233:
234: return m_configuredParserClassname;
235: }
236:
237: /**
238: * Internal action method.<p>
239: *
240: * Parses (and potentially transforms) a HTMl content block.<p>
241: *
242: * @param content the content to be parsed / transformed
243: * @param context needed for getting the encoding / the locale
244: * @param parser the visitor / parser to use
245: *
246: * @return the transformed content
247: */
248: public String parseTagAction(String content, PageContext context,
249: A_CmsConfiguredHtmlParser parser) {
250:
251: String result = null;
252: CmsRequestContext cmsContext = CmsFlexController.getCmsObject(
253: context.getRequest()).getRequestContext();
254:
255: if (parser == null) {
256: if (LOG.isErrorEnabled()) {
257: LOG.error(Messages.get().getBundle(
258: cmsContext.getLocale()).key(
259: Messages.GUI_ERR_TAG_ATTRIBUTE_MISSING_2,
260: new Object[] { TAG_NAME, ATT_VISITOR_CLASS }));
261: }
262: result = content;
263: } else {
264:
265: String encoding = cmsContext.getEncoding();
266: try {
267: result = parser.doParse(content, encoding,
268: this .m_noAutoCloseTags);
269:
270: } catch (ParserException pex) {
271:
272: if (LOG.isErrorEnabled()) {
273: LOG.error(Messages.get().getBundle(
274: cmsContext.getLocale()).key(
275: Messages.ERR_PROCESS_TAG_1,
276: new Object[] { TAG_NAME }), pex);
277: }
278: StringWriter stackTrace = new StringWriter();
279: PrintWriter writer = new PrintWriter(new StringWriter());
280: StringBuffer msg = new StringBuffer("<!--\n").append(
281: pex.getLocalizedMessage()).append("\n");
282: pex.printStackTrace(writer);
283: msg.append(stackTrace.toString()).append("\n-->");
284: result = msg.toString();
285: } catch (CmsException cmex) {
286: if (LOG.isErrorEnabled()) {
287: LOG.error(Messages.get().getBundle(
288: cmsContext.getLocale()).key(
289: Messages.ERR_PROCESS_TAG_1,
290: new Object[] { TAG_NAME }), cmex);
291: }
292: StringWriter stackTrace = new StringWriter();
293: PrintWriter writer = new PrintWriter(new StringWriter());
294: StringBuffer msg = new StringBuffer("<!--\n").append(
295: cmex.getLocalizedMessage()).append("\n");
296: cmex.printStackTrace(writer);
297: msg.append(stackTrace.toString()).append("\n-->");
298: result = msg.toString();
299: }
300:
301: }
302: return result;
303: }
304:
305: /**
306: * @see javax.servlet.jsp.tagext.Tag#release()
307: */
308: public void release() {
309:
310: m_configuredParserClassname = null;
311: m_param = null;
312: super .release();
313: }
314:
315: /**
316: * Setter for the attribute "noAutoCloseTags" of the <cms:parse> tag.<p>
317: *
318: * Awaits a <code>String</code> that consists of the comma-separated upper case tag names for which this
319: * tag should not correct missing closing tags.<p>
320: *
321: * @param noAutoCloseTagList a <code>String</code> that consists of the comma-separated upper case tag names for which this
322: * tag should not correct missing closing tags
323: */
324: public void setNoAutoCloseTags(String noAutoCloseTagList) {
325:
326: m_noAutoCloseTags = CmsStringUtil.splitAsList(
327: noAutoCloseTagList, ',');
328:
329: }
330:
331: /**
332: * Sets the param.<p>
333: *
334: * @param param the param to set
335: */
336: public void setParam(String param) {
337:
338: m_param = param;
339: }
340:
341: /**
342: * Sets the fully qualified class name of the {@link A_CmsConfiguredHtmlParser} class to use for
343: * parsing.<p>
344: *
345: * @param parserClass the fully qualified class name of the {@link A_CmsConfiguredHtmlParser}
346: * class to use for parsing
347: */
348: public void setParserClass(String parserClass) {
349:
350: m_configuredParserClassname = parserClass;
351: }
352: }
|