View Javadoc

1   /*
2    * Copyright 2002,2004 The Apache Software Foundation.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.apache.commons.jelly.tags.core;
17  
18  import java.io.StringReader;
19  
20  import javax.xml.parsers.ParserConfigurationException;
21  import javax.xml.parsers.SAXParser;
22  import javax.xml.parsers.SAXParserFactory;
23  
24  import org.apache.commons.jelly.JellyTagException;
25  import org.apache.commons.jelly.MissingAttributeException;
26  import org.apache.commons.jelly.Script;
27  import org.apache.commons.jelly.TagSupport;
28  import org.apache.commons.jelly.XMLOutput;
29  import org.apache.commons.jelly.parser.XMLParser;
30  import org.apache.commons.logging.Log;
31  import org.apache.commons.logging.LogFactory;
32  import org.xml.sax.ContentHandler;
33  import org.xml.sax.InputSource;
34  import org.xml.sax.SAXException;
35  import org.xml.sax.XMLReader;
36  
37  /***
38   * Parses the output of this tags body or of a given String as a Jelly script
39   * then either outputting the Script as a variable or executing the script.
40   *
41   * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
42   * @version $Revision: 155420 $
43   */
44  public class ParseTag extends TagSupport {
45  
46      /*** The Log to which logging calls will be made. */
47      private static final Log log = LogFactory.getLog(ParseTag.class);
48  
49      /*** The variable that will be generated for the document */
50      private String var;
51  
52      /*** The markup text to be parsed */
53      private String text;
54  
55      /*** The XMLReader used to parser the document */
56      private XMLReader xmlReader;
57  
58      /*** The Jelly parser */
59      private XMLParser jellyParser;
60  
61      public ParseTag() {
62      }
63  
64      // Tag interface
65      //-------------------------------------------------------------------------
66  
67      /* (non-Javadoc)
68       * @see org.apache.commons.jelly.Tag#doTag(org.apache.commons.jelly.XMLOutput)
69       */
70      public void doTag(XMLOutput output)
71          throws MissingAttributeException, JellyTagException {
72  
73          String text = getText();
74          if (text != null) {
75              parseText(text);
76          }
77          else {
78              parseBody(output);
79          }
80  
81          Script script = getJellyParser().getScript();
82          if (var != null) {
83              context.setVariable(var, script);
84          }
85          else {
86              // invoke the script
87              script.run(context, output);
88          }
89      }
90  
91      // Properties
92      //-------------------------------------------------------------------------
93      /*** The variable name that will be used for the Document variable created
94       */
95      public String getVar() {
96          return var;
97      }
98  
99      /*** Sets the variable name that will be used for the Document variable created
100      */
101     public void setVar(String var) {
102         this.var = var;
103     }
104 
105     /***
106      * Returns the text to be parsed
107      * @return String
108      */
109     public String getText() {
110         return text;
111     }
112 
113     /***
114      * Sets the text to be parsed by this parser
115      * @param text The text to be parsed by this parser
116      */
117     public void setText(String text) {
118         this.text = text;
119     }
120 
121 
122     /*** @return the XMLReader used for parsing, creating one lazily if need be  */
123     public XMLReader getXMLReader() throws ParserConfigurationException, SAXException {
124         if (xmlReader == null) {
125             xmlReader = createXMLReader();
126         }
127         return xmlReader;
128     }
129 
130     /*** Sets the XMLReader used for parsing */
131     public void setXMLReader(XMLReader xmlReader) {
132         this.xmlReader = xmlReader;
133     }
134 
135 
136     /***
137      * @return XMLParser
138      */
139     public XMLParser getJellyParser() {
140         if (jellyParser == null) {
141             jellyParser = createJellyParser();
142         }
143         return jellyParser;
144     }
145 
146     /***
147      * Sets the jellyParser.
148      * @param jellyParser The jellyParser to set
149      */
150     public void setJellyParser(XMLParser jellyParser) {
151         this.jellyParser = jellyParser;
152     }
153 
154 
155     // Implementation methods
156     //-------------------------------------------------------------------------
157 
158     /***
159      * Factory method to create a new XMLReader
160      */
161     protected XMLReader createXMLReader() throws ParserConfigurationException, SAXException {
162         SAXParserFactory factory = SAXParserFactory.newInstance();
163         factory.setNamespaceAware(true);
164         SAXParser parser = factory.newSAXParser();
165         return parser.getXMLReader();
166     }
167 
168 
169     /***
170      * Parses the body of this tag and returns the parsed document
171      */
172     protected void parseBody(XMLOutput output) throws JellyTagException {
173         ContentHandler handler = getJellyParser();
174         XMLOutput newOutput = new XMLOutput(handler);
175 
176         try {
177             handler.startDocument();
178             invokeBody(newOutput);
179             handler.endDocument();
180         }
181         catch (SAXException e) {
182             throw new JellyTagException(e);
183         }
184     }
185 
186     /***
187      * Parses the give piece of text as being markup
188      */
189     protected void parseText(String text) throws JellyTagException {
190         if ( log.isDebugEnabled() ) {
191             log.debug( "About to parse: " + text );
192         }
193 
194         try {
195             getXMLReader().parse( new InputSource( new StringReader( text ) ) );
196         }
197         catch (Exception e) {
198             throw new JellyTagException(e);
199         }
200     }
201 
202     /***
203      * Factory method to create a new Jelly parser
204      * @return XMLParser
205      */
206     protected XMLParser createJellyParser() {
207         XMLParser answer = new XMLParser();
208         answer.setContext(context);
209         return answer;
210     }
211 }