KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > servlet > jsp > jstl > tlv > ScriptFreeTLV


1 /*
2  * Copyright 1999-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
17 package javax.servlet.jsp.jstl.tlv;
18
19 import java.io.IOException JavaDoc;
20 import java.io.InputStream JavaDoc;
21 import java.util.Map JavaDoc;
22
23 import javax.servlet.jsp.tagext.PageData JavaDoc;
24 import javax.servlet.jsp.tagext.TagLibraryValidator JavaDoc;
25 import javax.servlet.jsp.tagext.ValidationMessage JavaDoc;
26 import javax.xml.parsers.ParserConfigurationException JavaDoc;
27 import javax.xml.parsers.SAXParser JavaDoc;
28 import javax.xml.parsers.SAXParserFactory JavaDoc;
29
30 import org.xml.sax.Attributes JavaDoc;
31 import org.xml.sax.SAXException JavaDoc;
32 import org.xml.sax.helpers.DefaultHandler JavaDoc;
33
34 /**
35  * <p>A TagLibraryValidator for enforcing restrictions against
36  * the use of JSP scripting elements.</p>
37  * <p>This TLV supports four initialization parameters, for controlling
38  * which of the four types of scripting elements are allowed or prohibited:</p>
39  * <ul>
40  * <li><b>allowDeclarations</b>: if true, indicates that declaration elements
41  * are not prohibited.
42  * <li><b>allowScriptlets</b>: if true, indicates that scriptlets are not
43  * prohibited
44  * <li><b>allowExpressions</b>: if true, indicates that top-level expression
45  * elements (i.e., expressions not associated with request-time attribute
46  * values) are not prohibited.
47  * <li><b>allowRTExpressions</b>: if true, indicates that expression elements
48  * associated with request-time attribute values are not prohibited.
49  * </ul>
50  * <p>The default value for all for initialization parameters is false,
51  * indicating all forms of scripting elements are to be prohibited.</p>
52  *
53  * @author <a HREF="mailto:mak@taglib.com">Mark A. Kolb</a>
54  * @author Shawn Bayern (minor changes)
55  */

