KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > quadcap > http > servlets > jsp > JspServlet


1 package com.quadcap.http.servlets.jsp;
2
3 /* Copyright 1999 - 2003 Quadcap Software. All rights reserved.
4  *
5  * This software is distributed under the Quadcap Free Software License.
6  * This software may be used or modified for any purpose, personal or
7  * commercial. Open Source redistributions are permitted. Commercial
8  * redistribution of larger works derived from, or works which bundle
9  * this software requires a "Commercial Redistribution License"; see
10  * http://www.quadcap.com/purchase.
11  *
12  * Redistributions qualify as "Open Source" under one of the following terms:
13  *
14  * Redistributions are made at no charge beyond the reasonable cost of
15  * materials and delivery.
16  *
17  * Redistributions are accompanied by a copy of the Source Code or by an
18  * irrevocable offer to provide a copy of the Source Code for up to three
19  * years at the cost of materials and delivery. Such redistributions
20  * must allow further use, modification, and redistribution of the Source
21  * Code under substantially the same terms as this license.
22  *
23  * Redistributions of source code must retain the copyright notices as they
24  * appear in each source code file, these license terms, and the
25  * disclaimer/limitation of liability set forth as paragraph 6 below.
26  *
27  * Redistributions in binary form must reproduce this Copyright Notice,
28  * these license terms, and the disclaimer/limitation of liability set
29  * forth as paragraph 6 below, in the documentation and/or other materials
30  * provided with the distribution.
31  *
32  * The Software is provided on an "AS IS" basis. No warranty is
33  * provided that the Software is free of defects, or fit for a
34  * particular purpose.
35  *
36  * Limitation of Liability. Quadcap Software shall not be liable
37  * for any damages suffered by the Licensee or any third party resulting
38  * from use of the Software.
39  */

40
41 import java.io.BufferedOutputStream JavaDoc;
42 import java.io.BufferedReader JavaDoc;
43 import java.io.ByteArrayInputStream JavaDoc;
44 import java.io.DataInputStream JavaDoc;
45 import java.io.File JavaDoc;
46 import java.io.FileOutputStream JavaDoc;
47 import java.io.FileReader JavaDoc;
48 import java.io.IOException JavaDoc;
49 import java.io.LineNumberReader JavaDoc;
50 import java.io.PrintWriter JavaDoc;
51 import java.io.Reader JavaDoc;
52
53 import java.util.Hashtable JavaDoc;
54 import java.util.Properties JavaDoc;
55 import java.util.Vector JavaDoc;
56
57 import javax.servlet.Servlet JavaDoc;
58 import javax.servlet.ServletConfig JavaDoc;
59 import javax.servlet.ServletContext JavaDoc;
60 import javax.servlet.ServletException JavaDoc;
61 import javax.servlet.SingleThreadModel JavaDoc;
62
63 import javax.servlet.http.HttpServlet JavaDoc;
64 import javax.servlet.http.HttpServletRequest JavaDoc;
65 import javax.servlet.http.HttpServletResponse JavaDoc;
66
67 import javax.servlet.jsp.HttpJspPage JavaDoc;
68
69 import org.xml.sax.DocumentHandler JavaDoc;
70 import org.xml.sax.EntityResolver JavaDoc;
71 import org.xml.sax.InputSource JavaDoc;
72 import org.xml.sax.SAXException JavaDoc;
73
74 import com.quadcap.io.HtmlifyWriter;
75 import com.quadcap.io.NullOutputStream;
76
77 import com.quadcap.util.ConfigString;
78 import com.quadcap.util.Debug;
79 import com.quadcap.util.Util;
80
81 /**
82  * "The" JSP Servlet.
83  *
84  * @author Stan Bailes
85  */

