倭マン's BLOG

くだらない日々の日記書いてます。 たまにプログラミング関連の記事書いてます。 書いてます。

システムリソースからスタイルシートを読み込む (3) : SystemStylesheetLoader

前回のサンプルコードでは、スタイルシートを読み込む手順 (Main クラスの main() メソッド)において、システムリソースの読み込みの基点となる「BASEDIR」変数が2箇所(ステップ2とステップ3)で参照されています。 この整合性は保守をする人にとって無駄な労力なので、「BASEDIR」を一度指定するだけでいいようにしましょう。 加えて、Transformer オブジェクトをもっと手軽に取得できるようにします。

このために、org.sample.SystemStylesheetLoader というクラスを作成します。

SystemStylesheetLoader のサンプルコード


SystemStylesheetLoader は private フィールドとして、システムリソースの読み込みの基点となる「basedir (String)」と、Transformer のインスタンスを生成するための「factory (TransformerFactory)」 を持ち、Transformer オブジェクトを生成するメソッド「newTransformer()」が定義されています:

package org.sample;

import java.io.InputStream;
import javax.xml.transform.*;
import javax.xml.transform.stream.StreamSource;

public class SystemStylesheetLoader {

    private final String basedir;
    private final TransformerFactory factory;
    
    public SystemStylesheetLoader(String basedir){
        if(basedir.endsWith("/"))
            this.basedir = basedir;
        else
            this.basedir = basedir+"/";
        
        this.factory = TransformerFactory.newInstance();
        this.factory.setURIResolver(new SystemResourceURIResolver(this.basedir));
    }

    public Transformer newTransformer(String stylesheet)
            throws TransformerConfigurationException{
        InputStream is = ClassLoader.getSystemResourceAsStream(this.basedir+stylesheet);
        return this.factory.newTransformer(new StreamSource(is));
    }
    
    private static class SystemResourceURIResolver implements URIResolver{

        private final String basedir;

        SystemResourceURIResolver(String basedir){
            this.basedir = basedir;
        }

        public Source resolve(String href, String base)throws TransformerException {
            InputStream is = ClassLoader.getSystemResourceAsStream(this.basedir+href);
            return new StreamSource(is);
        }
    }
}

SystemStylesheetLoader の使用例


SystemStylesheetLoader の使用手順は以下の通り:

  1. SystemStylesheetLoader のインスタンスを生成する
  2. Transformer のインスタンスを生成する
  3. 変換を実行する

サンプルコードは次のようになります:

package org.sample;

import javax.xml.transform.Transformer;
import javax.xml.transform.stream.*;

public class Main{

    public void test()throws Exception{
        
        // 1. SystemStylesheetLoader のインスタンスを生成する
        SystemStylesheetLoader loader = new SystemStylesheetLoader("org/sample/resources/xsl/");

        // 2. Transformer のインスタンスを生成する
        Transformer transformer = loader.newTransformer("stylesheet.xsl");
        
        // 3. 変換を実行する
        transformer.transform(
                new StreamSource("sample.xml"), 
                new StreamResult(System.out));
    }
}