2 * xml resource resolver
\r
4 * License : The MIT License
\r
5 * Copyright(c) 2009 olyutorskii
\r
8 package jp.sourceforge.jindolf;
\r
10 import java.io.IOException;
\r
11 import java.io.InputStream;
\r
12 import java.io.Reader;
\r
13 import java.net.URI;
\r
14 import java.net.URISyntaxException;
\r
15 import java.net.URL;
\r
16 import java.util.Map;
\r
17 import jp.sourceforge.jindolf.corelib.XmlResource;
\r
18 import org.w3c.dom.ls.LSInput;
\r
19 import org.w3c.dom.ls.LSResourceResolver;
\r
20 import org.xml.sax.EntityResolver;
\r
21 import org.xml.sax.InputSource;
\r
22 import org.xml.sax.SAXException;
\r
25 * URL変換マップに従い、XML文書からの外部参照をリダイレクトする。
\r
26 * 相対URIはこのクラスをベースに解決される。
\r
27 * 主な用途は外部スキーマのリソース化など。
\r
29 public class XmlResourceResolver
\r
30 implements LSResourceResolver,
\r
33 private static final URI EMPTY_URI = URI.create("");
\r
36 * 絶対URIと相対URIを合成したURIを返す。
\r
38 * @param base 絶対URIでなければならない。nullでもよい。
\r
39 * @param relative 絶対URIでもよいがその場合baseは無視される。null可。
\r
40 * @return 合成結果のURLオブジェクト。必ず絶対URIになる。
\r
41 * @throws java.net.URISyntaxException URIとして変。
\r
42 * @throws java.lang.IllegalArgumentException 絶対URIが生成できない。
\r
44 protected static URI buildBaseRelativeURI(String base, String relative)
\r
45 throws URISyntaxException,
\r
46 IllegalArgumentException {
\r
49 baseURI = new URI(base);
\r
50 if( ! baseURI.isAbsolute() ) throw new IllegalArgumentException();
\r
53 URI relativeURI = EMPTY_URI;
\r
54 if(relative != null){
\r
55 relativeURI = new URI(relative);
\r
59 if(baseURI == null || relativeURI.isAbsolute()){
\r
60 resultURI = relativeURI;
\r
62 resultURI = baseURI.resolve(relativeURI);
\r
65 if( ! resultURI.isAbsolute() ) throw new IllegalArgumentException();
\r
67 resultURI = resultURI.normalize();
\r
76 public static LSInput createLSInput(){
\r
77 LSInput input = new LSInputImpl();
\r
81 private final Map<URI, URI> uriMap = XmlResource.RESOLVE_MAP;
\r
86 public XmlResourceResolver(){
\r
92 * 変換後のリソースの入力ストリームを得る。
\r
93 * @param originalURI オリジナルURI
\r
95 * @throws java.io.IOException 入出力エラー
\r
97 public InputStream getXMLResourceAsStream(URI originalURI)
\r
99 URI resourceURI = this.uriMap.get(originalURI.normalize());
\r
100 URL resourceURL = resourceURI.toURL();
\r
101 InputStream is = resourceURL.openStream();
\r
108 * URL変換したあとの入力ソースを返す。
\r
109 * @param type {@inheritDoc}
\r
110 * @param namespaceURI {@inheritDoc}
\r
111 * @param publicId {@inheritDoc}
\r
112 * @param systemId {@inheritDoc}
\r
113 * @param baseURI {@inheritDoc}
\r
114 * @return {@inheritDoc}
\r
116 public LSInput resolveResource(String type,
\r
117 String namespaceURI,
\r
121 if(systemId == null) return null;
\r
125 originalURI = buildBaseRelativeURI(baseURI, systemId);
\r
126 }catch(URISyntaxException e){
\r
132 is = getXMLResourceAsStream(originalURI);
\r
133 }catch(IOException e){
\r
137 LSInput input = createLSInput();
\r
138 input.setBaseURI(baseURI);
\r
139 input.setPublicId(publicId);
\r
140 input.setSystemId(systemId);
\r
141 input.setByteStream(is);
\r
148 * URL変換したあとの入力ソースを返す。
\r
149 * @param publicId {@inheritDoc}
\r
150 * @param systemId {@inheritDoc}
\r
151 * @return {@inheritDoc}
\r
152 * @throws org.xml.sax.SAXException {@inheritDoc}
\r
153 * @throws java.io.IOException {@inheritDoc}
\r
155 public InputSource resolveEntity(String publicId, String systemId)
\r
156 throws SAXException, IOException{
\r
157 if(systemId == null) return null;
\r
161 originalUri = new URI(systemId);
\r
162 }catch(URISyntaxException e){
\r
166 InputStream is = getXMLResourceAsStream(originalUri);
\r
168 InputSource source = new InputSource(is);
\r
169 source.setPublicId(publicId);
\r
170 source.setSystemId(systemId);
\r
176 * JRE1.5用LSInput実装。
\r
178 * org.w3c.dom.ls.DOMImplementationLS#createLSInput()
\r
181 public static class LSInputImpl implements LSInput{
\r
183 private String baseURI = null;
\r
184 private InputStream byteStream = null;
\r
185 private boolean certifiedText = false;
\r
186 private Reader characterStream = null;
\r
187 private String encoding = null;
\r
188 private String publicId = null;
\r
189 private String stringData = null;
\r
190 private String systemId = null;
\r
195 public LSInputImpl(){
\r
202 * @return {@inheritDoc}
\r
204 public String getBaseURI(){
\r
205 return this.baseURI;
\r
210 * @param baseURI {@inheritDoc}
\r
212 public void setBaseURI(String baseURI){
\r
213 this.baseURI = baseURI;
\r
219 * @return {@inheritDoc}
\r
221 public InputStream getByteStream(){
\r
222 return this.byteStream;
\r
227 * @param byteStream {@inheritDoc}
\r
229 public void setByteStream(InputStream byteStream){
\r
230 this.byteStream = byteStream;
\r
235 * @return {@inheritDoc}
\r
237 public boolean getCertifiedText(){
\r
238 return this.certifiedText;
\r
243 * @param certifiedText {@inheritDoc}
\r
245 public void setCertifiedText(boolean certifiedText){
\r
246 this.certifiedText = certifiedText;
\r
252 * @return {@inheritDoc}
\r
254 public Reader getCharacterStream(){
\r
255 return this.characterStream;
\r
260 * @param characterStream {@inheritDoc}
\r
262 public void setCharacterStream(Reader characterStream){
\r
263 this.characterStream = characterStream;
\r
268 * @return {@inheritDoc}
\r
270 public String getEncoding(){
\r
271 return this.encoding;
\r
276 * @param encoding {@inheritDoc}
\r
278 public void setEncoding(String encoding){
\r
279 this.encoding = encoding;
\r
285 * @return {@inheritDoc}
\r
287 public String getPublicId(){
\r
288 return this.publicId;
\r
293 * @param publicId {@inheritDoc}
\r
295 public void setPublicId(String publicId){
\r
296 this.publicId = publicId;
\r
302 * @return {@inheritDoc}
\r
304 public String getStringData(){
\r
305 return this.stringData;
\r
310 * @param stringData {@inheritDoc}
\r
312 public void setStringData(String stringData){
\r
313 this.stringData = stringData;
\r
319 * @return {@inheritDoc}
\r
321 public String getSystemId(){
\r
322 return this.systemId;
\r
327 * @param systemId {@inheritDoc}
\r
329 public void setSystemId(String systemId){
\r
330 this.systemId = systemId;
\r
336 // TODO OASIS XML Catalog などと調和したい。
\r