001: /*
002: * Copyright 1999-2004 The Apache Software Foundation.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.apache.catalina.startup;
018:
019: import java.net.URL;
020: import javax.xml.parsers.ParserConfigurationException;
021:
022: import org.apache.catalina.util.SchemaResolver;
023: import org.apache.commons.digester.Digester;
024: import org.apache.commons.digester.RuleSet;
025: import org.xml.sax.SAXNotRecognizedException;
026: import org.xml.sax.SAXNotSupportedException;
027:
028: /**
029: * Wrapper class around the Digester that hide Digester's initialization details
030: *
031: * @author Jean-Francois Arcand
032: */
033: public class DigesterFactory {
034:
035: /**
036: * The XML entiry resolver used by the Digester.
037: */
038: private static SchemaResolver schemaResolver;
039:
040: /**
041: * Create a <code>Digester</code> parser with no <code>Rule</code>
042: * associated and XML validation turned off.
043: */
044: public static Digester newDigester() {
045: return newDigester(false, false, null);
046: }
047:
048: /**
049: * Create a <code>Digester</code> parser with XML validation turned off.
050: * @param rule an instance of <code>Rule</code↔ used for parsing the xml.
051: */
052: public static Digester newDigester(RuleSet rule) {
053: return newDigester(false, false, rule);
054: }
055:
056: /**
057: * Create a <code>Digester</code> parser.
058: * @param xmlValidation turn on/off xml validation
059: * @param xmlNamespaceAware turn on/off namespace validation
060: * @param rule an instance of <code>Rule</code↔ used for parsing the xml.
061: */
062: public static Digester newDigester(boolean xmlValidation,
063: boolean xmlNamespaceAware, RuleSet rule) {
064:
065: URL url = null;
066: Digester digester = new Digester();
067: digester.setNamespaceAware(xmlNamespaceAware);
068: digester.setValidating(xmlValidation);
069: digester.setUseContextClassLoader(true);
070:
071: String parserName = digester.getFactory().getClass().getName();
072: if (parserName.indexOf("xerces") != -1) {
073: digester = patchXerces(digester);
074: }
075:
076: schemaResolver = new SchemaResolver(digester);
077: if (xmlValidation) {
078: // Xerces 2.3 and up has a special way to turn on validation
079: // for both DTD and Schema
080: if (parserName.indexOf("xerces") != -1) {
081: turnOnXercesValidation(digester);
082: } else {
083: turnOnValidation(digester);
084: }
085: }
086: registerLocalSchema();
087:
088: digester.setEntityResolver(schemaResolver);
089: if (rule != null)
090: digester.addRuleSet(rule);
091:
092: return (digester);
093: }
094:
095: /**
096: * Patch Xerces for backward compatibility.
097: */
098: private static Digester patchXerces(Digester digester) {
099: // This feature is needed for backward compatibility with old DDs
100: // which used Java encoding names such as ISO8859_1 etc.
101: // with Crimson (bug 4701993). By default, Xerces does not
102: // support ISO8859_1.
103: try {
104: digester
105: .setFeature(
106: "http://apache.org/xml/features/allow-java-encodings",
107: true);
108: } catch (ParserConfigurationException e) {
109: // log("contextConfig.registerLocalSchema", e);
110: } catch (SAXNotRecognizedException e) {
111: // log("contextConfig.registerLocalSchema", e);
112: } catch (SAXNotSupportedException e) {
113: // log("contextConfig.registerLocalSchema", e);
114: }
115: return digester;
116: }
117:
118: /**
119: * Utilities used to force the parser to use local schema, when available,
120: * instead of the <code>schemaLocation</code> XML element.
121: */
122: protected static void registerLocalSchema() {
123: // J2EE
124: register(Constants.J2eeSchemaResourcePath_14,
125: Constants.J2eeSchemaPublicId_14);
126: // W3C
127: register(Constants.W3cSchemaResourcePath_10,
128: Constants.W3cSchemaPublicId_10);
129: // JSP
130: register(Constants.JspSchemaResourcePath_20,
131: Constants.JspSchemaPublicId_20);
132: // TLD
133: register(Constants.TldDtdResourcePath_11,
134: Constants.TldDtdPublicId_11);
135:
136: register(Constants.TldDtdResourcePath_12,
137: Constants.TldDtdPublicId_12);
138:
139: register(Constants.TldSchemaResourcePath_20,
140: Constants.TldSchemaPublicId_20);
141:
142: // web.xml
143: register(Constants.WebDtdResourcePath_22,
144: Constants.WebDtdPublicId_22);
145:
146: register(Constants.WebDtdResourcePath_23,
147: Constants.WebDtdPublicId_23);
148:
149: register(Constants.WebSchemaResourcePath_24,
150: Constants.WebSchemaPublicId_24);
151:
152: // Web Service
153: register(Constants.J2eeWebServiceSchemaResourcePath_11,
154: Constants.J2eeWebServiceSchemaPublicId_11);
155:
156: register(Constants.J2eeWebServiceClientSchemaResourcePath_11,
157: Constants.J2eeWebServiceClientSchemaPublicId_11);
158:
159: }
160:
161: /**
162: * Load the resource and add it to the
163: */
164: protected static void register(String resourceURL,
165: String resourcePublicId) {
166:
167: URL url = DigesterFactory.class.getResource(resourceURL);
168: schemaResolver.register(resourcePublicId, url.toString());
169:
170: }
171:
172: /**
173: * Turn on DTD and/or validation (based on the parser implementation)
174: */
175: protected static void turnOnValidation(Digester digester) {
176: URL url = DigesterFactory.class
177: .getResource(Constants.WebSchemaResourcePath_24);
178: digester.setSchema(url.toString());
179: }
180:
181: /**
182: * Turn on schema AND DTD validation on Xerces parser.
183: */
184: protected static void turnOnXercesValidation(Digester digester) {
185: try {
186: digester
187: .setFeature(
188: "http://apache.org/xml/features/validation/dynamic",
189: true);
190: digester.setFeature(
191: "http://apache.org/xml/features/validation/schema",
192: true);
193: } catch (ParserConfigurationException e) {
194: // log("contextConfig.registerLocalSchema", e);
195: } catch (SAXNotRecognizedException e) {
196: // log("contextConfig.registerLocalSchema", e);
197: } catch (SAXNotSupportedException e) {
198: // log("contextConfig.registerLocalSchema", e);
199: }
200: }
201: }
|