2 * xml resource resolver
4 * License : The MIT License
5 * Copyright(c) 2009 olyutorskii
8 package jp.sfjp.mikutoga.xml;
10 import java.io.BufferedInputStream;
11 import java.io.ByteArrayInputStream;
12 import java.io.IOException;
13 import java.io.InputStream;
15 import java.net.URISyntaxException;
17 import java.util.Collections;
18 import java.util.HashMap;
20 import org.w3c.dom.DOMImplementation;
21 import org.w3c.dom.bootstrap.DOMImplementationRegistry;
22 import org.w3c.dom.ls.DOMImplementationLS;
23 import org.w3c.dom.ls.LSInput;
24 import org.w3c.dom.ls.LSResourceResolver;
27 * register & redirect original URI to local resource contents.
29 public class XmlResourceResolver
30 implements LSResourceResolver{
32 private static final URI EMPTY_URI = URI.create("");
34 private static final DOMImplementationLS DOM_LS;
37 private final Map<URI, URI> uriMap;
42 DOM_LS = buildDomImplLS();
43 }catch( ClassNotFoundException
44 | IllegalAccessException
45 | InstantiationException e){
46 throw new ExceptionInInitializerError(e);
54 public XmlResourceResolver(){
58 map = new HashMap<>();
59 map = Collections.synchronizedMap(map);
67 * return DOMImplementationLS implement.
69 * @return DOMImplementationLS implement
70 * @throws ClassNotFoundException no class
71 * @throws InstantiationException no object
72 * @throws IllegalAccessException no grant
74 private static DOMImplementationLS buildDomImplLS() throws
75 ClassNotFoundException,
76 InstantiationException,
77 IllegalAccessException {
78 DOMImplementationRegistry domReg;
79 DOMImplementation domImp;
80 DOMImplementationLS domImpLs;
82 domReg = DOMImplementationRegistry.newInstance();
83 domImp = domReg.getDOMImplementation("LS 3.0");
85 Object feature = domImp.getFeature("LS", "3.0");
86 assert feature instanceof DOMImplementationLS;
87 domImpLs = (DOMImplementationLS) feature;
93 * return LSInput implement.
95 * @return LSInput implement
97 public static LSInput createLSInput(){
98 LSInput input = DOM_LS.createLSInput();
103 * merge base-uri text & relative URI text.
105 * @param base base URI text must be absolute or null.
106 * @param relative relative URI text.
107 * If absolute, base is ignored.
109 * @return merged absolute URI.
110 * @throws java.net.URISyntaxException illegal URI
111 * @throws java.lang.IllegalArgumentException result is not Absolute.
113 protected static URI buildBaseRelativeURI(String base, String relative)
114 throws URISyntaxException,
115 IllegalArgumentException {
118 baseURI = new URI(base);
119 if( ! baseURI.isAbsolute() ){
120 throw new IllegalArgumentException();
127 if(relative != null){
128 relativeURI = new URI(relative);
130 relativeURI = EMPTY_URI;
133 URI result = buildBaseRelativeURI(baseURI, relativeURI);
138 * merge base-uri & relative URI.
140 * @param baseURI base URI must be absolute or null.
141 * @param relativeURI relative URI. If absolute, baseURI is ignored.
142 * @return merged absolute URI.
143 * @throws java.lang.IllegalArgumentException result is not Absolute.
145 private static URI buildBaseRelativeURI(URI baseURI, URI relativeURI)
146 throws IllegalArgumentException {
149 if(baseURI == null || relativeURI.isAbsolute()){
150 resultURI = relativeURI;
152 resultURI = baseURI.resolve(relativeURI);
155 if( ! resultURI.isAbsolute() ){
156 throw new IllegalArgumentException();
159 resultURI = resultURI.normalize();
166 * map original URI & local resource URI.
168 * @param original original URI
169 * @param redirect local resource URI
171 public void putRedirected(URI original, URI redirect){
172 URI oridinalNorm = original.normalize();
173 URI redirectNorm = redirect.normalize();
175 this.uriMap.put(oridinalNorm, redirectNorm);
181 * add other resolver mapping.
183 * @param other resolver
185 public void putRedirected(XmlResourceResolver other){
186 this.uriMap.putAll(other.uriMap);
191 * get redirected local resource URI.
193 * @param original original URI
194 * @return mapped local resource URI. null if unmapped.
196 public URI getRedirected(URI original){
197 URI keyURI = original.normalize();
198 URI resourceURI = this.uriMap.get(keyURI);
203 * get redirected local input stream.
205 * @param originalURI original URI
206 * @return mapped local resource input stream.
207 * If no mapping, return zero-length data stream.
208 * @throws java.io.IOException local resource i/o error
210 private InputStream getXMLResourceAsStream(URI originalURI)
214 URI resourceURI = getRedirected(originalURI);
215 if(resourceURI == null){
216 result = new ByteArrayInputStream(new byte[0]);
218 URL resourceURL = resourceURI.toURL();
219 result = resourceURL.openStream();
222 result = new BufferedInputStream(result);
230 * <p>Return redirected local resource data.
232 * @param type {@inheritDoc}
233 * @param namespaceURI {@inheritDoc}
234 * @param publicId {@inheritDoc}
235 * @param systemId {@inheritDoc}
236 * @param baseURI {@inheritDoc}
237 * @return {@inheritDoc} LSInput of local resource.
238 * If no mapping, return zero-length data.
241 public LSInput resolveResource(
247 if(systemId == null) return null;
251 originalURI = buildBaseRelativeURI(baseURI, systemId);
252 }catch(URISyntaxException e){
254 throw new AssertionError(e);
259 is = getXMLResourceAsStream(originalURI);
260 }catch(IOException e){
262 throw new AssertionError(e);
265 LSInput input = createLSInput();
266 input.setBaseURI(baseURI);
267 input.setPublicId(publicId);
268 input.setSystemId(systemId);
269 input.setByteStream(is);