OSDN Git Service

a167e86b98a08728bb2f7687a9423fdf52a3fc47
[mikutoga/Pmd2XML.git] / src / main / java / jp / sfjp / mikutoga / pmd / xml / LocalSchema.java
1 /*
2  * local xml schema for PMD-XML
3  *
4  * License : The MIT License
5  * Copyright(c) 2013 MikuToga Partners
6  */
7
8 package jp.sfjp.mikutoga.pmd.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.LinkedList;
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 jp.sourceforge.mikutoga.xml.XmlResourceResolver;
24 import org.xml.sax.SAXException;
25
26 /**
27  * XML用各種スキーマのローカル参照解決基盤。
28  */
29 public abstract class LocalSchema {
30
31     /**
32      * コンストラクタ。
33      */
34     protected LocalSchema(){
35         super();
36         return;
37     }
38
39
40     /**
41      * XML Schema 用のスキーマファクトリを返す。
42      * @return スキーマファクトリ
43      */
44     private static SchemaFactory newSchemaFactory(){
45         SchemaFactory schemaFactory =
46                 SchemaFactory.newInstance(
47                     XMLConstants.W3C_XML_SCHEMA_NS_URI
48                 );
49
50 //      schemaFactory.setFeature(name, value);
51 //      schemaFactory.setProperty(name, object);
52
53         schemaFactory.setErrorHandler(BotherHandler.HANDLER);
54
55         return schemaFactory;
56     }
57
58     /**
59      * ローカルスキーマをロードする。
60      * <p>任意のリゾルバを指定可能
61      * @param resolver リゾルバ
62      * @param lscs ローカルスキーマ情報の配列
63      * @return スキーマ
64      */
65     public static Schema newSchema(XmlResourceResolver resolver,
66                                     LocalSchema... lscs ){
67         List<Source> sourceList = new LinkedList<Source>();
68         for(LocalSchema lsc : lscs){
69             if(lsc == null) continue;
70             lsc.appendToUriMap(resolver);
71
72             Source local = lsc.getLocalSchemaSource();
73             if(local == null) continue;
74             sourceList.add(local);
75         }
76
77         SchemaFactory schemaFactory = newSchemaFactory();
78         schemaFactory.setResourceResolver(resolver);
79
80         Source[] sources = new Source[sourceList.size()];
81         sourceList.toArray(sources);
82
83         Schema result;
84         try{
85             if(sources.length <= 0){
86                 result = schemaFactory.newSchema();
87             }else{
88                 result = schemaFactory.newSchema(sources);
89             }
90         }catch(SAXException e){   // Build error
91             assert false;
92             throw new AssertionError(e);
93         }
94
95         return result;
96     }
97
98     /**
99      * オリジナル版スキーマ定義のURIを返す。
100      * <p>nullを返す場合は
101      * スキーマの自動判定&ダウンロードが求められていると見なされる。
102      * <p>このクラスの実装では常にnullを返す。
103      * @return オリジナル版スキーマのURL。
104      */
105     public abstract URI getOriginalSchema();
106
107     /**
108      * ローカルリソース版スキーマ定義のURIを返す。
109      * <p>nullを返す場合は
110      * スキーマの自動判定&ダウンロードが求められていると見なされる。
111      * <p>このクラスの実装では常にnullを返す。
112      * @return ローカルリソース版スキーマのURL。
113      */
114     public abstract URI getLocalSchema();
115
116     /**
117      * スキーマのSourceを返す。
118      * <p>ローカルスキーマのSourceを返す。
119      * @return Source 見つからなければnull
120      */
121     public Source getLocalSchemaSource(){
122         URI uri;
123
124         uri = getLocalSchema();
125         if(uri == null) return null;
126
127         URL url;
128         try{
129             url = uri.toURL();
130         }catch(MalformedURLException e){      // Build error
131             assert false;
132             throw new AssertionError(e);
133         }
134
135         InputStream is;
136         try{
137             is = url.openStream();
138         }catch(IOException e){              // Build error
139             assert false;
140             throw new AssertionError(e);
141         }
142         is = new BufferedInputStream(is);
143
144         Source result = new StreamSource(is);
145
146         return result;
147     }
148
149     /**
150      * ローカルで解決可能なリソース参照をリゾルバに追加登録する。
151      * @param resolver リゾルバ
152      */
153     public void appendToUriMap(XmlResourceResolver resolver){
154         URI original = getOriginalSchema();
155         URI local    = getLocalSchema();
156
157         if(original == null) return;
158
159         resolver.putRedirected(original, local);
160
161         return;
162     }
163
164 }