OSDN Git Service

ローカルスキーマ参照処理の共通化
authorOlyutorskii <olyutorskii@users.osdn.me>
Thu, 25 Apr 2013 15:39:51 +0000 (00:39 +0900)
committerOlyutorskii <olyutorskii@users.osdn.me>
Thu, 25 Apr 2013 15:39:51 +0000 (00:39 +0900)
src/main/java/jp/sourceforge/mikutoga/xml/LocalSchema.java [new file with mode: 0644]

diff --git a/src/main/java/jp/sourceforge/mikutoga/xml/LocalSchema.java b/src/main/java/jp/sourceforge/mikutoga/xml/LocalSchema.java
new file mode 100644 (file)
index 0000000..92da58a
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ * local xml schema
+ *
+ * License : The MIT License
+ * Copyright(c) 2013 MikuToga Partners
+ */
+
+package jp.sourceforge.mikutoga.xml;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URL;
+import java.util.LinkedList;
+import java.util.List;
+import javax.xml.XMLConstants;
+import javax.xml.transform.Source;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+import org.xml.sax.SAXException;
+
+/**
+ * XML用各種スキーマのローカル参照解決基盤。
+ */
+public abstract class LocalSchema {
+
+    /**
+     * コンストラクタ。
+     */
+    protected LocalSchema(){
+        super();
+        return;
+    }
+
+
+    /**
+     * XML Schema 用のスキーマファクトリを返す。
+     * @return スキーマファクトリ
+     */
+    private static SchemaFactory newSchemaFactory(){
+        SchemaFactory schemaFactory =
+                SchemaFactory.newInstance(
+                    XMLConstants.W3C_XML_SCHEMA_NS_URI
+                );
+
+//      schemaFactory.setFeature(name, value);
+//      schemaFactory.setProperty(name, object);
+
+        schemaFactory.setErrorHandler(BotherHandler.HANDLER);
+
+        return schemaFactory;
+    }
+
+    /**
+     * ローカルスキーマをロードする。
+     * <p>任意のリゾルバを指定可能
+     * @param resolver リゾルバ
+     * @param lscs ローカルスキーマ情報の配列
+     * @return スキーマ
+     */
+    public static Schema newSchema(XmlResourceResolver resolver,
+                                    LocalSchema... lscs ){
+        List<Source> sourceList = new LinkedList<Source>();
+        for(LocalSchema lsc : lscs){
+            if(lsc == null) continue;
+            lsc.appendToUriMap(resolver);
+
+            Source local = lsc.getLocalSchemaSource();
+            if(local == null) continue;
+            sourceList.add(local);
+        }
+
+        SchemaFactory schemaFactory = newSchemaFactory();
+        schemaFactory.setResourceResolver(resolver);
+
+        Source[] sources = new Source[sourceList.size()];
+        sourceList.toArray(sources);
+
+        Schema result;
+        try{
+            if(sources.length <= 0){
+                result = schemaFactory.newSchema();
+            }else{
+                result = schemaFactory.newSchema(sources);
+            }
+        }catch(SAXException e){   // Build error
+            assert false;
+            throw new AssertionError(e);
+        }
+
+        return result;
+    }
+
+    /**
+     * オリジナル版スキーマ定義のURIを返す。
+     * <p>nullを返す場合は
+     * スキーマの自動判定&ダウンロードが求められていると見なされる。
+     * <p>このクラスの実装では常にnullを返す。
+     * @return オリジナル版スキーマのURL。
+     */
+    public abstract URI getOriginalSchema();
+
+    /**
+     * ローカルリソース版スキーマ定義のURIを返す。
+     * <p>nullを返す場合は
+     * スキーマの自動判定&ダウンロードが求められていると見なされる。
+     * <p>このクラスの実装では常にnullを返す。
+     * @return ローカルリソース版スキーマのURL。
+     */
+    public abstract URI getLocalSchema();
+
+    /**
+     * スキーマのSourceを返す。
+     * <p>ローカルスキーマのSourceを返す。
+     * @return Source 見つからなければnull
+     */
+    public Source getLocalSchemaSource(){
+        URI uri;
+
+        uri = getLocalSchema();
+        if(uri == null) return null;
+
+        URL url;
+        try{
+            url = uri.toURL();
+        }catch(MalformedURLException e){      // Build error
+            assert false;
+            throw new AssertionError(e);
+        }
+
+        InputStream is;
+        try{
+            is = url.openStream();
+        }catch(IOException e){              // Build error
+            assert false;
+            throw new AssertionError(e);
+        }
+        is = new BufferedInputStream(is);
+
+        Source result = new StreamSource(is);
+
+        return result;
+    }
+
+    /**
+     * ローカルで解決可能なリソース参照をリゾルバに追加登録する。
+     * @param resolver リゾルバ
+     */
+    public void appendToUriMap(XmlResourceResolver resolver){
+        URI original = getOriginalSchema();
+        URI local    = getLocalSchema();
+
+        if(original == null) return;
+
+        resolver.putRedirected(original, local);
+
+        return;
+    }
+
+}