KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > winstone > WebXmlParser


1 /*
2  * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
3  * Distributed under the terms of either:
4  * - the common development and distribution license (CDDL), v1.0; or
5  * - the GNU Lesser General Public License, v2.1 or later
6  */

7 package winstone;
8
9 import java.io.File JavaDoc;
10 import java.io.IOException JavaDoc;
11 import java.net.URL JavaDoc;
12
13 import javax.xml.parsers.DocumentBuilder JavaDoc;
14 import javax.xml.parsers.DocumentBuilderFactory JavaDoc;
15 import javax.xml.parsers.ParserConfigurationException JavaDoc;
16
17 import org.w3c.dom.Document JavaDoc;
18 import org.xml.sax.EntityResolver JavaDoc;
19 import org.xml.sax.ErrorHandler JavaDoc;
20 import org.xml.sax.InputSource JavaDoc;
21 import org.xml.sax.SAXException JavaDoc;
22 import org.xml.sax.SAXParseException JavaDoc;
23
24 /**
25  * The web.xml parsing logic. This is used by more than one launcher, so it's shared from here.
26  *
27  * @author <a HREF="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
28  * @version $Id: WebXmlParser.java,v 1.8 2006/09/07 00:15:11 rickknowles Exp $
29  */

30 public class WebXmlParser implements EntityResolver JavaDoc, ErrorHandler JavaDoc {
31
32     private ClassLoader JavaDoc commonLoader;
33     private boolean rethrowValidationExceptions;
34
35     public WebXmlParser(ClassLoader JavaDoc commonCL) {
36         this.commonLoader = commonCL;
37         this.rethrowValidationExceptions = true;
38     }
39     
40     private final static String JavaDoc SCHEMA_SOURCE_PROPERTY = "http://java.sun.com/xml/jaxp/properties/schemaSource";
41     
42     /**
43      * Get a parsed XML DOM from the given inputstream. Used to process the
44      * web.xml application deployment descriptors. Returns null if the parse fails,
45      * so the effect is as if there was no web.xml file available.
46      */

47     protected Document JavaDoc parseStreamToXML(File JavaDoc webXmlFile) {
48         DocumentBuilderFactory JavaDoc factory = getBaseDBF();
49         
50         URL JavaDoc localXSD25 = this.commonLoader.getResource(LOCAL_ENTITY_TABLE[3][2]);
51         URL JavaDoc localXSD24 = this.commonLoader.getResource(LOCAL_ENTITY_TABLE[2][2]);
52         
53         // Test for XSD compliance
54
try {
55             factory.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage",
56                     "http://www.w3.org/2001/XMLSchema");
57             if (localXSD25 != null) {
58                 factory.setAttribute(SCHEMA_SOURCE_PROPERTY, localXSD25.toString());
59                 Logger.log(Logger.FULL_DEBUG, Launcher.RESOURCES, "WebXmlParser.Local25XSDEnabled");
60             } else if (localXSD24 != null) {
61                 factory.setAttribute(SCHEMA_SOURCE_PROPERTY, localXSD24.toString());
62                 Logger.log(Logger.FULL_DEBUG, Launcher.RESOURCES, "WebXmlParser.Local24XSDEnabled");
63             } else {
64                 Logger.log(Logger.WARNING, Launcher.RESOURCES, "WebXmlParser.2524XSDNotFound");
65             }
66         } catch (Throwable JavaDoc err) {
67             // if non-compliant parser, then parse as non-XSD compliant
68
Logger.log(Logger.WARNING, Launcher.RESOURCES, "WebXmlParser.NonXSDParser");
69             try {
70                 this.rethrowValidationExceptions = false;
71                 return parseAsV23Webapp(webXmlFile);
72             } catch (Throwable JavaDoc v23Err) {
73                 Logger.log(Logger.ERROR, Launcher.RESOURCES, "WebXmlParser.WebXML23ParseError", v23Err);
74                 return null;
75             }
76         }
77         
78         // XSD compliant parser available, so parse as 2.5
79
try {
80             if (localXSD25 != null) {
81                 factory.setAttribute(SCHEMA_SOURCE_PROPERTY, localXSD25.toString());
82             } else {
83                 factory.setAttribute(SCHEMA_SOURCE_PROPERTY, null);
84             }
85             DocumentBuilder JavaDoc builder = factory.newDocumentBuilder();
86             builder.setEntityResolver(this);
87             builder.setErrorHandler(this);
88             this.rethrowValidationExceptions = true;
89             return builder.parse(webXmlFile);
90         } catch (Throwable JavaDoc errV25) {
91             try {
92                 // Try as 2.4
93
if (localXSD24 != null) {
94                     factory.setAttribute(SCHEMA_SOURCE_PROPERTY, localXSD24.toString());
95                 } else {
96                     factory.setAttribute(SCHEMA_SOURCE_PROPERTY, null);
97                 }
98                 DocumentBuilder JavaDoc builder = factory.newDocumentBuilder();
99                 builder.setEntityResolver(this);
100                 builder.setErrorHandler(this);
101                 this.rethrowValidationExceptions = true;
102                 return builder.parse(webXmlFile);
103             } catch (Throwable JavaDoc errV24) {
104                 // Try parsing as a v2.3 spec webapp, and if another error happens, report 2.3, 2.4, 2.5
105
try {
106                     this.rethrowValidationExceptions = false;
107                     return parseAsV23Webapp(webXmlFile);
108                 } catch (Throwable JavaDoc errV23) {
109                     Logger.log(Logger.ERROR, Launcher.RESOURCES, "WebXmlParser.WebXMLBothErrors");
110                     Logger.log(Logger.ERROR, Launcher.RESOURCES, "WebXmlParser.WebXML25ParseError", errV25);
111                     Logger.log(Logger.ERROR, Launcher.RESOURCES, "WebXmlParser.WebXML24ParseError", errV24);
112                     Logger.log(Logger.ERROR, Launcher.RESOURCES, "WebXmlParser.WebXML23ParseError", errV23);
113                     return null;
114                 }
115             }
116         }
117     }
118     
119     private Document JavaDoc parseAsV23Webapp(File JavaDoc webXmlFile) throws ParserConfigurationException JavaDoc,
120             SAXException JavaDoc, IOException JavaDoc {
121         DocumentBuilderFactory JavaDoc factory = getBaseDBF();
122         DocumentBuilder JavaDoc builder = factory.newDocumentBuilder();
123         builder.setEntityResolver(this);
124         builder.setErrorHandler(this);
125         return builder.parse(webXmlFile);
126     }
127     
128     private DocumentBuilderFactory JavaDoc getBaseDBF() {
129         // Use JAXP to create a document builder
130
DocumentBuilderFactory JavaDoc factory = DocumentBuilderFactory.newInstance();
131         factory.setExpandEntityReferences(false);
132         factory.setValidating(true);
133         factory.setNamespaceAware(true);
134         factory.setIgnoringComments(true);
135         factory.setCoalescing(true);
136         factory.setIgnoringElementContentWhitespace(true);
137         return factory;
138     }
139
140     /**
141      * Table mapping public doctypes and system ids against local classloader paths. This
142      * is used to resolve local entities where possible.
143      * Column 0 = public doctype
144      * Column 1 = system id
145      * Column 2 = local path
146      */