86 public class JspServlet extends HttpServlet JavaDoc {
87     ClassLoader JavaDoc parentClassLoader;
88     ServletConfig JavaDoc config;
89     ServletContext JavaDoc context;
90     File JavaDoc repository;
91     Hashtable JavaDoc pages = new Hashtable JavaDoc();
92     JspClassLoader classLoader = null;
93     JavaCompiler javaCompiler = null;
94
95     public void init(ServletConfig JavaDoc config) throws ServletException JavaDoc {
96     new JspFactory();
97         super.init(config);
98     this.config = config;
99         this.context = config.getServletContext();
100     this.repository = (File JavaDoc)context.getAttribute("repository");
101
102         // For windows, the classpath needs to be quoted. So we invent
103
// 'wq', the 'windows quote' variable. sheesh.
104
Properties JavaDoc p = new Properties JavaDoc();
105         p.putAll(System.getProperties());
106         if (File.pathSeparatorChar == ';') {
107             p.put("wq", "\"");
108         } else {
109             p.put("wq", "");
110         }
111
112         String JavaDoc jc = config.getInitParameter("compiler");
113         if (jc == null || jc.trim().length() == 0) {
114             /*{com.quadcap.util.Config-vars.xml-2000}
115              * <config-var>
116              * <config-name>jsp.compiler</config-name>
117              * <config-dflt>jikes</config-dflt>
118              * <config-desc>Choices are 'jikes' or 'javac'.</config-desc>
119              * </config-var>
120              */

121             ConfigString cs = ConfigString.find("jsp.compiler", "jikes");
122             if (cs != null) jc = cs.toString();
123         }
124         this.javaCompiler = null;
125         if (jc.equalsIgnoreCase("dynamic")) {
126             // jikes if possible, otherwise fallback to javac
127
if (Util.execCommand("jikes -v",
128                                  new NullOutputStream(),
129                                  new NullOutputStream()) == -1) {
130                 jc = "javac";
131             } else {
132                 jc = "jikes";
133             }
134         }
135
136         if (jc.equalsIgnoreCase("javac")) {
137             this.javaCompiler = new Javac();
138         } else {
139             this.javaCompiler = new JavaCompiler();
140         }
141         this.javaCompiler.init(getServletContext(),
142                                repository,
143                                config.getInitParameter("compile." + jc),
144                                p);
145         this.parentClassLoader =
146             (ClassLoader JavaDoc)context.getAttribute("com.quadcap.classLoader");
147         if (parentClassLoader == null) {
148             this.parentClassLoader = this.getClass().getClassLoader();
149         }
150     refreshClassLoader();
151     }
152
153     void refreshClassLoader() {
154     this.classLoader = new JspClassLoader(parentClassLoader, repository);
155     }
156
157     protected void service(HttpServletRequest JavaDoc request,
158                            HttpServletResponse JavaDoc response)
159     throws IOException JavaDoc, ServletException JavaDoc
160     {
161     String JavaDoc name = request.getServletPath();
162         response.setContentType("text/html");
163         response.setHeader("Expires", "0");
164
165     JspPage page = null;
166     try {
167         page = getJspPageForName(name, response);
168     } catch (JspException e) {
169         if (e.getReportedError()) return;
170         throw e;
171     }
172         if (page == null) {
173             response.sendError(HttpServletResponse.SC_NOT_FOUND,
174                                "Not found: " + request.getRequestURI());
175             return;
176         }
177     if (page instanceof SingleThreadModel JavaDoc) {
178         synchronized (page) {
179         page._jspService(request, response);
180         }
181     } else {
182         page._jspService(request, response);
183     }
184     }
185
186     JspPage getJspPageForName(String JavaDoc name, HttpServletResponse JavaDoc response)
187     throws IOException JavaDoc, ServletException JavaDoc
188     {
189     JspObject jsp = (JspObject)pages.get(name);
190     boolean found = jsp != null;
191     if (jsp == null) {
192             if (context.getResource(name) == null) {
193                 return null;
194             }
195         synchronized (this) {
196         jsp = new JspObject(config.getServletContext(),
197                     repository, name);
198         }
199     }
200         JspPage p = jsp.getJspPage();
201     if (p == null || jsp.needRecompile()) {
202         if (p != null) {
203         unload(p);
204         jsp.setJspPage(null);
205         }
206         loadJspPage(jsp, response);
207     }
208     if (!found) pages.put(name, jsp);
209     return jsp.getJspPage();
210     }
211
212     void unload(JspPage page) {
213     page.jspDestroy();
214     refreshClassLoader();
215     }
216
217     static Object JavaDoc compileLock = new Object JavaDoc();
218     
219     JspPage loadJspPage(JspObject jsp, HttpServletResponse JavaDoc response)
220     throws IOException JavaDoc, ServletException JavaDoc, JspException
221     {
222     if (Trace.level() > 1) {
223         Debug.println("loadPage(" + jsp.getFullClassName() + ")");
224     }
225     JspPage page = null;
226     try {
227         if (jsp.needRecompile()) {
228                 synchronized (compileLock) {
229                     compilePage(jsp, response);
230                 }
231             }
232         Class JavaDoc jspClass = classLoader.loadClass(jsp.getFullClassName());
233         page = (JspPage)jspClass.newInstance();
234         page.init(getServletConfig());
235         page.jspInit();
236         jsp.setJspPage(page);
237     } catch (JspException e) {
238         throw e;
239     } catch (Throwable JavaDoc t) {
240         Debug.print(t);
241         throw new ServletException JavaDoc(t.toString());
242     }
243     return page;
244     }
245
246     void compilePage(JspObject jsp, HttpServletResponse JavaDoc response)
247     throws IOException JavaDoc, ServletException JavaDoc, ClassNotFoundException JavaDoc
248     {
249     translatePage(jsp);
250     try {
251             javaCompiler.compile(jsp.getJavaFile(), jsp.getClassFile());
252     } catch (JspException e) {
253         File JavaDoc javaFile = jsp.getJavaFile();
254         FileReader JavaDoc jr = new FileReader JavaDoc(javaFile);
255         LineNumberReader JavaDoc r = new LineNumberReader JavaDoc(jr);
256         PrintWriter JavaDoc pw = response.getWriter();
257         HtmlifyWriter w = new HtmlifyWriter(pw);
258         ByteArrayInputStream JavaDoc bis = new ByteArrayInputStream JavaDoc(e.toString().getBytes());
259         DataInputStream JavaDoc dis = new DataInputStream JavaDoc(bis);
260         boolean done = false;
261         int fl = -1, ll = -1, fc = -1, lc = -1;
262         int linep = 0;
263         String JavaDoc line = null;
264         pw.println("<html><head><title>Compile Error</title>");
265         pw.println("<style type=\"text/css\">");
266         pw.println(".errMsg {");
267         pw.println(" background-color: #202020;");
268         pw.println(" color: #ffff00;");
269         pw.println(" font-size: bigger;");
270         pw.println("}");
271         pw.println(".errText {");
272         pw.println(" background-color: #80a0c0;");
273         pw.println(" color: #000000;");
274         pw.println(" font-size: bigger;");
275         pw.println("}");
276         pw.println("</style>");
277         pw.println("</head>");
278         pw.println("<body bgcolor=#a0c0e0 text=#000000>");
279         pw.print("<h2>Compile Error for ");
280         pw.print(jsp.getName());
281         pw.println("</h2><pre>");
282         String JavaDoc errMsg = "";
283         
284         while (!done) {
285         if (fl < 0) {
286             String JavaDoc errLine = dis.readLine();
287             Debug.println("errLine = " + errLine);
288             if (errLine != null) {
289             try {
290                 String JavaDoc eline = errLine;
291                 int idx = errLine.indexOf(".java:");
292                 if (idx > 0) eline = errLine.substring(idx);
293                 Vector JavaDoc v = Util.split(eline, ':');
294                 for (int i = 0; i < v.size(); i++) {
295                 Debug.println("" + i + ": " + v.elementAt(i));
296                 }
297                 if (v.size() >= 5) {
298                 fl = Integer.parseInt(v.elementAt(1).toString());
299                 fc = Integer.parseInt(v.elementAt(2).toString());
300                 ll = Integer.parseInt(v.elementAt(3).toString());
301                 lc = Integer.parseInt(v.elementAt(4).toString());
302                 if (v.size() > 6) {
303                     errMsg = v.elementAt(6).toString();
304                 }
305                 }
306             } catch (Exception JavaDoc ce) {
307                 Debug.print(ce);
308                 ll = fl; lc = fc;
309                 errMsg = errLine;
310             }
311             } else {
312             fl = fc = ll = lc = -1;
313             }
314         }
315         while (fl < 0 || r.getLineNumber() < fl) {
316             line = r.readLine();
317             if (r.getLineNumber() == fl) break;
318             if (line == null) {
319             done = true;
320             break;
321             }
322             else {
323             w.println(line);
324             linep = r.getLineNumber();
325             }
326         }
327         if (done) break;
328         if (fl >= 0) {
329             if (linep < r.getLineNumber()) {
330             w.print(substring(line, 0, fc-1));
331             pw.print("<b><span class=\"errText\">");
332             if (ll == r.getLineNumber()) {
333                 w.print(substring(line, fc-1, lc));
334                 pw.print("</span></b>");
335                 w.println(substring(line, lc));
336             } else {
337                 w.println(substring(line, fc-1));
338                 while (ll < r.getLineNumber()) {
339                 line = r.readLine();
340                 if (line == null) {
341                     pw.println("</span></b>");
342                     done = true;
343                     break;
344                 }
345                 }
346                 if (done) break;
347                 w.print(substring(line, 0, lc));
348                 pw.print("</span></b>");
349                 w.println(substring(line, lc));
350             }
351             linep = r.getLineNumber();
352             }
353             fl = fc = ll = lc = -1;
354             pw.print("<i><span class=\"errMsg\">");
355             w.println(errMsg);
356             pw.println("</span></i>");
357         }
358         }
359         pw.println("</pre></body></html>");
360         e.setReportedError(true);
361         throw e;
362     }
363     }
364
365     static String JavaDoc substring(String JavaDoc s, int f) {
366     int len = s.length();
367     if (f < 0) f = 0;
368     if (f >= len) f = len-1;
369     return s.substring(f);
370     }
371
372     static String JavaDoc substring(String JavaDoc s, int f, int t) {
373     int len = s.length();
374     if (f < 0) f = 0;
375     if (f >= len) f = len-1;
376     if (t < 0) t = 0;
377     if (t >= len) t = len-1;
378     return s.substring(f, t);
379     }
380
381     void translatePage(JspObject jsp) throws IOException JavaDoc, ServletException JavaDoc {
382     File JavaDoc javaFile = jsp.getJavaFile();
383
384     if (javaFile.exists()) javaFile.delete();
385
386     FileOutputStream JavaDoc jos = new FileOutputStream JavaDoc(javaFile);
387     BufferedOutputStream JavaDoc bos = new BufferedOutputStream JavaDoc(jos);
388     PrintWriter JavaDoc w = new PrintWriter JavaDoc(bos);
389
390         try {
391             Reader JavaDoc r = jsp.getJspReader();
392
393             try {
394                 compileJsp(jsp, r, w);
395             } finally {
396                 r.close();
397             }
398         } finally {
399             w.close();
400         }
401     }
402
403     void compileJsp(JspObject jsp, Reader JavaDoc in, PrintWriter JavaDoc w)
404     throws IOException JavaDoc, ServletException JavaDoc
405     {
406     try {
407         JspParser p = new JspParser();
408         JspHandler h = new JspHandler(context, p, w, jsp);
409         p.setDocumentHandler(h);
410         p.setJspHandler(h);
411         p.setEntityResolver(h);
412         p.parse(new InputSource JavaDoc(in));
413     } catch (SAXException JavaDoc e) {
414         throw new ServletException JavaDoc(e.toString());
415     }
416     }
417
418     public void destroy() {
419         super.destroy();
420     }
421
422     public String JavaDoc getServletInfo() {
423         return "Quadcap Jsp Servlet";
424     }
425 }
426
Popular Tags