1 /* 2 * reserved comment block 3 * DO NOT REMOVE OR ALTER! 4 */ 5 // BootstrapResolver.java - Resolve entities and URIs internally 6 7 /* 8 * Copyright 2001-2004 The Apache Software Foundation or its licensors, 9 * as applicable. 10 * 11 * Licensed under the Apache License, Version 2.0 (the "License"); 12 * you may not use this file except in compliance with the License. 13 * You may obtain a copy of the License at 14 * 15 * http://www.apache.org/licenses/LICENSE-2.0 16 * 17 * Unless required by applicable law or agreed to in writing, software 18 * distributed under the License is distributed on an "AS IS" BASIS, 19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 * See the License for the specific language governing permissions and 21 * limitations under the License. 22 */ 23 24 package com.sun.org.apache.xml.internal.resolver.helpers; 25 26 import java.util.Hashtable; 27 import java.net.URL; 28 import java.net.MalformedURLException; 29 import java.io.InputStream; 30 31 import javax.xml.transform.URIResolver; 32 import javax.xml.transform.Source; 33 import javax.xml.transform.sax.SAXSource; 34 import javax.xml.transform.TransformerException; 35 36 import org.xml.sax.EntityResolver; 37 import org.xml.sax.InputSource; 38 39 /** 40 * A simple bootstrapping resolver. 41 * 42 * <p>This class is used as the entity resolver when reading XML Catalogs. 43 * It searches for the OASIS XML Catalog DTD, Relax NG Grammar and W3C XML Schema 44 * as resources (e.g., in the resolver jar file).</p> 45 * 46 * <p>If you have your own DTDs or schemas, you can extend this class and 47 * set the BootstrapResolver in your CatalogManager.</p> 48 * 49 * @see com.sun.org.apache.xml.internal.resolver.CatalogManager 50 * 51 * @author Norman Walsh 52 * <a href="mailto:Norman.Walsh@Sun.COM">Norman.Walsh@Sun.COM</a> 53 * 54 */ 55 public class BootstrapResolver implements EntityResolver, URIResolver { 56 /** URI of the W3C XML Schema for OASIS XML Catalog files. */ 57 public static final String xmlCatalogXSD = "http://www.oasis-open.org/committees/entity/release/1.0/catalog.xsd"; 58 59 /** URI of the RELAX NG Grammar for OASIS XML Catalog files. */ 60 public static final String xmlCatalogRNG = "http://www.oasis-open.org/committees/entity/release/1.0/catalog.rng"; 61 62 /** Public identifier for OASIS XML Catalog files. */ 63 public static final String xmlCatalogPubId = "-//OASIS//DTD XML Catalogs V1.0//EN"; 64 65 /** System identifier for OASIS XML Catalog files. */ 66 public static final String xmlCatalogSysId = "http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd"; 67 68 /** Private hash used for public identifiers. */ 69 private Hashtable publicMap = new Hashtable(); 70 71 /** Private hash used for system identifiers. */ 72 private Hashtable systemMap = new Hashtable(); 73 74 /** Private hash used for URIs. */ 75 private Hashtable uriMap = new Hashtable(); 76 77 /** Constructor. */ 78 public BootstrapResolver() { 79 URL url = this.getClass().getResource("/com/sun/org/apache/xml/internal/resolver/etc/catalog.dtd"); 80 if (url != null) { 81 publicMap.put(xmlCatalogPubId, url.toString()); 82 systemMap.put(xmlCatalogSysId, url.toString()); 83 } 84 85 url = this.getClass().getResource("/com/sun/org/apache/xml/internal/resolver/etc/catalog.rng"); 86 if (url != null) { 87 uriMap.put(xmlCatalogRNG, url.toString()); 88 } 89 90 url = this.getClass().getResource("/com/sun/org/apache/xml/internal/resolver/etc/catalog.xsd"); 91 if (url != null) { 92 uriMap.put(xmlCatalogXSD, url.toString()); 93 } 94 } 95 96 /** SAX resolveEntity API. */ 97 public InputSource resolveEntity (String publicId, String systemId) { 98 String resolved = null; 99 100 if (systemId != null && systemMap.containsKey(systemId)) { 101 resolved = (String) systemMap.get(systemId); 102 } else if (publicId != null && publicMap.containsKey(publicId)) { 103 resolved = (String) publicMap.get(publicId); 104 } 105 106 if (resolved != null) { 107 try { 108 InputSource iSource = new InputSource(resolved); 109 iSource.setPublicId(publicId); 110 111 // Ideally this method would not attempt to open the 112 // InputStream, but there is a bug (in Xerces, at least) 113 // that causes the parser to mistakenly open the wrong 114 // system identifier if the returned InputSource does 115 // not have a byteStream. 116 // 117 // It could be argued that we still shouldn't do this here, 118 // but since the purpose of calling the entityResolver is 119 // almost certainly to open the input stream, it seems to 120 // do little harm. 121 // 122 URL url = new URL(resolved); 123 InputStream iStream = url.openStream(); 124 iSource.setByteStream(iStream); 125 126 return iSource; 127 } catch (Exception e) { 128 // FIXME: silently fail? 129 return null; 130 } 131 } 132 133 return null; 134 } 135 136 /** Transformer resolve API. */ 137 public Source resolve(String href, String base) 138 throws TransformerException { 139 140 String uri = href; 141 String fragment = null; 142 int hashPos = href.indexOf("#"); 143 if (hashPos >= 0) { 144 uri = href.substring(0, hashPos); 145 fragment = href.substring(hashPos+1); 146 } 147 148 String result = null; 149 if (href != null && uriMap.containsKey(href)) { 150 result = (String) uriMap.get(href); 151 } 152 153 if (result == null) { 154 try { 155 URL url = null; 156 157 if (base==null) { 158 url = new URL(uri); 159 result = url.toString(); 160 } else { 161 URL baseURL = new URL(base); 162 url = (href.length()==0 ? baseURL : new URL(baseURL, uri)); 163 result = url.toString(); 164 } 165 } catch (java.net.MalformedURLException mue) { 166 // try to make an absolute URI from the current base 167 String absBase = makeAbsolute(base); 168 if (!absBase.equals(base)) { 169 // don't bother if the absBase isn't different! 170 return resolve(href, absBase); 171 } else { 172 throw new TransformerException("Malformed URL " 173 + href + "(base " + base + ")", 174 mue); 175 } 176 } 177 } 178 179 SAXSource source = new SAXSource(); 180 source.setInputSource(new InputSource(result)); 181 return source; 182 } 183 184 /** Attempt to construct an absolute URI */ 185 private String makeAbsolute(String uri) { 186 if (uri == null) { 187 uri = ""; 188 } 189 190 try { 191 URL url = new URL(uri); 192 return url.toString(); 193 } catch (MalformedURLException mue) { 194 try { 195 URL fileURL = FileURL.makeURL(uri); 196 return fileURL.toString(); 197 } catch (MalformedURLException mue2) { 198 // bail 199 return uri; 200 } 201 } 202 } 203 }