56 public class ScriptFreeTLV extends TagLibraryValidator JavaDoc {
57   private boolean allowDeclarations = false;
58   private boolean allowScriptlets = false;
59   private boolean allowExpressions = false;
60   private boolean allowRTExpressions = false;
61   private SAXParserFactory JavaDoc factory;
62
63   /**
64    * Constructs a new validator instance.
65    * Initializes the parser factory to create non-validating, namespace-aware
66    * SAX parsers.
67    */

68   public ScriptFreeTLV () {
69     factory = SAXParserFactory.newInstance();
70     factory.setValidating(false);
71     factory.setNamespaceAware(true);
72   }
73
74   /**
75    * Sets the values of the initialization parameters, as supplied in the TLD.
76    * @param initParms a mapping from the names of the initialization parameters
77    * to their values, as specified in the TLD.
78    */

79   public void setInitParameters (Map JavaDoc initParms) {
80     super.setInitParameters(initParms);
81     String JavaDoc declarationsParm = (String JavaDoc) initParms.get("allowDeclarations");
82     String JavaDoc scriptletsParm = (String JavaDoc) initParms.get("allowScriptlets");
83     String JavaDoc expressionsParm = (String JavaDoc) initParms.get("allowExpressions");
84     String JavaDoc rtExpressionsParm = (String JavaDoc) initParms.get("allowRTExpressions");
85
86     allowDeclarations = "true".equalsIgnoreCase(declarationsParm);
87     allowScriptlets = "true".equalsIgnoreCase(scriptletsParm);
88     allowExpressions = "true".equalsIgnoreCase(expressionsParm);
89     allowRTExpressions = "true".equalsIgnoreCase(rtExpressionsParm);
90   }
91
92   /**
93    * Validates a single JSP page.
94    * @param prefix the namespace prefix specified by the page for the
95    * custom tag library being validated.
96    * @param uri the URI specified by the page for the TLD of the
97    * custom tag library being validated.
98    * @param page a wrapper around the XML representation of the page
99    * being validated.
100    * @return null, if the page is valid; otherwise, a ValidationMessage[]
101    * containing one or more messages indicating why the page is not valid.
102    */

103   public ValidationMessage JavaDoc[] validate
104       (String JavaDoc prefix, String JavaDoc uri, PageData JavaDoc page) {
105     InputStream JavaDoc in = null;
106     SAXParser JavaDoc parser;
107     MyContentHandler handler = new MyContentHandler();
108     try {
109       synchronized (factory) {
110     parser = factory.newSAXParser();
111       }
112       in = page.getInputStream();
113       parser.parse(in, handler);
114     }
115     catch (ParserConfigurationException JavaDoc e) {
116       return vmFromString(e.toString());
117     }
118     catch (SAXException JavaDoc e) {
119       return vmFromString(e.toString());
120     }
121     catch (IOException JavaDoc e) {
122       return vmFromString(e.toString());
123     }
124     finally {
125       if (in != null) try { in.close(); } catch (IOException JavaDoc e) {}
126     }
127     return handler.reportResults();
128   }
129
130   /**
131    * Handler for SAX events.
132    * Four counters are provided as instance variables,
133    * for counting occurrences of prohibited scripting elements.
134    */

135   private class MyContentHandler extends DefaultHandler JavaDoc {
136     private int declarationCount = 0;
137     private int scriptletCount = 0;
138     private int expressionCount = 0;
139     private int rtExpressionCount = 0;
140
141     /**
142      * This event is received whenever a new element is encountered.
143      * The qualified name of each such element is compared against
144      * the names of any prohibited scripting elements. When found, the
145      * corresponding counter is incremented.
146      * If expressions representing request-time attribute values are
147      * prohibited, it is also necessary to check the values of all
148      * attributes specified by the element. (Trying to figure out
149      * which attributes actually support request-time attribute values
150      * and checking only those is far more trouble than it's worth.)
151      */

152     public void startElement (String JavaDoc namespaceUri,
153                   String JavaDoc localName, String JavaDoc qualifiedName,
154                   Attributes JavaDoc atts) {
155       if ((! allowDeclarations)
156       && qualifiedName.equals("jsp:declaration"))
157     ++declarationCount;
158       else if ((! allowScriptlets)
159            && qualifiedName.equals("jsp:scriptlet"))
160     ++scriptletCount;
161       else if ((! allowExpressions)
162            && qualifiedName.equals("jsp:expression"))
163     ++expressionCount;
164       if (! allowRTExpressions) countRTExpressions(atts);
165     }
166
167     /**
168      * Auxiliary method for checking attribute values to see if
169      * are specified via request-time attribute values.
170      * Expressions representing request-time attribute values are
171      * recognized by their "%=" and "%" delimiters. When found, the
172      * corresponding counter is incremented.
173      */

174     private void countRTExpressions (Attributes JavaDoc atts) {
175       int stop = atts.getLength();
176       for (int i = 0; i < stop; ++i) {
177     String JavaDoc attval = atts.getValue(i);
178     if (attval.startsWith("%=") && attval.endsWith("%"))
179       ++rtExpressionCount;
180       }
181     }
182
183     /**
184      * Constructs a String reporting the number(s) of prohibited
185      * scripting elements that were detected, if any.
186      * Returns null if no violations were found, making the result
187      * of this method suitable for the return value of the
188      * TagLibraryValidator.validate() method.
189      *
190      * TODO: The update from 7/13/2001 merely makes this validator
191      * compliant with the new TLV API, but does not fully take advantage
192      * of this API. In the future, we should do so... but because
193      * of the possibility that anti-script checking will be incorporated
194      * into the base TLV, I've held off for now and just changed this
195      * class to use the new API. -- SB.
196      */

197     public ValidationMessage JavaDoc[] reportResults () {
198       if (declarationCount + scriptletCount + expressionCount
199           + rtExpressionCount > 0) {
200     StringBuffer JavaDoc results = new StringBuffer JavaDoc("JSP page contains ");
201     boolean first = true;
202     if (declarationCount > 0) {
203       results.append(Integer.toString(declarationCount));
204       results.append(" declaration");
205       if (declarationCount > 1) results.append('s');
206       first = false;
207     }
208     if (scriptletCount > 0) {
209       if (! first) results.append(", ");
210       results.append(Integer.toString(scriptletCount));
211       results.append(" scriptlet");
212       if (scriptletCount > 1) results.append('s');
213       first = false;
214     }
215     if (expressionCount > 0) {
216       if (! first) results.append(", ");
217       results.append(Integer.toString(expressionCount));
218       results.append(" expression");
219       if (expressionCount > 1) results.append('s');
220       first = false;
221     }
222     if (rtExpressionCount > 0) {
223       if (! first) results.append(", ");
224       results.append(Integer.toString(rtExpressionCount));
225       results.append(" request-time attribute value");
226       if (rtExpressionCount > 1) results.append('s');
227       first = false;
228     }
229     results.append(".");
230     return vmFromString(results.toString());
231       } else {
232     return null;
233       }
234     }
235   }
236
237
238   // constructs a ValidationMessage[] from a single String and no ID
239
private static ValidationMessage JavaDoc[] vmFromString(String JavaDoc message) {
240     return new ValidationMessage JavaDoc[] {
241       new ValidationMessage JavaDoc(null, message)
242     };
243   }
244
245 }
246
Popular Tags