001: package com.quadcap.http.servlets.jsp;
002:
003: /* Copyright 1999 - 2003 Quadcap Software. All rights reserved.
004: *
005: * This software is distributed under the Quadcap Free Software License.
006: * This software may be used or modified for any purpose, personal or
007: * commercial. Open Source redistributions are permitted. Commercial
008: * redistribution of larger works derived from, or works which bundle
009: * this software requires a "Commercial Redistribution License"; see
010: * http://www.quadcap.com/purchase.
011: *
012: * Redistributions qualify as "Open Source" under one of the following terms:
013: *
014: * Redistributions are made at no charge beyond the reasonable cost of
015: * materials and delivery.
016: *
017: * Redistributions are accompanied by a copy of the Source Code or by an
018: * irrevocable offer to provide a copy of the Source Code for up to three
019: * years at the cost of materials and delivery. Such redistributions
020: * must allow further use, modification, and redistribution of the Source
021: * Code under substantially the same terms as this license.
022: *
023: * Redistributions of source code must retain the copyright notices as they
024: * appear in each source code file, these license terms, and the
025: * disclaimer/limitation of liability set forth as paragraph 6 below.
026: *
027: * Redistributions in binary form must reproduce this Copyright Notice,
028: * these license terms, and the disclaimer/limitation of liability set
029: * forth as paragraph 6 below, in the documentation and/or other materials
030: * provided with the distribution.
031: *
032: * The Software is provided on an "AS IS" basis. No warranty is
033: * provided that the Software is free of defects, or fit for a
034: * particular purpose.
035: *
036: * Limitation of Liability. Quadcap Software shall not be liable
037: * for any damages suffered by the Licensee or any third party resulting
038: * from use of the Software.
039: */
040:
041: import java.io.BufferedInputStream;
042: import java.io.BufferedReader;
043: import java.io.CharArrayWriter;
044: import java.io.File;
045: import java.io.FileReader;
046: import java.io.IOException;
047: import java.io.InputStream;
048: import java.io.InputStreamReader;
049: import java.io.PrintWriter;
050: import java.io.Reader;
051: import java.io.Writer;
052:
053: import java.util.Enumeration;
054: import java.util.Hashtable;
055: import java.util.Vector;
056:
057: import javax.servlet.ServletContext;
058:
059: import org.xml.sax.AttributeList;
060: import org.xml.sax.DocumentHandler;
061: import org.xml.sax.DTDHandler;
062: import org.xml.sax.EntityResolver;
063: import org.xml.sax.ErrorHandler;
064: import org.xml.sax.HandlerBase;
065: import org.xml.sax.InputSource;
066: import org.xml.sax.Locator;
067: import org.xml.sax.Parser;
068: import org.xml.sax.SAXException;
069:
070: import com.quadcap.util.collections.ArrayQueue;
071:
072: import com.quadcap.util.Debug;
073:
074: /**
075: * This class is a SAX parser handler for parsing JSP documents.
076: *
077: * @author Stan Bailes
078: */
079: public class JspHandler implements DocumentHandler, EntityResolver,
080: TagContext {
081: ServletContext context;
082: JspParser parser;
083: JspObject jsp;
084: Hashtable tagHandlers = new Hashtable();
085: PrintWriter w;
086: CharArrayWriter cw = null;
087: boolean written = false;
088: ArrayQueue tagStack = new ArrayQueue(0, -1);
089: ArrayQueue wStack = new ArrayQueue(0, -1);
090: Hashtable pageDirectives = new Hashtable();
091:
092: public JspHandler(ServletContext context, JspParser parser,
093: PrintWriter w, JspObject jsp) {
094: this .context = context;
095: this .parser = parser;
096: this .jsp = jsp;
097: this .w = w;
098: addHandler("jsp:root", new TagJspRoot());
099: addHandler("jsp:useBean", new TagJspUseBean());
100: addHandler("jsp:expression", new TagJspExpression());
101: addHandler("jsp:expr", new TagJspExpression());
102: addHandler("jsp:declaration", new TagJspDeclaration());
103: addHandler("jsp:decl", new TagJspDeclaration());
104: addHandler("jsp:scriptlet", new TagJspScriptlet());
105: addHandler("jsp:directive.page", new TagJspPage());
106: addHandler("jsp:directive.include", new TagDirInclude());
107: addHandler("jsp:forward", new TagJspForward());
108: addHandler("jsp:include", new TagJspInclude());
109: addHandler("jsp:getProperty", new TagJspGetProperty());
110: addHandler("jsp:setProperty", new TagJspSetProperty());
111: }
112:
113: public PrintWriter getPrintWriter() {
114: return w;
115: }
116:
117: public String getPackageName() {
118: return jsp.getPackageName();
119: }
120:
121: public String getClassName() {
122: return jsp.getClassName();
123: }
124:
125: public void includeFile(String file) throws IOException,
126: SAXException {
127: EntityResolver resolver = parser.getEntityResolver();
128: InputSource in = null;
129: if (resolver != null) {
130: in = resolver.resolveEntity(null, file);
131: } else {
132: FileReader f = new FileReader(file);
133: in = new InputSource(f);
134: }
135: if (in == null) {
136: throw new IOException("Can't resolve entity: " + file);
137: }
138: parser.pushInputSource(in);
139: }
140:
141: public PrintWriter pushPrintWriter(PrintWriter p) {
142: wStack.addBack(w);
143: PrintWriter oldW = w;
144: w = p;
145: return oldW;
146: }
147:
148: public PrintWriter popPrintWriter() {
149: w = (PrintWriter) wStack.popBack();
150: return w;
151: }
152:
153: public void addPageDirective(String name, String val) {
154: Vector v = (Vector) pageDirectives.get(name);
155: if (v == null) {
156: v = new Vector();
157: pageDirectives.put(name, v);
158: }
159: v.addElement(val);
160: }
161:
162: public Enumeration getPageDirectives(String name) {
163: Vector v = (Vector) pageDirectives.get(name);
164: if (v == null)
165: v = new Vector();
166: return v.elements();
167: }
168:
169: public String getPageDirective(String name) {
170: String s = null;
171: Vector v = (Vector) pageDirectives.get(name);
172: if (v != null && v.size() > 0)
173: s = v.elementAt(0).toString();
174: return s;
175: }
176:
177: public String getPageDirective(String name, String dflt) {
178: String s = dflt;
179: Vector v = (Vector) pageDirectives.get(name);
180: if (v != null && v.size() > 0)
181: s = v.elementAt(0).toString();
182: return s;
183: }
184:
185: public boolean isValidTag(String name) {
186: return tagHandlers.get(name) != null;
187: }
188:
189: public void addHandler(String name, TagHandler h) {
190: tagHandlers.put(name, h);
191: }
192:
193: public void startDocument() {
194: }
195:
196: public void endDocument() {
197: }
198:
199: public void ignorableWhitespace(char[] ch, int off, int cnt)
200: throws SAXException {
201: characters(ch, off, cnt);
202: }
203:
204: public void processingInstruction(String target, String data) {
205: }
206:
207: public void setDocumentLocator(Locator locator) {
208: }
209:
210: public void startElement(String tag, AttributeList attrs)
211: throws SAXException {
212: //Debug.println("START: " + tag + " " + TagJsp.toString(attrs));
213: try {
214: TagHandler h = (TagHandler) tagHandlers.get(tag);
215: if (h != null) {
216: TagInstance t = h.makeInstance(this );
217: t.doStartTag(tag, attrs);
218: tagStack.addBack(t);
219: } else {
220: CharArrayWriter cw = new CharArrayWriter();
221: cw.write('<');
222: cw.write(tag);
223: for (int i = 0; i < attrs.getLength(); i++) {
224: cw.write(' ');
225: cw.write(attrs.getName(i));
226: cw.write('=');
227: cw.write('"');
228: cw.write(attrs.getValue(i));
229: cw.write('"');
230: }
231: cw.write('>');
232: char[] ch = cw.toCharArray();
233: characters(ch, 0, ch.length);
234: }
235: } catch (Exception e) {
236: Debug.print(e);
237: throw new SAXException(e.toString());
238: }
239: }
240:
241: public void characters(char[] ch, int off, int len)
242: throws SAXException {
243: try {
244: TagInstance t = (TagInstance) tagStack.tail();
245: if (t != null) {
246: t.doCharacters(ch, off, len);
247: }
248: } catch (Exception e) {
249: Debug.print(e);
250: throw new SAXException(e.toString());
251: }
252: }
253:
254: public void endElement(String tag) throws SAXException {
255: //Debug.println("END: " + tag);
256: try {
257: TagInstance t = (TagInstance) tagStack.tail();
258: //Debug.println("t = " + t);
259: if (t != null && t.getTagName().equals(tag)) {
260: tagStack.popBack();
261: t.doEndTag();
262: } else {
263: CharArrayWriter cw = new CharArrayWriter();
264: cw.write("</");
265: cw.write(tag);
266: cw.write(">");
267: char[] ch = cw.toCharArray();
268: characters(ch, 0, ch.length);
269: }
270: } catch (Exception e) {
271: Debug.print(e);
272: throw new SAXException(e.toString());
273: }
274: }
275:
276: /**
277: * Entity resolver interface.
278: */
279: public InputSource resolveEntity(String publicId, String systemId)
280: throws IOException {
281: String name = null;
282: if (!systemId.startsWith("/")) {
283: name = jsp.getPackageName() + "/" + systemId;
284: }
285: InputStream in = context.getResourceAsStream(name);
286: InputSource is = null;
287: if (is != null) {
288: BufferedInputStream bin = new BufferedInputStream(in);
289: InputStreamReader r = new InputStreamReader(bin);
290: is = new InputSource(r);
291: }
292: return is;
293: }
294: }
|