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.util;
017
018import java.io.FileInputStream;
019import java.io.UnsupportedEncodingException;
020import java.io.IOException;
021import java.util.StringTokenizer;
022
023/**
024 * FileString は、ファイルを読み取って、そのまま String 文字列として返すクラスです。
025 * SQLを記述したファイルや、コマンドを記述したファイルを読み取って、コマンドラインからの
026 * 入力として利用できます。
027 *
028 * ファイルは、一旦すべて読み取ってメモリ上で加工されます。
029 * パラメータ等の設定ファイルをイメージしている為、巨大なファイルの読み込みは出来ません。
030 *
031 * @version  4.0
032 * @author   Kazuhiko Hasegawa
033 * @since    JDK5.0,
034 */
035public class FileString  {
036        private String  filename        = null ;
037        private String  encode          = null ;
038        private String  value           = null ;
039
040        /**
041         * ファイル名を設定します。
042         * 指定のファイルを読み取って、内部文字列に格納します。
043         * なお、格納するタイミングは、#getValue() を最初に行ったときです。
044         * ファイル名を再設定すると、内部のvalue は、クリアされます。
045         *
046         * @param  filename ファイル名
047         */
048        public void setFilename( final String filename ) {
049                if( filename == null ) {
050                        String errMsg = "ファイル名が指定されていません。" ;
051                        throw new RuntimeException( errMsg );
052                }
053
054                this.filename = filename;
055                value             = null;               // 初期化
056        }
057
058        /**
059         * ファイル名を取得します。
060         *
061         * @og.rev 5.2.3.0 (2010/12/01) 新規追加
062         *
063         * @return      ファイル名
064         */
065        public String getFilename() {
066                return filename;
067        }
068
069        /**
070         * ファイルのエンコードを設定します。
071         * 指定のファイルを読み取る場合のエンコードを指定します。
072         * 正確には、バイナリデータを読み取って、文字列に変換する場合に、
073         * String( byte[],String ) コンストラクタの引数に使用します。
074         * 指定されていない場合は、String( byte[] ) コンストラクタで変換します。
075         * エンコードを再設定すると、内部のvalue は、クリアされます。
076         *
077         * @param  encode エンコード名
078         */
079        public void setEncode( final String encode ) {
080                this.encode     = encode;
081                value           = null;         // 初期化
082        }
083
084        /**
085         * ファイルのエンコードを取得します。
086         * 正確には、内部文字列に変換したときのエンコードです。
087         * null の場合は、無指定(つまりデフォルトエンコード)と
088         * なります。
089         *
090         * @og.rev 5.2.3.0 (2010/12/01) 新規追加
091         *
092         * @return      ファイルのエンコード
093         */
094        public String getEncode() {
095                return encode;
096        }
097
098        /**
099         * ファイルを読み取って、文字列を作成します。
100         *
101         * データの読取が完全に出来なかったときには、途中までのデータを返します。
102         * 指定のエンコードが存在しない場合や、ファイルが存在しない場合は、
103         * RuntimeException を throw します。
104         *
105         * @return  ファイルを読み取った文字列
106         * @throws RuntimeException 指定のエンコードが存在しなかったとき。
107         */
108        public String getValue() {
109                if( value != null ) { return value; }
110
111                FileInputStream file = null;
112                try {
113                        file = new FileInputStream( filename );
114                        byte[] buf = new byte[file.available()];
115                        int len = file.read(buf);
116                        if( len != buf.length ) {
117                                String errMsg = "読み取りファイルのデータが切り捨てられました。" +
118                                                                "File=" + filename + " Length=" + len ;
119                                LogWriter.log( errMsg );
120                        }
121                        if( encode != null ) {
122                                value = new String( buf,encode );
123                        }
124                        else {
125//                              value = new String( buf );
126                                value = new String( buf,StringUtil.DEFAULT_CHARSET );   // 5.5.2.6 (2012/05/25) findbugs対応
127                        }
128                }
129                catch( UnsupportedEncodingException ex ) {
130                        String errMsg = "指定されたエンコーディングがサポートされていません。[" + encode + "]" ;
131                        throw new RuntimeException( errMsg,ex );
132                }
133                catch( IOException ex ) {
134                        String errMsg = "ファイル名がオープン出来ませんでした。[" + filename + "]" ;
135                        throw new RuntimeException( errMsg,ex );
136                }
137                finally {
138                        Closer.ioClose( file );
139                }
140
141                return value ;
142        }
143
144        /**
145         * 指定の区切り文字で分割された文字列配列を取得します。
146         * 区切り文字が連続している場合は、一つの区切り文字と認識します。
147         * 処理は、java.util.StringTokenizer で、処理する方法と同一です。
148         * 例えば、";" を指定すれば、SQL を複数記述しておくことが可能になります。
149         *
150         * @param       delim   ファイルを分割する区切り文字
151         *
152         * @return  ファイルを読み取った文字列
153         */
154        public String[] getValue( final String delim ) {
155
156                StringTokenizer token = new StringTokenizer( getValue(),delim );
157
158                String[] rtn = new String[token.countTokens()];
159
160                for( int i=0; token.hasMoreTokens(); i++ ) {
161                        rtn[i] = token.nextToken();
162                }
163
164                return rtn ;
165        }
166}