001: /*
002: * Copyright 2002,2004 The Apache Software Foundation.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.apache.commons.jelly.tags.core;
017:
018: import java.io.StringReader;
019:
020: import javax.xml.parsers.ParserConfigurationException;
021: import javax.xml.parsers.SAXParser;
022: import javax.xml.parsers.SAXParserFactory;
023:
024: import org.apache.commons.jelly.JellyTagException;
025: import org.apache.commons.jelly.MissingAttributeException;
026: import org.apache.commons.jelly.Script;
027: import org.apache.commons.jelly.TagSupport;
028: import org.apache.commons.jelly.XMLOutput;
029: import org.apache.commons.jelly.parser.XMLParser;
030: import org.apache.commons.logging.Log;
031: import org.apache.commons.logging.LogFactory;
032: import org.xml.sax.ContentHandler;
033: import org.xml.sax.InputSource;
034: import org.xml.sax.SAXException;
035: import org.xml.sax.XMLReader;
036:
037: /**
038: * Parses the output of this tags body or of a given String as a Jelly script
039: * then either outputting the Script as a variable or executing the script.
040: *
041: * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
042: * @version $Revision: 155420 $
043: */
044: public class ParseTag extends TagSupport {
045:
046: /** The Log to which logging calls will be made. */
047: private static final Log log = LogFactory.getLog(ParseTag.class);
048:
049: /** The variable that will be generated for the document */
050: private String var;
051:
052: /** The markup text to be parsed */
053: private String text;
054:
055: /** The XMLReader used to parser the document */
056: private XMLReader xmlReader;
057:
058: /** The Jelly parser */
059: private XMLParser jellyParser;
060:
061: public ParseTag() {
062: }
063:
064: // Tag interface
065: //-------------------------------------------------------------------------
066:
067: /* (non-Javadoc)
068: * @see org.apache.commons.jelly.Tag#doTag(org.apache.commons.jelly.XMLOutput)
069: */
070: public void doTag(XMLOutput output)
071: throws MissingAttributeException, JellyTagException {
072:
073: String text = getText();
074: if (text != null) {
075: parseText(text);
076: } else {
077: parseBody(output);
078: }
079:
080: Script script = getJellyParser().getScript();
081: if (var != null) {
082: context.setVariable(var, script);
083: } else {
084: // invoke the script
085: script.run(context, output);
086: }
087: }
088:
089: // Properties
090: //-------------------------------------------------------------------------
091: /** The variable name that will be used for the Document variable created
092: */
093: public String getVar() {
094: return var;
095: }
096:
097: /** Sets the variable name that will be used for the Document variable created
098: */
099: public void setVar(String var) {
100: this .var = var;
101: }
102:
103: /**
104: * Returns the text to be parsed
105: * @return String
106: */
107: public String getText() {
108: return text;
109: }
110:
111: /**
112: * Sets the text to be parsed by this parser
113: * @param text The text to be parsed by this parser
114: */
115: public void setText(String text) {
116: this .text = text;
117: }
118:
119: /** @return the XMLReader used for parsing, creating one lazily if need be */
120: public XMLReader getXMLReader()
121: throws ParserConfigurationException, SAXException {
122: if (xmlReader == null) {
123: xmlReader = createXMLReader();
124: }
125: return xmlReader;
126: }
127:
128: /** Sets the XMLReader used for parsing */
129: public void setXMLReader(XMLReader xmlReader) {
130: this .xmlReader = xmlReader;
131: }
132:
133: /**
134: * @return XMLParser
135: */
136: public XMLParser getJellyParser() {
137: if (jellyParser == null) {
138: jellyParser = createJellyParser();
139: }
140: return jellyParser;
141: }
142:
143: /**
144: * Sets the jellyParser.
145: * @param jellyParser The jellyParser to set
146: */
147: public void setJellyParser(XMLParser jellyParser) {
148: this .jellyParser = jellyParser;
149: }
150:
151: // Implementation methods
152: //-------------------------------------------------------------------------
153:
154: /**
155: * Factory method to create a new XMLReader
156: */
157: protected XMLReader createXMLReader()
158: throws ParserConfigurationException, SAXException {
159: SAXParserFactory factory = SAXParserFactory.newInstance();
160: factory.setNamespaceAware(true);
161: SAXParser parser = factory.newSAXParser();
162: return parser.getXMLReader();
163: }
164:
165: /**
166: * Parses the body of this tag and returns the parsed document
167: */
168: protected void parseBody(XMLOutput output) throws JellyTagException {
169: ContentHandler handler = getJellyParser();
170: XMLOutput newOutput = new XMLOutput(handler);
171:
172: try {
173: handler.startDocument();
174: invokeBody(newOutput);
175: handler.endDocument();
176: } catch (SAXException e) {
177: throw new JellyTagException(e);
178: }
179: }
180:
181: /**
182: * Parses the give piece of text as being markup
183: */
184: protected void parseText(String text) throws JellyTagException {
185: if (log.isDebugEnabled()) {
186: log.debug("About to parse: " + text);
187: }
188:
189: try {
190: getXMLReader().parse(
191: new InputSource(new StringReader(text)));
192: } catch (Exception e) {
193: throw new JellyTagException(e);
194: }
195: }
196:
197: /**
198: * Factory method to create a new Jelly parser
199: * @return XMLParser
200: */
201: protected XMLParser createJellyParser() {
202: XMLParser answer = new XMLParser();
203: answer.setContext(context);
204: return answer;
205: }
206: }
|