< prev index next >

src/java.xml/share/classes/javax/xml/catalog/CatalogResolverImpl.java

Print this page




   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 package javax.xml.catalog;
  26 




  27 import java.io.StringReader;
  28 import java.util.Iterator;





  29 import org.xml.sax.InputSource;


  30 
  31 /**
  32  * A SAX EntityResolver/JAXP URIResolver that uses catalogs.
  33  *
  34  * <p>
  35  * This class implements both a SAX EntityResolver and a JAXP URIResolver.

  36  *
  37  *
  38  * @since 9
  39  */
  40 final class CatalogResolverImpl implements CatalogResolver {
  41     Catalog catalog;
  42 
  43     /**
  44      * Construct an instance of the CatalogResolver from a Catalog.
  45      *
  46      * @param catalog A Catalog.
  47      */
  48     public CatalogResolverImpl(Catalog catalog) {
  49         this.catalog = catalog;
  50     }
  51 



  52     @Override
  53     public InputSource resolveEntity(String publicId, String systemId) {

  54         CatalogMessages.reportNPEOnNull("systemId", systemId);

  55         //Normalize publicId and systemId
  56         systemId = Normalizer.normalizeURI(Util.getNotNullOrEmpty(systemId));
  57         publicId = Normalizer.normalizePublicId(Normalizer.decodeURN(Util.getNotNullOrEmpty(publicId)));
  58 
  59         //check whether systemId is an urn
  60         if (systemId != null && systemId.startsWith(Util.URN)) {
  61             systemId = Normalizer.decodeURN(systemId);
  62             if (publicId != null && !publicId.equals(systemId)) {
  63                 systemId = null;
  64             } else {
  65                 publicId = systemId;
  66                 systemId = null;
  67             }
  68         }
  69 
  70         CatalogImpl c = (CatalogImpl)catalog;
  71         String resolvedSystemId = Util.resolve(c, publicId, systemId);
  72 
  73         if (resolvedSystemId != null) {
  74             return new InputSource(resolvedSystemId);
  75         }
  76 
  77         GroupEntry.ResolveType resolveType = ((CatalogImpl) catalog).getResolve();
  78         switch (resolveType) {
  79             case IGNORE:
  80                 return new InputSource(new StringReader(""));
  81             case STRICT:
  82                 CatalogMessages.reportError(CatalogMessages.ERR_NO_MATCH,
  83                         new Object[]{publicId, systemId});
  84         }
  85 
  86         //no action, allow the parser to continue
  87         return null;














































































































































































































































  88     }
  89 
  90 }


   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 package javax.xml.catalog;
  26 
  27 import com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl;
  28 import java.io.IOException;
  29 import java.io.InputStream;
  30 import java.io.Reader;
  31 import java.io.StringReader;
  32 import java.net.URL;
  33 import javax.xml.parsers.ParserConfigurationException;
  34 import javax.xml.parsers.SAXParserFactory;
  35 import javax.xml.transform.Source;
  36 import javax.xml.transform.sax.SAXSource;
  37 import org.w3c.dom.ls.LSInput;
  38 import org.xml.sax.InputSource;
  39 import org.xml.sax.SAXException;
  40 import org.xml.sax.XMLReader;
  41 
  42 /**
  43  * Implements CatalogResolver.
  44  *
  45  * <p>
  46  * This class implements a SAX EntityResolver, StAX XMLResolver,
  47  * Schema Validation LSResourceResolver and Transform URIResolver.
  48  *
  49  *
  50  * @since 9
  51  */
  52 final class CatalogResolverImpl implements CatalogResolver {
  53     Catalog catalog;
  54 
  55     /**
  56      * Construct an instance of the CatalogResolver from a Catalog.
  57      *
  58      * @param catalog A Catalog.
  59      */
  60     public CatalogResolverImpl(Catalog catalog) {
  61         this.catalog = catalog;
  62     }
  63 
  64     /*
  65        Implements the EntityResolver interface
  66     */
  67     @Override
  68     public InputSource resolveEntity(String publicId, String systemId) {
  69         //8150187: NPE expected if the system identifier is null for CatalogResolver
  70         CatalogMessages.reportNPEOnNull("systemId", systemId);
  71 
  72         //Normalize publicId and systemId
  73         systemId = Normalizer.normalizeURI(Util.getNotNullOrEmpty(systemId));
  74         publicId = Normalizer.normalizePublicId(Normalizer.decodeURN(Util.getNotNullOrEmpty(publicId)));
  75 
  76         //check whether systemId is an urn
  77         if (systemId != null && systemId.startsWith(Util.URN)) {
  78             systemId = Normalizer.decodeURN(systemId);
  79             if (publicId != null && !publicId.equals(systemId)) {
  80                 systemId = null;
  81             } else {
  82                 publicId = systemId;
  83                 systemId = null;
  84             }
  85         }
  86 
  87         CatalogImpl c = (CatalogImpl)catalog;
  88         String resolvedSystemId = Util.resolve(c, publicId, systemId);
  89 
  90         if (resolvedSystemId != null) {
  91             return new InputSource(resolvedSystemId);
  92         }
  93 
  94         GroupEntry.ResolveType resolveType = ((CatalogImpl) catalog).getResolve();
  95         switch (resolveType) {
  96             case IGNORE:
  97                 return new InputSource(new StringReader(""));
  98             case STRICT:
  99                 CatalogMessages.reportError(CatalogMessages.ERR_NO_MATCH,
 100                         new Object[]{publicId, systemId});
 101         }
 102 
 103         //no action, allow the parser to continue
 104         return null;
 105     }
 106 
 107     /*
 108         Implements the URIResolver interface
 109     */
 110     CatalogResolverImpl entityResolver;
 111 
 112     @Override
 113     public Source resolve(String href, String base) {
 114         CatalogMessages.reportNPEOnNull("href", href);
 115 
 116         href = Util.getNotNullOrEmpty(href);
 117         base = Util.getNotNullOrEmpty(base);
 118 
 119         String result = null;
 120         CatalogImpl c = (CatalogImpl)catalog;
 121         String uri = Normalizer.normalizeURI(href);
 122         //check whether uri is an urn
 123         if (uri != null && uri.startsWith(Util.URN)) {
 124             String publicId = Normalizer.decodeURN(uri);
 125             if (publicId != null) {
 126                 result = Util.resolve(c, publicId, null);
 127             }
 128         }
 129 
 130         //if no match with a public id, continue search for an URI
 131         if (result == null) {
 132             //remove fragment if any.
 133             int hashPos = uri.indexOf("#");
 134             if (hashPos >= 0) {
 135                 uri = uri.substring(0, hashPos);
 136             }
 137 
 138             //search the current catalog
 139             result = Util.resolve(c, null, uri);
 140         }
 141 
 142         //Report error or return the URI as is when no match is found
 143         if (result == null) {
 144             GroupEntry.ResolveType resolveType = c.getResolve();
 145             switch (resolveType) {
 146                 case IGNORE:
 147                     return new SAXSource(new InputSource(new StringReader("")));
 148                 case STRICT:
 149                     CatalogMessages.reportError(CatalogMessages.ERR_NO_URI_MATCH,
 150                             new Object[]{href, base});
 151             }
 152             try {
 153                 URL url = null;
 154 
 155                 if (base == null) {
 156                     url = new URL(uri);
 157                     result = url.toString();
 158                 } else {
 159                     URL baseURL = new URL(base);
 160                     url = (href.length() == 0 ? baseURL : new URL(baseURL, uri));
 161                     result = url.toString();
 162                 }
 163             } catch (java.net.MalformedURLException mue) {
 164                     CatalogMessages.reportError(CatalogMessages.ERR_CREATING_URI,
 165                             new Object[]{href, base});
 166             }
 167         }
 168 
 169         SAXSource source = new SAXSource();
 170         source.setInputSource(new InputSource(result));
 171         setEntityResolver(source);
 172         return source;
 173     }
 174 
 175     /**
 176      * Establish an entityResolver for newly resolved URIs.
 177      * <p>
 178      * This is called from the URIResolver to set an EntityResolver on the SAX
 179      * parser to be used for new XML documents that are encountered as a result
 180      * of the document() function, xsl:import, or xsl:include. This is done
 181      * because the XSLT processor calls out to the SAXParserFactory itself to
 182      * create a new SAXParser to parse the new document. The new parser does not
 183      * automatically inherit the EntityResolver of the original (although
 184      * arguably it should). Quote from JAXP specification on Class
 185      * SAXTransformerFactory:
 186      * <p>
 187      * {@code If an application wants to set the ErrorHandler or EntityResolver
 188      * for an XMLReader used during a transformation, it should use a URIResolver
 189      * to return the SAXSource which provides (with getXMLReader) a reference to
 190      * the XMLReader}
 191      *
 192      */
 193     private void setEntityResolver(SAXSource source) {
 194         XMLReader reader = source.getXMLReader();
 195         if (reader == null) {
 196             SAXParserFactory spFactory = new SAXParserFactoryImpl();
 197             spFactory.setNamespaceAware(true);
 198             try {
 199                 reader = spFactory.newSAXParser().getXMLReader();
 200             } catch (ParserConfigurationException | SAXException ex) {
 201                 CatalogMessages.reportRunTimeError(CatalogMessages.ERR_PARSER_CONF, ex);
 202             }
 203         }
 204         if (entityResolver != null) {
 205             entityResolver = new CatalogResolverImpl(catalog);
 206         }
 207         reader.setEntityResolver(entityResolver);
 208         source.setXMLReader(reader);
 209     }
 210 
 211     @Override
 212     public InputStream resolveEntity(String publicId, String systemId, String baseUri, String namespace) {
 213         InputSource is = resolveEntity(publicId, systemId);
 214 
 215         if (is != null && !is.isEmpty()) {
 216 
 217             try {
 218                 return new URL(is.getSystemId()).openStream();
 219             } catch (IOException ex) {
 220                 //considered as no mapping.
 221             }
 222 
 223         }
 224 
 225         GroupEntry.ResolveType resolveType = ((CatalogImpl) catalog).getResolve();
 226         switch (resolveType) {
 227             case IGNORE:
 228                 return null;
 229             case STRICT:
 230                 CatalogMessages.reportError(CatalogMessages.ERR_NO_MATCH,
 231                         new Object[]{publicId, systemId});
 232         }
 233 
 234         //no action, allow the parser to continue
 235         return null;
 236     }
 237 
 238     @Override
 239     public LSInput resolveResource(String type, String namespaceURI, String publicId, String systemId, String baseURI) {
 240         InputSource is = resolveEntity(publicId, systemId);
 241 
 242         if (is != null && !is.isEmpty()) {
 243             return new LSInputImpl(is.getSystemId());
 244         }
 245 
 246         GroupEntry.ResolveType resolveType = ((CatalogImpl) catalog).getResolve();
 247         switch (resolveType) {
 248             case IGNORE:
 249                 return null;
 250             case STRICT:
 251                 CatalogMessages.reportError(CatalogMessages.ERR_NO_MATCH,
 252                         new Object[]{publicId, systemId});
 253         }
 254 
 255         //no action, allow the parser to continue
 256         return null;
 257     }
 258 
 259     /**
 260      * Implements LSInput. All that we need is the systemId since the Catalog
 261      * has already resolved it.
 262      */
 263     class LSInputImpl implements LSInput {
 264 
 265         private String systemId;
 266 
 267         public LSInputImpl(String systemId) {
 268             this.systemId = systemId;
 269         }
 270 
 271         @Override
 272         public Reader getCharacterStream() {
 273             return null;
 274         }
 275 
 276         @Override
 277         public void setCharacterStream(Reader characterStream) {
 278         }
 279 
 280         @Override
 281         public InputStream getByteStream() {
 282             return null;
 283         }
 284 
 285         @Override
 286         public void setByteStream(InputStream byteStream) {
 287         }
 288 
 289         @Override
 290         public String getStringData() {
 291             return null;
 292         }
 293 
 294         @Override
 295         public void setStringData(String stringData) {
 296         }
 297 
 298         @Override
 299         public String getSystemId() {
 300             return systemId;
 301         }
 302 
 303         @Override
 304         public void setSystemId(String systemId) {
 305             this.systemId = systemId;
 306         }
 307 
 308         @Override
 309         public String getPublicId() {
 310             return null;
 311         }
 312 
 313         @Override
 314         public void setPublicId(String publicId) {
 315         }
 316 
 317         @Override
 318         public String getBaseURI() {
 319             return null;
 320         }
 321 
 322         @Override
 323         public void setBaseURI(String baseURI) {
 324         }
 325 
 326         @Override
 327         public String getEncoding() {
 328             return null;
 329         }
 330 
 331         @Override
 332         public void setEncoding(String encoding) {
 333         }
 334 
 335         @Override
 336         public boolean getCertifiedText() {
 337             return false;
 338         }
 339 
 340         @Override
 341         public void setCertifiedText(boolean certifiedText) {
 342         }
 343     }
 344 
 345 }
< prev index next >