OSDN Git Service

Appendable対応
[mikutoga/TogaGem.git] / src / main / java / jp / sfjp / mikutoga / xml / SchemaUtil.java
1 /*
2  * xml schema utility
3  *
4  * License : The MIT License
5  * Copyright(c) 2013 MikuToga Partners
6  */
7
8 package jp.sfjp.mikutoga.xml;
9
10 import java.io.BufferedInputStream;
11 import java.io.IOException;
12 import java.io.InputStream;
13 import java.net.MalformedURLException;
14 import java.net.URI;
15 import java.net.URL;
16 import java.util.ArrayList;
17 import java.util.List;
18 import javax.xml.XMLConstants;
19 import javax.xml.transform.Source;
20 import javax.xml.transform.stream.StreamSource;
21 import javax.xml.validation.Schema;
22 import javax.xml.validation.SchemaFactory;
23 import org.w3c.dom.ls.LSResourceResolver;
24 import org.xml.sax.SAXException;
25
26 /**
27  * XMLスキーマの各種ビルダ。
28  */
29 public final class SchemaUtil {
30
31     /**
32      * 隠しコンストラクタ。
33      */
34     private SchemaUtil(){
35         assert false;
36         throw new AssertionError();
37     }
38
39
40     /**
41      * XML Schema 用のスキーマファクトリを返す。
42      * @return スキーマファクトリ
43      */
44     public static SchemaFactory newSchemaFactory(){
45         SchemaFactory result = newSchemaFactory(null);
46         return result;
47     }
48
49     /**
50      * XML Schema 用のスキーマファクトリを返す。
51      * @param resolver カスタムリゾルバ。nullも可。
52      * @return スキーマファクトリ
53      */
54     public static SchemaFactory newSchemaFactory(
55             LSResourceResolver resolver ){
56         SchemaFactory schemaFactory =
57                 SchemaFactory.newInstance(
58                     XMLConstants.W3C_XML_SCHEMA_NS_URI
59                 );
60
61 //      schemaFactory.setFeature(name, value);
62 //      schemaFactory.setProperty(name, object);
63
64         schemaFactory.setErrorHandler(BotherHandler.HANDLER);
65         schemaFactory.setResourceResolver(resolver);
66
67         return schemaFactory;
68     }
69
70     /**
71      * ローカルリソースをSourceに変換する。
72      * @param resource ローカルリソース
73      * @return XML Source
74      * @throws MalformedURLException 不正なURI
75      * @throws IOException オープンエラー
76      */
77     private static Source toLocalSource(LocalXmlResource resource)
78             throws MalformedURLException, IOException{
79         URI localUri = resource.getLocalResource();
80         URL localUrl = localUri.toURL();
81
82         InputStream is = localUrl.openStream();
83         is = new BufferedInputStream(is);
84
85         Source result = new StreamSource(is);
86         return result;
87     }
88
89     /**
90      * ローカルリソース群をSource群に変換する。
91      * @param resArray ローカルリソースURI並び
92      * @return XML Source並び
93      * @throws MalformedURLException 不正なURI
94      * @throws IOException オープンエラー
95      */
96     private static Source[] toLocalSourceArray(LocalXmlResource[] resArray)
97             throws MalformedURLException, IOException{
98         List<Source> sourceList = new ArrayList<Source>(resArray.length);
99
100         for(LocalXmlResource resource : resArray){
101             Source localSource = toLocalSource(resource);
102             sourceList.add(localSource);
103         }
104
105         Source[] result = new Source[sourceList.size()];
106         result = sourceList.toArray(result);
107         return result;
108     }
109
110     /**
111      * ローカルスキーマをロードする。
112      * <p>任意のリゾルバを指定可能
113      * @param resolver リゾルバ
114      * @param resArray ローカルスキーマ情報並び
115      * @return スキーマ
116      */
117     public static Schema newSchema(XmlResourceResolver resolver,
118                                     LocalXmlResource... resArray ){
119         for(LocalXmlResource resource : resArray){
120             resolver.putRedirected(resource);
121         }
122
123         Source[] sources;
124         try{
125             sources = toLocalSourceArray(resArray);
126         }catch(IOException e){                   // ビルド障害
127             assert false;
128             throw new AssertionError(e);
129         }
130
131         SchemaFactory schemaFactory = newSchemaFactory(resolver);
132
133         Schema result;
134         try{
135             if(sources.length <= 0){
136                 // ドキュメント埋め込みスキーマURLにリゾルバ経由でアクセス
137                 result = schemaFactory.newSchema();
138             }else{
139                 result = schemaFactory.newSchema(sources);
140             }
141         }catch(SAXException e){   // Build error
142             assert false;
143             throw new AssertionError(e);
144         }
145
146         // TODO: Sourceを閉めるのは誰の責務?
147
148         return result;
149     }
150
151 }