    001/*
    002 * Copyright (c) 2009 The openGion Project.
    003 *
    004 * Licensed under the Apache License, Version 2.0 (the "License");
    005 * you may not use this file except in compliance with the License.
    006 * You may obtain a copy of the License at
    007 *
    008 *     http://www.apache.org/licenses/LICENSE-2.0
    009 *
    010 * Unless required by applicable law or agreed to in writing, software
    011 * distributed under the License is distributed on an "AS IS" BASIS,
    012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
    013 * either express or implied. See the License for the specific language
    014 * governing permissions and limitations under the License.
    015 */
    016package org.opengion.fukurou.xml;
    017
    018import java.io.File ;
    019import java.io.Writer ;
    020import java.io.BufferedWriter ;
    021import java.io.OutputStreamWriter ;
    022import java.io.FileOutputStream ;
    023import java.io.IOException ;
    024
    025import javax.xml.transform.dom.DOMSource ;
    026import javax.xml.transform.stream.StreamResult ;
    027import javax.xml.transform.Transformer ;
    028import javax.xml.transform.TransformerFactory ;
    029import javax.xml.transform.TransformerException ;
    030import javax.xml.transform.TransformerConfigurationException ;
    031import javax.xml.transform.OutputKeys ;
    032
    033import javax.xml.parsers.DocumentBuilder ;
    034import javax.xml.parsers.DocumentBuilderFactory ;
    035import javax.xml.parsers.ParserConfigurationException ;
    036import org.xml.sax.SAXException ;
    037import org.opengion.fukurou.util.Closer;
    038import org.w3c.dom.Document ;
    039
    040/**
    041 * XMLファイルを読み取って、Document オブジェクトを取得する、ユーティリティークラスです。
    042 *
    043 * javax.xml.parsers および、org.w3c.dom の簡易処理を行います。
    044 * read で、Document を読み込み、write で、ファイルに書き出します。
    045 * なお、書き出しに関しては、UTF-8 固定で、かつ、Transformer で行いますので、
    046 * 属性の並び順は、保障されません。(つまり、簡易的な書き出し機能です。)
    047 *
    048 * @og.rev 5.1.7.0 (2010/06/01) 新規作成
    049 *
    050 * @version  5.0
    051 * @author   Kazuhiko Hasegawa
    052 * @since    JDK6.0,
    053 */
    054
    055public final class DomParser {
    056
    057        /**
    058         * プライベート コンストラクター
    059         *
    060         * オブジェクトの作成を拒否します。
    061         */
    062        private DomParser() {}
    063
    064        /**
    065         * XMLファイルを読み込み、org.w3c.dom.Documentを返す
    066         * @param       aFile   XMLファイル
    067         *
    068         * @return      構築した Document( nullは読み込み失敗 )
    069         */
    070        public static Document read( final File aFile ) {
    071
    072                Document document = null;
    073                try {
    074                        //----------------------------------------------------
    075                        // step1. DocumentBuilderを構築する
    076                        //----------------------------------------------------
    077                        DocumentBuilderFactory bfactory = DocumentBuilderFactory.newInstance();
    078                        DocumentBuilder builder = bfactory.newDocumentBuilder();
    079
    080                        //----------------------------------------------------
    081                        // step2. XMLファイルを読み込んで、Documentを構築する
    082                        //----------------------------------------------------
    083                        document = builder.parse( aFile );
    084
    085                } catch (ParserConfigurationException ex) {
    086                        System.err.println( ex.getMessage() );
    087                        ex.printStackTrace();
    088                } catch (SAXException ex) {
    089                        // 文法エラーが発生した場合
    090                        System.err.println( ex.getMessage() );
    091                        ex.printStackTrace();
    092                } catch (IOException ex) {
    093                        // ファイルが読み込めなかった場合
    094                        System.err.println( ex.getMessage() );
    095                        ex.printStackTrace();
    096                }
    097
    098                // 完了
    099                return document;
    100        }
    101
    102        /**
    103         * Documentを指定ファイルに保存する
    104         * @param aFile 保存先ファイル
    105         * @param aDocument Documentインスタンス
    106         *
    107         * @og.rev 5.1.9.0 (2010/08/01) Closeされないバグを修正
    108         * @og.rev 5.6.6.0 (2013/07/05) 若干のインデックス（らしきもの）を入れます
    109         */
    110        public static void write( final File aFile, final Document aDocument ){
    111                Writer out = null;
    112                try {
    113                        //---------------------------------
    114                        // step1. Transformerの準備
    115                        //---------------------------------
    116                        TransformerFactory tfactory = TransformerFactory.newInstance();
    117                        Transformer transformer = tfactory.newTransformer();
    118
    119                        //---------------------------------
    120                        // step2. Transformerの動作設定
    121                        //---------------------------------
    122                        transformer.setOutputProperty(OutputKeys.INDENT,   "yes");
    123                        transformer.setOutputProperty(OutputKeys.METHOD,   "xml");                      // 5.6.6.0 (2013/07/05)
    124
    125                        // 5.6.6.0 (2013/07/05) インデントを入れるには、OutputKeys.INDENT だけではだめ。
    126                        // Xalan の メインの xalan.jarじゃなくて、serializer.jar に入っている OutputPropertiesFactory が必要。
    127                        // transformer.setOutputPropert( org.apache.xml.serializer.OutputPropertiesFactory.S_KEY_INDENT_AMOUNT, "2" );
    128
    129                        // この為だけに、また、java の JAVA_HOME/jre/lib/ext を増やすのは嫌なので、OutputPropertiesFactory.S_KEY_INDENT_AMOUNT
    130                        // で作成している文字列を直接記述しちゃいます。良い子はマネしないでね。
    131                        transformer.setOutputProperty( "{http://xml.apache.org/xalan}indent-amount", "2" );
    132
    133                        transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
    134
    135                        //---------------------------------
    136                        // step3. Writerの準備
    137                        //---------------------------------
    138                        out = new BufferedWriter( new OutputStreamWriter( new FileOutputStream(aFile),"UTF-8" )) ;
    139
    140                        //---------------------------------
    141                        // step4. 書き出し
    142                        //---------------------------------
    143                        transformer.transform( new DOMSource( aDocument ), new StreamResult( out ) );
    144
    145                } catch (TransformerConfigurationException ex) {
    146                        System.err.println( ex.getMessage() );
    147                        ex.printStackTrace();
    148                } catch (TransformerException ex) {
    149                        // 書き出しエラー発生
    150                        System.err.println( ex.getMessage() );
    151                        ex.printStackTrace();
    152                } catch (IOException ex) {
    153                        // ファイルが読み込めなかった場合
    154                        System.err.println( ex.getMessage() );
    155                        ex.printStackTrace();
    156                // 5.1.9.0 (2010/08/01) Closeされないバグを修正
    157                } finally {
    158                        Closer.ioClose( out );
    159                }
    160        }
    161}