OSDN Git Service

remove subversion keyword
[jindolf/Jindolf.git] / src / main / java / jp / sourceforge / jindolf / XmlResourceResolver.java
1 /*\r
2  * xml resource resolver\r
3  *\r
4  * License : The MIT License\r
5  * Copyright(c) 2009 olyutorskii\r
6  */\r
7 \r
8 package jp.sourceforge.jindolf;\r
9 \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
23 \r
24 /**\r
25  * URL変換マップに従い、XML文書からの外部参照をリダイレクトする。\r
26  * 相対URIはこのクラスをベースに解決される。\r
27  * 主な用途は外部スキーマのリソース化など。\r
28  */\r
29 public class XmlResourceResolver\r
30         implements LSResourceResolver,\r
31                    EntityResolver{\r
32 \r
33     private static final URI EMPTY_URI = URI.create("");\r
34 \r
35     /**\r
36      * 絶対URIと相対URIを合成したURIを返す。\r
37      * 正規化も行われる。\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
43      */\r
44     protected static URI buildBaseRelativeURI(String base, String relative)\r
45             throws URISyntaxException,\r
46                    IllegalArgumentException {\r
47         URI baseURI = null;\r
48         if(base != null){\r
49             baseURI = new URI(base);\r
50             if( ! baseURI.isAbsolute() ) throw new IllegalArgumentException();\r
51         }\r
52 \r
53         URI relativeURI = EMPTY_URI;\r
54         if(relative != null){\r
55             relativeURI = new URI(relative);\r
56         }\r
57 \r
58         URI resultURI;\r
59         if(baseURI == null || relativeURI.isAbsolute()){\r
60             resultURI = relativeURI;\r
61         }else{\r
62             resultURI = baseURI.resolve(relativeURI);\r
63         }\r
64 \r
65         if( ! resultURI.isAbsolute() ) throw new IllegalArgumentException();\r
66 \r
67         resultURI = resultURI.normalize();\r
68 \r
69         return resultURI;\r
70     }\r
71 \r
72     /**\r
73      * LSInput実装を生成する。\r
74      * @return LSInput実装\r
75      */\r
76     public static LSInput createLSInput(){\r
77         LSInput input = new LSInputImpl();\r
78         return input;\r
79     }\r
80 \r
81     private final Map<URI, URI> uriMap = XmlResource.RESOLVE_MAP;\r
82 \r
83     /**\r
84      * コンストラクタ。\r
85      */\r
86     public XmlResourceResolver(){\r
87         super();\r
88         return;\r
89     }\r
90 \r
91     /**\r
92      * 変換後のリソースの入力ストリームを得る。\r
93      * @param originalURI オリジナルURI\r
94      * @return 入力ストリーム\r
95      * @throws java.io.IOException 入出力エラー\r
96      */\r
97     public InputStream getXMLResourceAsStream(URI originalURI)\r
98             throws IOException{\r
99         URI resourceURI = this.uriMap.get(originalURI.normalize());\r
100         URL resourceURL = resourceURI.toURL();\r
101         InputStream is = resourceURL.openStream();\r
102 \r
103         return is;\r
104     }\r
105 \r
106     /**\r
107      * {@inheritDoc}\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
115      */\r
116     public LSInput resolveResource(String type,\r
117                                      String namespaceURI,\r
118                                      String publicId,\r
119                                      String systemId,\r
120                                      String baseURI ){\r
121         if(systemId == null) return null;\r
122 \r
123         URI originalURI;\r
124         try{\r
125             originalURI = buildBaseRelativeURI(baseURI, systemId);\r
126         }catch(URISyntaxException e){\r
127             return null;\r
128         }\r
129 \r
130         InputStream is;\r
131         try{\r
132             is = getXMLResourceAsStream(originalURI);\r
133         }catch(IOException e){\r
134             return null;\r
135         }\r
136 \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
142 \r
143         return input;\r
144     }\r
145 \r
146     /**\r
147      * {@inheritDoc}\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
154      */\r
155     public InputSource resolveEntity(String publicId, String systemId)\r
156             throws SAXException, IOException{\r
157         if(systemId == null) return null;\r
158 \r
159         URI originalUri;\r
160         try{\r
161             originalUri = new URI(systemId);\r
162         }catch(URISyntaxException e){\r
163             return null;\r
164         }\r
165 \r
166         InputStream is = getXMLResourceAsStream(originalUri);\r
167 \r
168         InputSource source = new InputSource(is);\r
169         source.setPublicId(publicId);\r
170         source.setSystemId(systemId);\r
171 \r
172         return source;\r
173     }\r
174 \r
175     /**\r
176      * JRE1.5用LSInput実装。\r
177      * JRE1.6なら\r
178      * org.w3c.dom.ls.DOMImplementationLS#createLSInput()\r
179      * で生成可能かも。\r
180      */\r
181     public static class LSInputImpl implements LSInput{\r
182 \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
191 \r
192         /**\r
193          * コンストラクタ。\r
194          */\r
195         public LSInputImpl(){\r
196             super();\r
197             return;\r
198         }\r
199 \r
200         /**\r
201          * {@inheritDoc}\r
202          * @return {@inheritDoc}\r
203          */\r
204         public String getBaseURI(){\r
205             return this.baseURI;\r
206         }\r
207 \r
208         /**\r
209          * {@inheritDoc}\r
210          * @param baseURI {@inheritDoc}\r
211          */\r
212         public void setBaseURI(String baseURI){\r
213             this.baseURI = baseURI;\r
214             return;\r
215         }\r
216 \r
217         /**\r
218          * {@inheritDoc}\r
219          * @return {@inheritDoc}\r
220          */\r
221         public InputStream getByteStream(){\r
222             return this.byteStream;\r
223         }\r
224 \r
225         /**\r
226          * {@inheritDoc}\r
227          * @param byteStream {@inheritDoc}\r
228          */\r
229         public void setByteStream(InputStream byteStream){\r
230             this.byteStream = byteStream;\r
231         }\r
232 \r
233         /**\r
234          * {@inheritDoc}\r
235          * @return {@inheritDoc}\r
236          */\r
237         public boolean getCertifiedText(){\r
238             return this.certifiedText;\r
239         }\r
240 \r
241         /**\r
242          * {@inheritDoc}\r
243          * @param certifiedText {@inheritDoc}\r
244          */\r
245         public void setCertifiedText(boolean certifiedText){\r
246             this.certifiedText = certifiedText;\r
247             return;\r
248         }\r
249 \r
250         /**\r
251          * {@inheritDoc}\r
252          * @return {@inheritDoc}\r
253          */\r
254         public Reader getCharacterStream(){\r
255             return this.characterStream;\r
256         }\r
257 \r
258         /**\r
259          * {@inheritDoc}\r
260          * @param characterStream {@inheritDoc}\r
261          */\r
262         public void setCharacterStream(Reader characterStream){\r
263             this.characterStream = characterStream;\r
264         }\r
265 \r
266         /**\r
267          * {@inheritDoc}\r
268          * @return {@inheritDoc}\r
269          */\r
270         public String getEncoding(){\r
271             return this.encoding;\r
272         }\r
273 \r
274         /**\r
275          * {@inheritDoc}\r
276          * @param encoding {@inheritDoc}\r
277          */\r
278         public void setEncoding(String encoding){\r
279             this.encoding = encoding;\r
280             return;\r
281         }\r
282 \r
283         /**\r
284          * {@inheritDoc}\r
285          * @return {@inheritDoc}\r
286          */\r
287         public String getPublicId(){\r
288             return this.publicId;\r
289         }\r
290 \r
291         /**\r
292          * {@inheritDoc}\r
293          * @param publicId {@inheritDoc}\r
294          */\r
295         public void setPublicId(String publicId){\r
296             this.publicId = publicId;\r
297             return;\r
298         }\r
299 \r
300         /**\r
301          * {@inheritDoc}\r
302          * @return {@inheritDoc}\r
303          */\r
304         public String getStringData(){\r
305             return this.stringData;\r
306         }\r
307 \r
308         /**\r
309          * {@inheritDoc}\r
310          * @param stringData {@inheritDoc}\r
311          */\r
312         public void setStringData(String stringData){\r
313             this.stringData = stringData;\r
314             return;\r
315         }\r
316 \r
317         /**\r
318          * {@inheritDoc}\r
319          * @return {@inheritDoc}\r
320          */\r
321         public String getSystemId(){\r
322             return this.systemId;\r
323         }\r
324 \r
325         /**\r
326          * {@inheritDoc}\r
327          * @param systemId {@inheritDoc}\r
328          */\r
329         public void setSystemId(String systemId){\r
330             this.systemId = systemId;\r
331             return;\r
332         }\r
333 \r
334     }\r
335 \r
336     // TODO OASIS XML Catalog などと調和したい。\r
337 }\r