CatalogResolver.java revision 988:1c6c21d87aa4
1/* 2 * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 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 */ 25package javax.xml.catalog; 26 27import java.io.InputStream; 28import javax.xml.stream.XMLResolver; 29import javax.xml.transform.Source; 30import javax.xml.transform.URIResolver; 31import org.w3c.dom.ls.LSInput; 32import org.w3c.dom.ls.LSResourceResolver; 33import org.xml.sax.EntityResolver; 34import org.xml.sax.InputSource; 35 36/** 37 * A Catalog Resolver that implements SAX {@link org.xml.sax.EntityResolver}, 38 * StAX {@link javax.xml.stream.XMLResolver}, 39 * DOM LS {@link org.w3c.dom.ls.LSResourceResolver} used by Schema Validation, and 40 * Transform {@link javax.xml.transform.URIResolver}, and resolves 41 * external references using catalogs. 42 * <p> 43 * The <a href="https://www.oasis-open.org/committees/download.php/14809/xml-catalogs.html"> 44 * Catalog Standard</a> distinguished {@code external identifiers} from {@code uri entries} 45 * as being used to solely identify DTDs, while {@code uri entries} for 46 * other resources such as stylesheets and schema. The Java APIs, such as 47 * {@link javax.xml.stream.XMLResolver} and {@link org.w3c.dom.ls.LSResourceResolver} 48 * however, make no such distinction. 49 * In consistent with the existing Java API, this CatalogResolver recognizes a 50 * system identifier as an URI and will search both {@code system} and {@code uri} 51 * entries in a catalog in order to find a matching entry. 52 * <p> 53 * The search is started in the current catalog. If a match is found, 54 * no further attempt will be made. Only if there is no match in the current 55 * catalog, will alternate catalogs including delegate and next catalogs be considered. 56 * <p> 57 * <h3>Search Order</h3> 58 * The resolver will first search the system-type of entries with the specified 59 * {@code systemId}. The system entries include {@code system}, 60 * {@code rewriteSystem} and {@code systemSuffix} entries. 61 * <p> 62 * If no match is found, {@code public} entries may be searched in accordance with 63 * the {@code prefer} attribute. 64 * <p> 65 * <b>The {@code prefer} attribute</b>: if the {@code prefer} is public, 66 * and there is no match found through the system entries, {@code public} entries 67 * will be considered. If it is not specified, the {@code prefer} is public 68 * by default (Note that by the OASIS standard, system entries will always 69 * be considered before public entries. Prefer public means that public entries 70 * will be matched when both system and public identifiers are specified. 71 * In general therefore, prefer public is recommended.) 72 * <p> 73 * If no match is found with the {@code systemId} and {@code public} identifier, 74 * the resolver will continue searching {@code uri} entries 75 * with the specified {@code systemId} or {@code href}. The {@code uri} entries 76 * include {@code uri}, {@code rewriteURI}, and {@code uriSuffix} entries. 77 * 78 * <p> 79 * <h3>Error Handling</h3> 80 * The interfaces that the CatalogResolver extend specified checked exceptions, including: 81 * <ul> 82 * <li> 83 * {@link org.xml.sax.SAXException} and {@link java.io.IOException} by 84 * {@link org.xml.sax.EntityResolver#resolveEntity(java.lang.String, java.lang.String)} 85 * </li> 86 * <li> 87 * {@link javax.xml.stream.XMLStreamException} by 88 * {@link javax.xml.stream.XMLResolver#resolveEntity(java.lang.String, java.lang.String, java.lang.String, java.lang.String)} 89 * </li> 90 * <li> 91 * {@link javax.xml.transform.TransformerException} by 92 * {@link javax.xml.transform.URIResolver#resolve(java.lang.String, java.lang.String)} 93 * </li> 94 * </ul> 95 * <p> 96 * The CatalogResolver however, will throw {@link javax.xml.catalog.CatalogException} 97 * only when {@code javax.xml.catalog.resolve} is specified as {@code strict}. 98 * For applications that expect to handle the checked Exceptions, it may be 99 * necessary to use a custom resolver to wrap the CatalogResolver or implement it 100 * with a {@link javax.xml.catalog.Catalog} object. 101 * 102 * @since 9 103 */ 104public interface CatalogResolver extends EntityResolver, XMLResolver, 105 URIResolver, LSResourceResolver { 106 107 /** 108 * Implements {@link org.xml.sax.EntityResolver}. The method searches through 109 * the catalog entries in the main and alternative catalogs to attempt to find 110 * a match with the specified {@code publicId} or systemId. 111 * 112 * @param publicId the public identifier of the external entity being 113 * referenced, or null if none was supplied 114 * 115 * @param systemId the system identifier of the external entity being 116 * referenced. A system identifier is required on all external entities. XML 117 * requires a system identifier on all external entities, so this value is 118 * always specified. 119 * 120 * @return a {@link org.xml.sax.InputSource} object if a mapping is found. 121 * If no mapping is found, returns a {@link org.xml.sax.InputSource} object 122 * containing an empty {@link java.io.Reader} if the 123 * {@code javax.xml.catalog.resolve} property is set to {@code ignore}; 124 * returns null if the 125 * {@code javax.xml.catalog.resolve} property is set to {@code continue}. 126 * 127 * @throws CatalogException if no mapping is found and 128 * {@code javax.xml.catalog.resolve} is specified as {@code strict} 129 */ 130 @Override 131 public InputSource resolveEntity(String publicId, String systemId); 132 133 134 /** 135 * Implements URIResolver. The method searches through the catalog entries 136 * in the main and alternative catalogs to attempt to find a match 137 * with the specified {@code href} attribute. The {@code href} attribute will 138 * be used literally, with no attempt to be made absolute to the {@code base}. 139 * <p> 140 * If the value is an URN, the {@code href} attribute is recognized as a 141 * {@code publicId}, and used to search {@code public} entries. 142 * If the value is an URI, it is taken as a {@code systemId}, and used to 143 * search both {@code system} and {@code uri} entries. 144 * 145 * 146 * @param href the href attribute that specifies the URI of a style sheet, 147 * which may be relative or absolute 148 * @param base The base URI against which the href attribute will be made 149 * absolute if the absolute URI is required 150 * 151 * @return a {@link javax.xml.transform.Source} object if a mapping is found. 152 * If no mapping is found, returns an empty {@link javax.xml.transform.Source} 153 * object if the {@code javax.xml.catalog.resolve} property is set to 154 * {@code ignore}; 155 * returns a {@link javax.xml.transform.Source} object with the original URI 156 * (href, or href resolved with base if base is not null) if the 157 * {@code javax.xml.catalog.resolve} property is set to {@code continue}. 158 * 159 * @throws CatalogException if no mapping is found and 160 * {@code javax.xml.catalog.resolve} is specified as {@code strict} 161 */ 162 @Override 163 public Source resolve(String href, String base); 164 165 /** 166 * Implements {@link javax.xml.stream.XMLResolver}. For the purpose of resolving 167 * {@code publicId} and {@code systemId}, this method is equivalent to 168 * {@link #resolveEntity(java.lang.String, java.lang.String) }. 169 * <p> 170 * The {@code systemId} will be used literally, with no attempt to be made 171 * absolute to the {@code baseUri}. The {@code baseUri} and {@code namespace} 172 * are not used in the search for a match in a catalog. However, a relative 173 * {@code systemId} in an xml source may have been made absolute by the parser 174 * with the {@code baseURI}, thus making it unable to find a {@code system} entry. 175 * In such a case, a {@code systemSuffix} entry is recommended over a 176 * {@code system} entry. 177 * 178 * @param publicId the public identifier of the external entity being 179 * referenced, or null if none was supplied 180 * 181 * @param systemId the system identifier of the external entity being 182 * referenced. A system identifier is required on all external entities. XML 183 * requires a system identifier on all external entities, so this value is 184 * always specified. 185 * @param baseUri the absolute base URI, not used by the CatalogResolver 186 * @param namespace the namespace of the entity to resolve, not used by the 187 * CatalogResolver. 188 * 189 * @return an {@link java.io.InputStream} object if a mapping is found; null 190 * if no mapping is found and the {@code javax.xml.catalog.resolve} property 191 * is set to {@code continue} or {@code ignore}. Note that for XMLResolver, 192 * it is not possible to ignore a reference, {@code ignore} is therefore 193 * treated the same as {@code continue}. 194 * 195 * @throws CatalogException if no mapping is found and 196 * {@code javax.xml.catalog.resolve} is specified as {@code strict} 197 */ 198 @Override 199 public InputStream resolveEntity(String publicId, String systemId, 200 String baseUri, String namespace); 201 202 /** 203 * Implements {@link org.w3c.dom.ls.LSResourceResolver}. For the purpose of 204 * resolving {@code publicId} and {@code systemId}, this method is equivalent 205 * to {@link #resolveEntity(java.lang.String, java.lang.String) }. 206 * <p> 207 * The {@code systemId} will be used literally, with no attempt to be made 208 * absolute to the {@code baseUri}. The {@code baseUri}, {@code namespaceUri} 209 * and {@code type} are not used in the search for a match in a catalog. 210 * However, a relative {@code systemId} in a source may have been made absolute 211 * by the parser with the {@code baseURI}, thus making it unable to find a 212 * {@code system} entry. In such a case, a {@code systemSuffix} entry is 213 * recommended over a {@code system} entry. 214 * 215 * @param type the type of the resource being resolved, 216 * not used by the CatalogResolver 217 * @param namespaceUri the namespace of the resource being resolved, 218 * not used by the CatalogResolver 219 * @param publicId the public identifier of the external entity being 220 * referenced, or {@code null} if no public identifier was 221 * supplied or if the resource is not an entity. 222 * @param systemId the system identifier, an URI reference of the 223 * external resource being referenced 224 * @param baseUri the absolute base URI, not used by the CatalogResolver 225 * 226 * @return a {@link org.w3c.dom.ls.LSInput} object if a mapping is found; null 227 * if no mapping is found and the {@code javax.xml.catalog.resolve} property 228 * is set to {@code continue} or {@code ignore}. Note that for 229 * {@link org.w3c.dom.ls.LSResourceResolver}, it is not possible to ignore a 230 * reference, {@code ignore} is therefore treated the same as {@code continue}. 231 * 232 * @throws CatalogException if no mapping is found and 233 * {@code javax.xml.catalog.resolve} is specified as {@code strict} 234 */ 235 @Override 236 public LSInput resolveResource(String type, String namespaceUri, 237 String publicId, String systemId, String baseUri); 238 239} 240