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