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: package org.apache.catalina.util;
017:
018: import java.util.HashMap;
019:
020: import org.apache.commons.digester.Digester;
021: import org.xml.sax.InputSource;
022: import org.xml.sax.EntityResolver;
023: import org.xml.sax.SAXException;
024:
025: /**
026: * This class implements a local SAX's <code>EntityResolver</code>. All
027: * DTDs and schemas used to validate the web.xml file will re-directed
028: * to a local file stored in the servlet-api.jar and jsp-api.jar.
029: *
030: * @author Jean-Francois Arcand
031: */
032: public class SchemaResolver implements EntityResolver {
033:
034: /**
035: * The disgester instance for which this class is the entity resolver.
036: */
037: protected Digester digester;
038:
039: /**
040: * The URLs of dtds and schemas that have been registered, keyed by the
041: * public identifier that corresponds.
042: */
043: protected HashMap entityValidator = new HashMap();
044:
045: /**
046: * The public identifier of the DTD we are currently parsing under
047: * (if any).
048: */
049: protected String publicId = null;
050:
051: /**
052: * Extension to make the difference between DTD and Schema.
053: */
054: protected String schemaExtension = "xsd";
055:
056: /**
057: * Create a new <code>EntityResolver</code> that will redirect
058: * all remote dtds and schema to a locat destination.
059: * @param digester The digester instance.
060: */
061: public SchemaResolver(Digester digester) {
062: this .digester = digester;
063: }
064:
065: /**
066: * Register the specified DTD/Schema URL for the specified public
067: * identifier. This must be called before the first call to
068: * <code>parse()</code>.
069: *
070: * When adding a schema file (*.xsd), only the name of the file
071: * will get added. If two schemas with the same name are added,
072: * only the last one will be stored.
073: *
074: * @param publicId Public identifier of the DTD to be resolved
075: * @param entityURL The URL to use for reading this DTD
076: */
077: public void register(String publicId, String entityURL) {
078: String key = publicId;
079: if (publicId.indexOf(schemaExtension) != -1)
080: key = publicId.substring(publicId.lastIndexOf('/') + 1);
081: entityValidator.put(key, entityURL);
082: }
083:
084: /**
085: * Resolve the requested external entity.
086: *
087: * @param publicId The public identifier of the entity being referenced
088: * @param systemId The system identifier of the entity being referenced
089: *
090: * @exception SAXException if a parsing exception occurs
091: *
092: */
093: public InputSource resolveEntity(String publicId, String systemId)
094: throws SAXException {
095:
096: if (publicId != null) {
097: this .publicId = publicId;
098: digester.setPublicId(publicId);
099: }
100:
101: // Has this system identifier been registered?
102: String entityURL = null;
103: if (publicId != null) {
104: entityURL = (String) entityValidator.get(publicId);
105: }
106:
107: // Redirect the schema location to a local destination
108: String key = null;
109: if (entityURL == null && systemId != null) {
110: key = systemId.substring(systemId.lastIndexOf('/') + 1);
111: entityURL = (String) entityValidator.get(key);
112: }
113:
114: if (entityURL == null) {
115: return (null);
116: }
117:
118: try {
119: return (new InputSource(entityURL));
120: } catch (Exception e) {
121: throw new SAXException(e);
122: }
123:
124: }
125:
126: }
|