1 /*
2  * reserved comment block
3  * DO NOT REMOVE OR ALTER!
4  */
5 /*
6  * Licensed to the Apache Software Foundation (ASF) under one or more
7  * contributor license agreements.  See the NOTICE file distributed with
8  * this work for additional information regarding copyright ownership.
9  * The ASF licenses this file to You under the Apache License, Version 2.0
10  * (the "License"); you may not use this file except in compliance with
11  * the License.  You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  */
21 
22 package com.sun.org.apache.xerces.internal.util;
23 
24 import java.io.InputStream;
25 import java.io.IOException;
26 import java.io.Reader;
27 
28 import com.sun.org.apache.xerces.internal.impl.ExternalSubsetResolver;
29 import com.sun.org.apache.xerces.internal.impl.XMLEntityDescription;
30 import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier;
31 import com.sun.org.apache.xerces.internal.xni.XNIException;
32 import com.sun.org.apache.xerces.internal.xni.grammars.XMLDTDDescription;
33 import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
34 
35 import org.xml.sax.ext.EntityResolver2;
36 import org.xml.sax.InputSource;
37 import org.xml.sax.SAXException;
38 
39 /**
40  * <p>This class wraps a SAX entity resolver (EntityResolver2) in an XNI entity resolver.</p>
41  *
42  * @author Michael Glavassevich, IBM
43  *
44  */
45 public class EntityResolver2Wrapper
46     implements ExternalSubsetResolver {
47 
48     //
49     // Data
50     //
51 
52     /** An instance of SAX2 Extensions 1.1's EntityResolver2. */
53     protected EntityResolver2 fEntityResolver;
54 
55     //
56     // Constructors
57     //
58 
59     /** Default constructor. */
EntityResolver2Wrapper()60     public EntityResolver2Wrapper() {}
61 
62     /**
63      * <p>Creates a new instance wrapping the given SAX entity resolver.</p>
64      *
65      * @param entityResolver the SAX entity resolver to wrap
66      */
EntityResolver2Wrapper(EntityResolver2 entityResolver)67     public EntityResolver2Wrapper(EntityResolver2 entityResolver) {
68         setEntityResolver(entityResolver);
69     } // <init>(EntityResolver2)
70 
71     //
72     // Public methods
73     //
74 
75     /**
76      * <p>Sets the SAX entity resolver wrapped by this object.</p>
77      *
78      * @param entityResolver the SAX entity resolver to wrap
79      */
setEntityResolver(EntityResolver2 entityResolver)80     public void setEntityResolver(EntityResolver2 entityResolver) {
81         fEntityResolver = entityResolver;
82     } // setEntityResolver(EntityResolver2)
83 
84     /**
85      * <p>Returns the SAX entity resolver wrapped by this object.</p>
86      *
87      * @return the SAX entity resolver wrapped by this object
88      */
getEntityResolver()89     public EntityResolver2 getEntityResolver() {
90         return fEntityResolver;
91     } // getEntityResolver():EntityResolver2
92 
93     //
94     // ExternalSubsetResolver methods
95     //
96 
97     /**
98      * <p>Locates an external subset for documents which do not explicitly
99      * provide one. If no external subset is provided, this method should
100      * return <code>null</code>.</p>
101      *
102      * @param grammarDescription a description of the DTD
103      *
104      * @throws XNIException Thrown on general error.
105      * @throws IOException  Thrown if resolved entity stream cannot be
106      *                      opened or some other i/o error occurs.
107      */
getExternalSubset(XMLDTDDescription grammarDescription)108     public XMLInputSource getExternalSubset(XMLDTDDescription grammarDescription)
109             throws XNIException, IOException {
110 
111         if (fEntityResolver != null) {
112 
113             String name = grammarDescription.getRootName();
114             String baseURI = grammarDescription.getBaseSystemId();
115 
116             // Resolve using EntityResolver2
117             try {
118                 InputSource inputSource = fEntityResolver.getExternalSubset(name, baseURI);
119                 return (inputSource != null) ? createXMLInputSource(inputSource, baseURI) : null;
120             }
121             // error resolving external subset
122             catch (SAXException e) {
123                 Exception ex = e.getException();
124                 if (ex == null) {
125                     ex = e;
126                 }
127                 throw new XNIException(ex);
128             }
129         }
130 
131         // unable to resolve external subset
132         return null;
133 
134     } // getExternalSubset(XMLDTDDescription):XMLInputSource
135 
136     //
137     // XMLEntityResolver methods
138     //
139 
140     /**
141      * Resolves an external parsed entity. If the entity cannot be
142      * resolved, this method should return null.
143      *
144      * @param resourceIdentifier contains the physical co-ordinates of the resource to be resolved
145      *
146      * @throws XNIException Thrown on general error.
147      * @throws IOException  Thrown if resolved entity stream cannot be
148      *                      opened or some other i/o error occurs.
149      */
resolveEntity(XMLResourceIdentifier resourceIdentifier)150     public XMLInputSource resolveEntity(XMLResourceIdentifier resourceIdentifier)
151             throws XNIException, IOException {
152 
153         if (fEntityResolver != null) {
154 
155             String pubId = resourceIdentifier.getPublicId();
156             String sysId = resourceIdentifier.getLiteralSystemId();
157             String baseURI = resourceIdentifier.getBaseSystemId();
158             String name = null;
159             if (resourceIdentifier instanceof XMLDTDDescription) {
160                 name = "[dtd]";
161             }
162             else if (resourceIdentifier instanceof XMLEntityDescription) {
163                 name = ((XMLEntityDescription) resourceIdentifier).getEntityName();
164             }
165 
166             // When both pubId and sysId are null, the user's entity resolver
167             // can do nothing about it. We'd better not bother calling it.
168             // This happens when the resourceIdentifier is a GrammarDescription,
169             // which describes a schema grammar of some namespace, but without
170             // any schema location hint. -Sg
171             if (pubId == null && sysId == null) {
172                 return null;
173             }
174 
175             // Resolve using EntityResolver2
176             try {
177                 InputSource inputSource =
178                     fEntityResolver.resolveEntity(name, pubId, baseURI, sysId);
179                 return (inputSource != null) ? createXMLInputSource(inputSource, baseURI) : null;
180             }
181             // error resolving entity
182             catch (SAXException e) {
183                 Exception ex = e.getException();
184                 if (ex == null) {
185                     ex = e;
186                 }
187                 throw new XNIException(ex);
188             }
189         }
190 
191         // unable to resolve entity
192         return null;
193 
194     } // resolveEntity(XMLResourceIdentifier):XMLInputSource
195 
196     /**
197      * Creates an XMLInputSource from a SAX InputSource.
198      */
createXMLInputSource(InputSource source, String baseURI)199     private XMLInputSource createXMLInputSource(InputSource source, String baseURI) {
200 
201         String publicId = source.getPublicId();
202         String systemId = source.getSystemId();
203         String baseSystemId = baseURI;
204         InputStream byteStream = source.getByteStream();
205         Reader charStream = source.getCharacterStream();
206         String encoding = source.getEncoding();
207         XMLInputSource xmlInputSource =
208             new XMLInputSource(publicId, systemId, baseSystemId, false);
209         xmlInputSource.setByteStream(byteStream);
210         xmlInputSource.setCharacterStream(charStream);
211         xmlInputSource.setEncoding(encoding);
212         return xmlInputSource;
213 
214     } // createXMLInputSource(InputSource,String):XMLInputSource
215 
216 } // class EntityResolver2Wrapper
217