147     private static final String JavaDoc LOCAL_ENTITY_TABLE[][] = {
148         {"-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN", null, "javax/servlet/resources/web-app_2_2.dtd"},
149         {"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN", null, "javax/servlet/resources/web-app_2_3.dtd"},
150         {null, "http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd", "javax/servlet/resources/web-app_2_4.xsd"},
151         {null, "http://java.sun.com/xml/ns/j2ee/web-app_2_5.xsd", "javax/servlet/resources/web-app_2_5.xsd"},
152         {null, "http://www.w3.org/2001/xml.xsd", "javax/servlet/resources/xml.xsd"},
153         {"-//W3C//DTD XMLSCHEMA 200102//EN", null, "javax/servlet/resources/XMLSchema.dtd"},
154         {null, "http://www.w3.org/2001/datatypes.dtd", "javax/servlet/resources/datatypes.dtd"},
155         {null, "http://java.sun.com/xml/ns/j2ee/j2ee_1_4.xsd", "javax/servlet/resources/j2ee_1_4.xsd"},
156         {null, "http://java.sun.com/xml/ns/j2ee/javaee_5.xsd", "javax/servlet/resources/javaee_5.xsd"},
157         {null, "http://www.ibm.com/webservices/xsd/j2ee_web_services_client_1_1.xsd", "javax/servlet/resources/j2ee_web_services_client_1_1.xsd"},
158         {null, "http://www.ibm.com/webservices/xsd/j2ee_web_services_client_1_2.xsd", "javax/servlet/resources/javaee_web_services_client_1_2.xsd"}
159     };
160     
161     /**
162      * Implements the EntityResolver interface. This allows us to redirect any
163      * requests by the parser for webapp DTDs to local copies. It's faster and
164      * it means you can run winstone without being web-connected.
165      */

