001: /******************************************************************
002: Copyright (c) 2006 Andy Jefferson and others. All rights reserved.
003: Licensed under the Apache License, Version 2.0 (the "License");
004: you may not use this file except in compliance with the License.
005: You may obtain a copy of the License at
006:
007: http://www.apache.org/licenses/LICENSE-2.0
008:
009: Unless required by applicable law or agreed to in writing, software
010: distributed under the License is distributed on an "AS IS" BASIS,
011: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012: See the License for the specific language governing permissions and
013: limitations under the License.
014:
015:
016: Contributors:
017: ...
018: *****************************************************************/package org.jpox.util;
019:
020: import java.io.File;
021: import java.io.FileInputStream;
022: import java.io.FileNotFoundException;
023: import java.io.InputStream;
024: import java.io.InputStreamReader;
025: import java.net.URL;
026: import java.util.HashMap;
027:
028: import org.jpox.util.JPOXLogger;
029: import org.jpox.util.Localiser;
030: import org.xml.sax.EntityResolver;
031: import org.xml.sax.InputSource;
032: import org.xml.sax.SAXException;
033:
034: /**
035: * Abstract implementation of an entity resolver for XML files.
036: * Supports a series of internally supported public or system identities, allowing
037: * implementers to support particular identities and direct them to local copies
038: * of the DTD for example.
039: *
040: * @version $Revision: 1.4 $
041: */
042: public abstract class AbstractXMLEntityResolver implements
043: EntityResolver {
044: /** Localiser for messages. */
045: protected static Localiser LOCALISER = Localiser
046: .getInstance("org.jpox.Localisation");
047:
048: /** Map of public identity entities supported. The key will be the identity, and the value is the local input to use. */
049: protected HashMap publicIdEntities = new HashMap();
050:
051: /** Map of system identity entities supported. The key will be the identity, and the value is the local input to use. */
052: protected HashMap systemIdEntities = new HashMap();
053:
054: /**
055: * Method to resolve XML entities.
056: * Allows for the internally supported public and system identity entities.
057: * @param publicId The public id.
058: * @param systemId The system id.
059: * @return Input Source for the URI.
060: * @see org.xml.sax.EntityResolver#resolveEntity(java.lang.String,java.lang.String)
061: */
062: public InputSource resolveEntity(String publicId, String systemId)
063: throws SAXException {
064: try {
065: if (publicId != null) {
066: // Use publicId if possible
067: String internalEntity = (String) publicIdEntities
068: .get(publicId);
069: if (internalEntity != null) {
070: return getLocalInputSource(publicId, systemId,
071: internalEntity);
072: }
073: }
074:
075: if (systemId != null) {
076: // Use systemId if possible
077: String internalEntity = (String) systemIdEntities
078: .get(systemId);
079: if (internalEntity != null) {
080: return getLocalInputSource(publicId, systemId,
081: internalEntity);
082: } else if (systemId.startsWith("file://")) {
083: // This is used to load from a file on the system, not on the CLASSPATH
084: String localPath = systemId.substring(7);
085: File file = new File(localPath);
086: if (file.exists()) {
087: if (JPOXLogger.METADATA.isDebugEnabled()) {
088: JPOXLogger.METADATA.debug(LOCALISER.msg(
089: "028001", publicId, systemId));
090: }
091: FileInputStream in = new FileInputStream(file);
092: return new InputSource(in);
093: }
094: return null;
095: } else if (systemId.startsWith("file:")) {
096: // Try to get the local file using CLASSPATH
097: return getLocalInputSource(publicId, systemId,
098: systemId.substring(5));
099: } else if (systemId.startsWith("http:")) {
100: // Try to get the URL and open its stream
101: try {
102: if (JPOXLogger.METADATA.isDebugEnabled()) {
103: JPOXLogger.METADATA.debug(LOCALISER.msg(
104: "028001", publicId, systemId));
105: }
106: URL url = new URL(systemId);
107: InputStream url_stream = url.openStream();
108: return new InputSource(url_stream);
109: } catch (Exception e) {
110: JPOXLogger.METADATA.error(e);
111: }
112: }
113: }
114:
115: JPOXLogger.METADATA.error(LOCALISER.msg("028002", publicId,
116: systemId));
117: return null;
118: } catch (Exception e) {
119: JPOXLogger.METADATA.error(LOCALISER.msg("028003", publicId,
120: systemId), e);
121: throw new SAXException(e.getMessage(), e);
122: }
123: }
124:
125: /**
126: * Accessor for the input source for a path.
127: * @param publicId Public identity
128: * @param systemId System identity
129: * @param localPath The local path
130: * @return The input source
131: * @throws FileNotFoundException if the local file is not accessible
132: */
133: protected InputSource getLocalInputSource(String publicId,
134: String systemId, String localPath)
135: throws FileNotFoundException {
136: if (JPOXLogger.METADATA.isDebugEnabled()) {
137: JPOXLogger.METADATA.debug(LOCALISER.msg("028000", publicId,
138: systemId, localPath));
139: }
140:
141: InputStream in = AbstractXMLEntityResolver.class
142: .getResourceAsStream(localPath);
143: if (in == null) {
144: JPOXLogger.METADATA.fatal("local resource \"" + localPath
145: + "\" does not exist!!!");
146: throw new FileNotFoundException("Unable to load resource: "
147: + localPath);
148: }
149: return new InputSource(new InputStreamReader(in));
150: }
151: }
|