00001
package com.quadcap.http.servlets.jsp;
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
import java.io.BufferedOutputStream;
00042
import java.io.BufferedReader;
00043
import java.io.ByteArrayInputStream;
00044
import java.io.DataInputStream;
00045
import java.io.File;
00046
import java.io.FileOutputStream;
00047
import java.io.FileReader;
00048
import java.io.IOException;
00049
import java.io.LineNumberReader;
00050
import java.io.PrintWriter;
00051
import java.io.Reader;
00052
00053
import java.util.Hashtable;
00054
import java.util.Properties;
00055
import java.util.Vector;
00056
00057
import javax.servlet.Servlet;
00058
import javax.servlet.ServletConfig;
00059
import javax.servlet.ServletContext;
00060
import javax.servlet.ServletException;
00061
import javax.servlet.SingleThreadModel;
00062
00063
import javax.servlet.http.HttpServlet;
00064
import javax.servlet.http.HttpServletRequest;
00065
import javax.servlet.http.HttpServletResponse;
00066
00067
import javax.servlet.jsp.HttpJspPage;
00068
00069
import org.xml.sax.DocumentHandler;
00070
import org.xml.sax.EntityResolver;
00071
import org.xml.sax.InputSource;
00072
import org.xml.sax.SAXException;
00073
00074
import com.quadcap.io.HtmlifyWriter;
00075
import com.quadcap.io.NullOutputStream;
00076
00077
import com.quadcap.util.ConfigString;
00078
import com.quadcap.util.Debug;
00079
import com.quadcap.util.Util;
00080
00081
00082
00083
00084
00085
00086 public class JspServlet extends HttpServlet {
00087 ClassLoader
parentClassLoader;
00088 ServletConfig
config;
00089 ServletContext
context;
00090 File
repository;
00091 Hashtable
pages =
new Hashtable();
00092 JspClassLoader classLoader = null;
00093 JavaCompiler javaCompiler = null;
00094
00095 public void init(ServletConfig config)
throws ServletException {
00096
new JspFactory();
00097 super.init(
config);
00098
this.config =
config;
00099
this.context =
config.getServletContext();
00100
this.repository = (File)
context.getAttribute(
"repository");
00101
00102
00103
00104 Properties p =
new Properties();
00105 p.putAll(System.getProperties());
00106
if (File.pathSeparatorChar ==
';') {
00107 p.put(
"wq",
"\"");
00108 }
else {
00109 p.put(
"wq",
"");
00110 }
00111
00112 String jc =
config.getInitParameter(
"compiler");
00113
if (jc == null || jc.trim().length() == 0) {
00114
00115
00116
00117
00118
00119
00120
00121
ConfigString cs =
ConfigString.find(
"jsp.compiler",
"jikes");
00122
if (cs != null) jc = cs.
toString();
00123 }
00124
this.javaCompiler = null;
00125
if (jc.equalsIgnoreCase(
"dynamic")) {
00126
00127
if (
Util.execCommand(
"jikes -v",
00128
new NullOutputStream(),
00129
new NullOutputStream()) == -1) {
00130 jc =
"javac";
00131 }
else {
00132 jc =
"jikes";
00133 }
00134 }
00135
00136
if (jc.equalsIgnoreCase(
"javac")) {
00137
this.javaCompiler =
new Javac();
00138 }
else {
00139
this.javaCompiler =
new JavaCompiler();
00140 }
00141
this.javaCompiler.init(getServletContext(),
00142
repository,
00143
config.getInitParameter(
"compile." + jc),
00144 p);
00145
this.parentClassLoader =
00146 (ClassLoader)
context.getAttribute(
"com.quadcap.classLoader");
00147
if (
parentClassLoader == null) {
00148
this.parentClassLoader =
this.getClass().getClassLoader();
00149 }
00150
refreshClassLoader();
00151 }
00152
00153 void refreshClassLoader() {
00154
this.classLoader =
new JspClassLoader(
parentClassLoader,
repository);
00155 }
00156
00157 protected void service(HttpServletRequest request,
00158 HttpServletResponse response)
00159
throws IOException, ServletException
00160 {
00161 String name = request.getServletPath();
00162 response.setContentType(
"text/html");
00163 response.setHeader(
"Expires",
"0");
00164
00165
JspPage page = null;
00166
try {
00167 page =
getJspPageForName(name, response);
00168 }
catch (
JspException e) {
00169
if (e.getReportedError())
return;
00170
throw e;
00171 }
00172
if (page == null) {
00173 response.sendError(HttpServletResponse.SC_NOT_FOUND,
00174
"Not found: " + request.getRequestURI());
00175
return;
00176 }
00177
if (page instanceof SingleThreadModel) {
00178
synchronized (page) {
00179 page.
_jspService(request, response);
00180 }
00181 }
else {
00182 page.
_jspService(request, response);
00183 }
00184 }
00185
00186 JspPage getJspPageForName(String name, HttpServletResponse response)
00187
throws IOException, ServletException
00188 {
00189
JspObject jsp = (
JspObject)
pages.get(name);
00190
boolean found = jsp != null;
00191
if (jsp == null) {
00192
if (
context.getResource(name) == null) {
00193
return null;
00194 }
00195
synchronized (
this) {
00196 jsp =
new JspObject(
config.getServletContext(),
00197
repository, name);
00198 }
00199 }
00200
JspPage p = jsp.
getJspPage();
00201
if (p == null || jsp.
needRecompile()) {
00202
if (p != null) {
00203
unload(p);
00204 jsp.
setJspPage(null);
00205 }
00206
loadJspPage(jsp, response);
00207 }
00208
if (!found)
pages.put(name, jsp);
00209
return jsp.
getJspPage();
00210 }
00211
00212 void unload(
JspPage page) {
00213 page.
jspDestroy();
00214
refreshClassLoader();
00215 }
00216
00217 static Object
compileLock =
new Object();
00218
00219 JspPage loadJspPage(
JspObject jsp, HttpServletResponse response)
00220
throws IOException, ServletException,
JspException
00221 {
00222
if (
Trace.level() > 1) {
00223
Debug.println(
"loadPage(" + jsp.getFullClassName() +
")");
00224 }
00225
JspPage page = null;
00226
try {
00227
if (jsp.needRecompile()) {
00228
synchronized (
compileLock) {
00229
compilePage(jsp, response);
00230 }
00231 }
00232 Class jspClass =
classLoader.
loadClass(jsp.getFullClassName());
00233 page = (
JspPage)jspClass.newInstance();
00234 page.
init(getServletConfig());
00235 page.
jspInit();
00236 jsp.setJspPage(page);
00237 }
catch (
JspException e) {
00238
throw e;
00239 }
catch (Throwable t) {
00240
Debug.print(t);
00241
throw new ServletException(t.toString());
00242 }
00243
return page;
00244 }
00245
00246 void compilePage(
JspObject jsp, HttpServletResponse response)
00247
throws IOException, ServletException, ClassNotFoundException
00248 {
00249
translatePage(jsp);
00250
try {
00251
javaCompiler.
compile(jsp.getJavaFile(), jsp.getClassFile());
00252 }
catch (
JspException e) {
00253 File javaFile = jsp.getJavaFile();
00254 FileReader jr =
new FileReader(javaFile);
00255 LineNumberReader r =
new LineNumberReader(jr);
00256 PrintWriter pw = response.getWriter();
00257
HtmlifyWriter w =
new HtmlifyWriter(pw);
00258 ByteArrayInputStream bis =
new ByteArrayInputStream(e.toString().getBytes());
00259 DataInputStream dis =
new DataInputStream(bis);
00260
boolean done =
false;
00261
int fl = -1, ll = -1, fc = -1, lc = -1;
00262
int linep = 0;
00263 String line = null;
00264 pw.println(
"<html><head><title>Compile Error</title>");
00265 pw.println(
"<style type=\"text/css\">");
00266 pw.println(
".errMsg {");
00267 pw.println(
" background-color: #202020;");
00268 pw.println(
" color: #ffff00;");
00269 pw.println(
" font-size: bigger;");
00270 pw.println(
"}");
00271 pw.println(
".errText {");
00272 pw.println(
" background-color: #80a0c0;");
00273 pw.println(
" color: #000000;");
00274 pw.println(
" font-size: bigger;");
00275 pw.println(
"}");
00276 pw.println(
"</style>");
00277 pw.println(
"</head>");
00278 pw.println(
"<body bgcolor=#a0c0e0 text=#000000>");
00279 pw.print(
"<h2>Compile Error for ");
00280 pw.print(jsp.getName());
00281 pw.println(
"</h2><pre>");
00282 String errMsg =
"";
00283
00284
while (!done) {
00285
if (fl < 0) {
00286 String errLine = dis.readLine();
00287
Debug.println(
"errLine = " + errLine);
00288
if (errLine != null) {
00289
try {
00290 String eline = errLine;
00291
int idx = errLine.indexOf(
".java:");
00292
if (idx > 0) eline = errLine.substring(idx);
00293 Vector v =
Util.split(eline,
':');
00294
for (
int i = 0; i < v.size(); i++) {
00295
Debug.println(
"" + i +
": " + v.elementAt(i));
00296 }
00297
if (v.size() >= 5) {
00298 fl = Integer.parseInt(v.elementAt(1).toString());
00299 fc = Integer.parseInt(v.elementAt(2).toString());
00300 ll = Integer.parseInt(v.elementAt(3).toString());
00301 lc = Integer.parseInt(v.elementAt(4).toString());
00302
if (v.size() > 6) {
00303 errMsg = v.elementAt(6).toString();
00304 }
00305 }
00306 }
catch (Exception ce) {
00307
Debug.print(ce);
00308 ll = fl; lc = fc;
00309 errMsg = errLine;
00310 }
00311 }
else {
00312 fl = fc = ll = lc = -1;
00313 }
00314 }
00315
while (fl < 0 || r.getLineNumber() < fl) {
00316 line = r.readLine();
00317
if (r.getLineNumber() == fl)
break;
00318
if (line == null) {
00319 done =
true;
00320
break;
00321 }
00322
else {
00323 w.
println(line);
00324 linep = r.getLineNumber();
00325 }
00326 }
00327
if (done)
break;
00328
if (fl >= 0) {
00329
if (linep < r.getLineNumber()) {
00330 w.
print(
substring(line, 0, fc-1));
00331 pw.print(
"<b><span class=\"errText\">");
00332
if (ll == r.getLineNumber()) {
00333 w.
print(
substring(line, fc-1, lc));
00334 pw.print(
"</span></b>");
00335 w.
println(
substring(line, lc));
00336 }
else {
00337 w.
println(
substring(line, fc-1));
00338
while (ll < r.getLineNumber()) {
00339 line = r.readLine();
00340
if (line == null) {
00341 pw.println(
"</span></b>");
00342 done =
true;
00343
break;
00344 }
00345 }
00346
if (done)
break;
00347 w.
print(
substring(line, 0, lc));
00348 pw.print(
"</span></b>");
00349 w.
println(
substring(line, lc));
00350 }
00351 linep = r.getLineNumber();
00352 }
00353 fl = fc = ll = lc = -1;
00354 pw.print(
"<i><span class=\"errMsg\">");
00355 w.
println(errMsg);
00356 pw.println(
"</span></i>");
00357 }
00358 }
00359 pw.println(
"</pre></body></html>");
00360 e.setReportedError(
true);
00361
throw e;
00362 }
00363 }
00364
00365 static String
substring(String s,
int f) {
00366
int len = s.length();
00367
if (f < 0) f = 0;
00368
if (f >= len) f = len-1;
00369
return s.substring(f);
00370 }
00371
00372 static String substring(String s,
int f,
int t) {
00373
int len = s.length();
00374
if (f < 0) f = 0;
00375
if (f >= len) f = len-1;
00376
if (t < 0) t = 0;
00377
if (t >= len) t = len-1;
00378
return s.substring(f, t);
00379 }
00380
00381 void translatePage(
JspObject jsp)
throws IOException, ServletException {
00382 File javaFile = jsp.getJavaFile();
00383
00384
if (javaFile.exists()) javaFile.delete();
00385
00386 FileOutputStream jos =
new FileOutputStream(javaFile);
00387 BufferedOutputStream bos =
new BufferedOutputStream(jos);
00388 PrintWriter w =
new PrintWriter(bos);
00389
00390
try {
00391 Reader r = jsp.getJspReader();
00392
00393
try {
00394
compileJsp(jsp, r, w);
00395 } finally {
00396 r.close();
00397 }
00398 } finally {
00399 w.close();
00400 }
00401 }
00402
00403 void compileJsp(
JspObject jsp, Reader in, PrintWriter w)
00404
throws IOException, ServletException
00405 {
00406
try {
00407
JspParser p =
new JspParser();
00408
JspHandler h =
new JspHandler(
context, p, w, jsp);
00409 p.
setDocumentHandler(h);
00410 p.
setJspHandler(h);
00411 p.
setEntityResolver(h);
00414
throw new ServletException(e.toString());
00415 }
00416 }
00417
00418 public void destroy() {
00419 super.destroy();
00420 }
00421
00422 public String
getServletInfo() {
00423
return "Quadcap Jsp Servlet";
00424 }
00425 }