166     public InputSource JavaDoc resolveEntity(String JavaDoc publicName, String JavaDoc url)
167             throws SAXException JavaDoc, IOException JavaDoc {
168         Logger.log(Logger.FULL_DEBUG, Launcher.RESOURCES, "WebXmlParser.ResolvingEntity",
169                 new String JavaDoc[] { publicName, url });
170         for (int n = 0; n < LOCAL_ENTITY_TABLE.length; n++) {
171             if (((LOCAL_ENTITY_TABLE[n][0] != null) && (publicName != null) &&
172                         publicName.equals(LOCAL_ENTITY_TABLE[n][0])) ||
173                     ((LOCAL_ENTITY_TABLE[n][1] != null) && (url != null) &&
174                             url.equals(LOCAL_ENTITY_TABLE[n][1]))) {
175                 if (this.commonLoader.getResource(LOCAL_ENTITY_TABLE[n][2]) != null) {
176                     return getLocalResource(url, LOCAL_ENTITY_TABLE[n][2]);
177                 }
178             }
179         }
180         if ((url != null) && url.startsWith("jar:")) {
181             return getLocalResource(url, url.substring(url.indexOf("!/") + 2));
182         } else if ((url != null) && url.startsWith("file:")) {
183             return new InputSource JavaDoc(url);
184         } else {
185             Logger.log(Logger.FULL_DEBUG, Launcher.RESOURCES,
186                     "WebXmlParser.NoLocalResource", url);
187             return new InputSource JavaDoc(url);
188         }
189     }
190
191     private InputSource JavaDoc getLocalResource(String JavaDoc url, String JavaDoc local) {
192         if (this.commonLoader.getResource(local) == null)
193             return new InputSource JavaDoc(url);
194         InputSource JavaDoc is = new InputSource JavaDoc(this.commonLoader.getResourceAsStream(local));
195         is.setSystemId(url);
196         return is;
197     }
198
199     public void error(SAXParseException JavaDoc exception) throws SAXException JavaDoc {
200         if (this.rethrowValidationExceptions) {
201             throw exception;
202         } else {
203             Logger.log(Logger.WARNING, Launcher.RESOURCES, "WebXmlParser.XMLParseError",
204                     new String JavaDoc[] { exception.getLineNumber() + "",
205                             exception.getMessage() });
206         }
207     }
208
209     public void fatalError(SAXParseException JavaDoc exception) throws SAXException JavaDoc {
210         error(exception);
211     }
212
213     public void warning(SAXParseException JavaDoc exception) throws SAXException JavaDoc {
214         Logger.log(Logger.WARNING, Launcher.RESOURCES, "WebXmlParser.XMLParseError",
215                 new String JavaDoc[] { exception.getLineNumber() + "",
216                         exception.getMessage() });
217     }
218 }
219
Popular Tags