- From: Yves Lafon via cvs-syncmail <cvsmail@w3.org>
- Date: Fri, 22 Jul 2005 09:45:20 +0000
- To: www-validator-cvs@w3.org
Update of /sources/public/2002/css-validator/org/w3c/css/servlet
In directory hutz:/tmp/cvs-serv22891/servlet
Modified Files:
CssValidator.java
Log Message:
Added code for error Handling (Jean-Guilhem Rouel)
Index: CssValidator.java
===================================================================
RCS file: /sources/public/2002/css-validator/org/w3c/css/servlet/CssValidator.java,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- CssValidator.java 12 Jul 2005 16:08:09 -0000 1.17
+++ CssValidator.java 22 Jul 2005 09:45:18 -0000 1.18
@@ -32,6 +32,8 @@
import org.w3c.css.css.StyleReportFactory;
import org.w3c.css.css.StyleSheet;
import org.w3c.css.css.StyleSheetParser;
+import org.w3c.css.error.ErrorReport;
+import org.w3c.css.error.ErrorReportFactory;
import org.w3c.css.util.ApplContext;
import org.w3c.css.util.Codecs;
import org.w3c.css.util.FakeFile;
@@ -40,11 +42,12 @@
import org.w3c.css.util.Utf8Properties;
import org.w3c.css.util.Util;
import org.w3c.www.mime.MimeType;
+import org.w3c.www.mime.MimeTypeFormatException;
import org.xml.sax.SAXParseException;
/**
* This class is a servlet to use the validator.
- *
+ *
* @version $Revision$
*/
public final class CssValidator extends HttpServlet {
@@ -64,7 +67,7 @@
final static String soap12 = "application/soap+xml";
final static String server_name = "Jigsaw/2.2.2 "
- + "W3C_CSS_Validator_JFouffa/2.0";
+ + "W3C_CSS_Validator_JFouffa/2.0";
/**
* Create a new CssValidator.
@@ -85,7 +88,7 @@
* ServletConfig object themselves. If an implementor decides to store the
* ServletConfig object in a different location, then the getServletConfig
* method must also be overridden.
- *
+ *
* <P>
* <DL>
* <STRONG>Init parameters:</STRONG>
@@ -101,7 +104,7 @@
* <DD><code>html</code> if the user have an HTML input or
* <code>xml</code> otherwise. <strong>deprecated</strong>
* </DL>
- *
+ *
* @param config
* servlet configuration information.
* @exception ServletException
@@ -119,10 +122,10 @@
// debug.
Util.onDebug = config.getInitParameter("debug").equals("true");
System.err.println("RUN IN DEBUG MODE: "
- + config.getInitParameter("debug").equals("true"));
+ + config.getInitParameter("debug").equals("true"));
} else if (Util.onDebug) {
System.err.println("RUN IN DEBUG MODE"+
- " but activated outside the servlet");
+ " but activated outside the servlet");
}
if ((config.getInitParameter("import") != null)
@@ -138,7 +141,7 @@
return new PrintWriter(new OutputStreamWriter(os, encoding));
} else {
return new PrintWriter(new OutputStreamWriter(os,
- Utf8Properties.ENCODING));
+ Utf8Properties.ENCODING));
}
}
@@ -155,11 +158,11 @@
* stored data should use some other HTTP method. (There have been cases of
* significant security breaches reported because web-based applications
* used GET inappropriately.)
- *
+ *
* <P>
* The GET operation is also expected to be <em>idempotent</em>, meaning
* that it can safely be repeated. This is not quite the same as being
- * safe, but in some common examples the requirements have the same result.
+ * safe, but in some common examples the requirements have the same result.
* For example, repeating queries is both safe and idempotent
* (unless payment is required!), but buying something or modifying data
* is neither safe nor idempotent.
@@ -180,7 +183,7 @@
* <DT>input
* <DD>HTML if the user have an HTML input or XML otherwise.
* </DL>
- *
+ *
* @param req
* encapsulates the request to the servlet.
* @param resp
@@ -198,14 +201,18 @@
int warningLevel = 2;
CssParser parser = null;
+ ApplContext ac = new ApplContext(req.getHeader("Accept-Language"));
+ ac.setContentEncoding(req.getHeader("Accept-Charset"));
+ String output = req.getParameter("output");
+
String uri = null;
try {
uri = req.getParameter("uri"); // null if the parameter does not
// exist
} catch (Exception ex) {
// pb in URI decoding (bad escaping, most probably)
- handleError(res, "No file", new IOException(
- "Invalid escape sequence in URI"));
+ handleError(res, ac, output, "No file", new IOException(
+ "Invalid escape sequence in URI"), false);
}
String text = null;
try {
@@ -214,17 +221,15 @@
// pb in URI decoding (bad escaping, most probably)
// not sure it will work here, as it may be catched by the first
// getParameter call
- handleError(res, "Invalid text", new IOException(
- "Invalid escape sequence in URI"));
+ handleError(res, ac, output, "Invalid text", new IOException(
+ "Invalid escape sequence in URI"), false);
}
- String output = req.getParameter("output");
+
String warning = req.getParameter("warning");
String error = req.getParameter("error");
String profile = req.getParameter("profile");
String usermedium = req.getParameter("usermedium");
- ApplContext ac = new ApplContext(req.getHeader("Accept-Language"));
- ac.setContentEncoding(req.getHeader("Accept-Charset"));
-
+
String credential = req.getHeader("Authorization");
if ((credential != null) && (credential.length() > 1)) {
ac.setCredential(credential);
@@ -274,10 +279,10 @@
// verify the request
if ((uri == null) && (text == null)) {
// res.sendError(res.SC_BAD_REQUEST,
- // "You have send an invalid request.");
- handleError(res, "No file",
- new IOException(
- ac.getMsg().getServletString("invalid-request")));
+ // "You have send an invalid request.");
+ handleError(res, ac, output, "No file",
+ new IOException(ac.getMsg().getServletString("invalid-request")),
+ false);
return;
}
@@ -308,8 +313,8 @@
} else {
Util.verbose("TEXTAREA Input");
}
- // verbose("From " + req.getRemoteHost() +
- // " (" + req.getRemoteAddr() + ") at " + (new Date()) );
+ // verbose("From " + req.getRemoteHost() +
+ // " (" + req.getRemoteAddr() + ") at " + (new Date()) );
if (uri != null) {
// HTML document
@@ -329,7 +334,7 @@
res.setHeader("WWW-Authenticate", pex.getMessage());
res.sendError(HttpServletResponse.SC_UNAUTHORIZED);
} catch (Exception e) {
- handleError(res, uri, e);
+ handleError(res, ac, output, uri, e, true);
}
} else {
Util.verbose("- TextArea Data -");
@@ -340,17 +345,15 @@
try {
parser.parseStyleElement(ac,
- new ByteArrayInputStream(text.getBytes())
- , null
- , usermedium
- , new URL("file://localhost/TextArea")
- , 0);
-
- handleRequest(ac, res, "file://localhost/TextArea",
- parser.getStyleSheet(), output, warningLevel,
- errorReport);
+ new ByteArrayInputStream(text.getBytes()),
+ null, usermedium,
+ new URL("file://localhost/TextArea"), 0);
+
+ handleRequest(ac, res, "file://localhost/TextArea",
+ parser.getStyleSheet(), output, warningLevel,
+ errorReport);
} catch (Exception e) {
- handleError(res, "TextArea", e);
+ handleError(res, ac, output, "TextArea", e, false);
}
}
Util.verbose("CssValidator: Request terminated.\n");
@@ -359,20 +362,20 @@
/**
* Performs the HTTP POST operation. An HTTP BAD_REQUEST error is reported
* if an error occurs. The headers that are set should include content type,
- * length, and encoding. Setting content length allows the servlet to take
- * advantage of HTTP "connection keep alive". If content length can not be
+ * length, and encoding. Setting content length allows the servlet to take
+ * advantage of HTTP "connection keep alive". If content length can not be
* set in advance, the performance penalties associated with not using keep
* alives will sometimes be avoided if the response entity fits in an
* internal buffer. The servlet implementor must write the headers before
* the response data because the headers can be flushed at any time after
* the data starts to be written.
- *
+ *
* <P>
* This method does not need to be either "safe" or "idempotent". Operations
* requested through POST could be ones for which users need to be held
* accountable. Specific examples including updating stored data or buying
* things online.
- *
+ *
* <P>
* <DL>
* <STRONG>Forms parameters:</STRONG>
@@ -383,7 +386,7 @@
* <DT>input
* <DD>HTML if the user have an HTML input or XML otherwise.
* </DL>
- *
+ *
* @param req
* encapsulates the request to the servlet
* @param resp
@@ -424,8 +427,8 @@
}
Util.verbose("\nCssValidator: Servlet request ");
- // verbose("From " + req.getRemoteHost() +
- // " (" + req.getRemoteAddr() + ") at " + (new Date()) );
+ // verbose("From " + req.getRemoteHost() +
+ // " (" + req.getRemoteAddr() + ") at " + (new Date()) );
Util.verbose("Content-length : " + req.getContentLength());
if (req.getContentType().trim().startsWith("multipart/form-data")) {
@@ -489,10 +492,11 @@
output = texthtml;
}
if (file == null || file.getSize() == 0) {
- // res.sendError(res.SC_BAD_REQUEST,
- // "You have send an invalid request");
- handleError(res, "No file",
- new IOException(ac.getMsg().getServletString("invalid-request")));
+ // res.sendError(res.SC_BAD_REQUEST,
+ // "You have send an invalid request");
+ handleError(res, ac, output, "No file",
+ new IOException(ac.getMsg().getServletString("invalid-request")),
+ false);
return;
}
@@ -520,59 +524,23 @@
try {
parser.parseStyleElement(ac, file.getInputStream(), null, null,
- new URL("file://localhost/" +
- file.getName()), 0);
+ new URL("file://localhost/" + file.getName()), 0);
handleRequest(ac, res, "file://localhost/" + file.getName(), parser
.getStyleSheet(), output, warningLevel, errorReport);
} catch (Exception e) {
- handleError(res, file.getName(), e);
+ handleError(res, ac, output, file.getName(), e, false);
}
Util.verbose("CssValidator: Request terminated.\n");
}
private void handleRequest(ApplContext ac, HttpServletResponse res,
- String title, StyleSheet styleSheet,
- String output, int warningLevel,
+ String title, StyleSheet styleSheet,
+ String output, int warningLevel,
boolean errorReport) throws Exception {
- // I don't want cache for the response (inhibits proxy)
- res.setHeader("Pragma", "no-cache"); // @@deprecated
- res.setHeader("Cache-Control", "no-cache");
- // Here is a little joke :-)
- // res.setHeader("Server", server_name);
-
- // set the content-type for the response
- MimeType outputMt = null;
- if (output.equals(texthtml)) {
- outputMt = MimeType.TEXT_HTML.getClone();
- } else if (output.equals("soap12")) {
- // invert the comments on the following two lines to activate
- // the soap Mime Type
- outputMt = new MimeType(soap12);
- //outputMt = MimeType.TEXT_PLAIN.getClone();
- } else {
- // Change this line if you want text/html output when incorrect
- // output is passed
- outputMt = MimeType.TEXT_PLAIN.getClone();
- }
-
- // ignore content encoding if output is SOAP
- if(output.equals("soap12")) {
- ac.setContentEncoding(null);
- }
-
- if (ac.getContentEncoding() != null) {
- outputMt.setParameter("charset", ac.getContentEncoding());
- }
- res.setContentType(outputMt.toString());
-
- if (ac.getContentLanguage() != null) {
- res.setHeader("Content-Language", ac.getContentLanguage());
- } else {
- res.setHeader("Content-Language", "en");
- }
+ buildHeader(ac, res, output);
if (styleSheet == null) {
throw new IOException(ac.getMsg().getServletString("process") + " "
@@ -591,15 +559,13 @@
styleSheet.findConflicts(ac);
StyleReport style = StyleReportFactory.getStyleReport(ac, title,
- styleSheet,
- output,
- warningLevel);
+ styleSheet, output, warningLevel);
if (!errorReport) {
style.desactivateError();
}
- PrintWriter out = getLocalPrintWriter(res.getOutputStream(),
- ac.getContentEncoding());
-
+ PrintWriter out = getLocalPrintWriter(res.getOutputStream(), ac
+ .getContentEncoding());
+
try {
style.print(out);
} finally {
@@ -607,80 +573,100 @@
}
}
- private void handleError(HttpServletResponse res,
- String title, Exception e) {
- System.err.println("[ERROR VALIDATOR] " + title);
- System.err.println(e.toString());
- e.printStackTrace();
-
+ /**
+ * Generates the response header
+ * @param ac
+ * @param res
+ * @param output
+ * @throws MimeTypeFormatException
+ */
+ private void buildHeader(ApplContext ac, HttpServletResponse res, String output) {
+
// I don't want cache for the response (inhibits proxy)
res.setHeader("Pragma", "no-cache"); // @@deprecated
res.setHeader("Cache-Control", "no-cache");
-
// Here is a little joke :-)
- res.setHeader("Server", server_name);
- res.setHeader("Content-Language", "en");
- res.setHeader("Content-Type", "text/html; charset=us-ascii");
- // res.setHeader("Content-Encoding", "us-ascii");
-
- PrintWriter out = null;
+ // res.setHeader("Server", server_name);
- try {
- out = getLocalPrintWriter(res.getOutputStream(), null);
- URL localURL = CssValidator.class.getResource("error.html");
- DataInputStream in = new DataInputStream(localURL.openStream());
+ if(output == null) {
+ output = new String(texthtml);
+ }
+
+ // set the content-type for the response
+ MimeType outputMt = null;
+ if (output.equals(texthtml)) {
+ outputMt = MimeType.TEXT_HTML.getClone();
+ } else if (output.equals("soap12")) {
+ // invert the comments on the following lines to (de)activate
+ // the soap Mime Type
try {
- while (true) {
- out.print((char) in.readUnsignedByte());
- }
- } catch (EOFException eof) {
- out.println("<h2>Target: " + Util.escapeHTML(title) + "</h2>");
- out.println("<div class=\"error\">");
- if (e instanceof IOException) {
- out.println("<p>I/O Error: ");
- out.println(Util.escapeHTML(e.getMessage()));
- } else if (e instanceof SAXParseException) {
- SAXParseException saxe = (SAXParseException) e;
- out.println("<p>Please, validate your XML document"
- + " first!</p>");
- if (saxe.getLineNumber() != -1) {
- out.print("<p>Line ");
- out.print(saxe.getLineNumber());
- out.println("</p>");
- }
- if (saxe.getColumnNumber() != -1) {
- out.print("<p>Column ");
- out.print(saxe.getColumnNumber());
- out.print("</p>\n");
- }
- out.println("<p>" + Util.escapeHTML(e.getMessage()));
- } else if (e instanceof NullPointerException) {
- out.println("<p>Oups! Internal error!</p><p>");
- e.printStackTrace();
- } else {
- out.println(e.toString());
- }
- out.println("</p></div>\n<hr />\n<p><img src='images/mwc"
- + "ss.gif' alt='made with CSS' /></p>\n<addres"
- + "s><a href='Email.html'>www-validator-css</a"
- + "></address>\n</body></html>");
- out.flush();
- /*
- * System.err.println("CSS Validator: request failed.");
- * e.printStackTrace();
- */
+ outputMt = new MimeType(soap12);
}
- } catch (Exception unknown) {
- if (out != null) {
- out.println("org.w3c.css.servlet.CssValidator: couldn't "
- + "load error file");
- out.flush();
+ catch (MimeTypeFormatException e) {
+ outputMt = MimeType.TEXT_PLAIN.getClone();
}
- unknown.printStackTrace();
- } finally {
- if (out != null) {
- out.close();
+ //outputMt = MimeType.TEXT_PLAIN.getClone();
+ } else {
+ // Change this line if you want text/html output when incorrect
+ // output is passed
+ outputMt = MimeType.TEXT_PLAIN.getClone();
+ }
+
+ if(ac != null) {
+ // ignore content encoding if output is SOAP
+ if(output.equals("soap12")) {
+ ac.setContentEncoding(null);
+ }
+
+ if (ac.getContentEncoding() != null) {
+ outputMt.setParameter("charset", ac.getContentEncoding());
}
+ res.setContentType(outputMt.toString());
+
+ if (ac.getContentLanguage() != null) {
+ res.setHeader("Content-Language", ac.getContentLanguage());
+ } else {
+ res.setHeader("Content-Language", "en");
+ }
+ }
+ else {
+ res.setHeader("Content-Language", "en");
+ res.setHeader("charset", Utf8Properties.ENCODING);
+ }
+ }
+
+ private void handleError(HttpServletResponse res, ApplContext ac,
+ String output, String title, Exception e, boolean validURI)
+ throws IOException {
+
+ System.err.println("[ERROR VALIDATOR] " + title);
+ System.err.println(e.toString());
+ e.printStackTrace();
+
+ buildHeader(ac, res, output);
+ res.setStatus(500);
+
+ if((e instanceof java.net.UnknownHostException) ||
+ ((e instanceof java.io.FileNotFoundException) &&
+ ((e.getMessage().indexOf("Not Found") != -1) ||
+ (e.getMessage().indexOf("Service Unavailable") != -1)))) {
+ validURI = true;
+ }
+ else {
+ validURI = false;
+ }
+
+ PrintWriter out = getLocalPrintWriter(res.getOutputStream(), ac
+ .getContentEncoding());
+
+ ErrorReport error = ErrorReportFactory.getErrorReport(ac, title, output,
+ e, validURI);
+
+ try {
+ error.print(out);
+ }
+ finally {
+ out.close();
}
}
Received on Friday, 22 July 2005 09:45:24 UTC