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//                      Writer out = new BufferedWriter( new OutputStreamWriter( new FileOutputStream(aFile),"UTF-8" )) ;
139                        out = new BufferedWriter( new OutputStreamWriter( new FileOutputStream(aFile),"UTF-8" )) ;
140
141                        //---------------------------------
142                        // step4. 書き出し
143                        //---------------------------------
144                        transformer.transform( new DOMSource( aDocument ), new StreamResult( out ) );
145
146                } catch (TransformerConfigurationException ex) {
147                        System.err.println( ex.getMessage() );
148                        ex.printStackTrace();
149                } catch (TransformerException ex) {
150                        // 書き出しエラー発生
151                        System.err.println( ex.getMessage() );
152                        ex.printStackTrace();
153                } catch (IOException ex) {
154                        // ファイルが読み込めなかった場合
155                        System.err.println( ex.getMessage() );
156                        ex.printStackTrace();
157                // 5.1.9.0 (2010/08/01) Closeされないバグを修正
158                } finally {
159                        Closer.ioClose( out );
160                }
161        }
162}