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.util.Arrays ;
019
020/**
021 * ToString.java は、共通的に使用される toString() を簡素化するクラスです。
022 * デバッグ情報を出力する最も一般的な方法は、内部文字列の出力です。
023 * 通常、キーと値をペアで記述するため、StringBuilder で append しながら作成するにしても
024 * コーディング的にあまり見栄えの良い形にはなりません。
025 * ここでは、それらを簡易的に整形して出力できるように、メソッドを用意しました。
026 *
027 * @og.group ユーティリティ
028 *
029 * @version  4.0
030 * @author       Kazuhiko Hasegawa
031 * @since    JDK5.0,
032 */
033public final class ToString {
034
035        /** システム依存の改行記号をセットします。 */
036        private static final String CR = System.getProperty("line.separator");
037
038        /** 4つ分のスペースです。 */
039        private static final String SPACE = "    " ;
040        /** 3つ分のカンマです。  */
041        private static final String COMMA = " , " ;
042
043        private final StringBuilder buf ;
044
045        /** 最後に改行記号を入れたかどうか。    */
046        private boolean lastCR = true ;
047
048        /** キー文字列の最大長(すべてASCII換算)       */
049        private int maxSize = 0;
050
051        /**
052         * タイトルを指定するコンストラクター
053         * タイトルは、先頭にスペースなしで入れます。最後は改行ありです。
054         *
055         * @param title タイトル文字列
056         */
057        public ToString( final String title ) {
058                buf = new StringBuilder( 200 );
059                buf.append( "TITLE = [" ).append( title ).append( "]" ).append( CR );
060                lastCR = true ;
061        }
062
063        /**
064         * 簡易的にオブジェクトを構築する static メソッド
065         * タイトルは、先頭にスペースなしで入れます。最後は改行ありです。
066         *
067         * @param       title タイトル文字列
068         *
069         * @return      ToStringオブジェクト
070         */
071        public static ToString title( final String title ) {
072                return new ToString( title );
073        }
074
075        /**
076         * 改行なしのキーと値のペアを設定します。
077         * 前回、改行で終わっている場合は、キーから始めます。
078         * そうでない場合、" , " を出力してから、書き始めます。
079         *
080         * @param       key     キー文字列
081         * @param       val     値文字列
082         *
083         * @return      自分自身
084         */
085        public ToString print( final String key,final Object val ) {
086                if( lastCR ) {  buf.append( SPACE ); }
087                else {                  buf.append( COMMA ); }
088                lastCR = false;
089
090                if( key != null ) {
091                        int len = key.length();
092                        if( len > maxSize ) { maxSize = len; }
093                        buf.append( key ).append( " = [" ).append( String.valueOf( val ) ).append( "]" );
094                }
095                else {
096                        buf.append( "   [" ).append( String.valueOf( val ) ).append( "]" );
097                }
098
099                return this ;
100        }
101
102        /**
103         * 改行ありのキーと値のペアを設定します。
104         * 前回、改行で終わっている場合は、キーから始めます。
105         * そうでない場合、" , " を出力してから、書き始めます。
106         *
107         * @param       key     キー文字列
108         * @param       val     値文字列
109         *
110         * @return      自分自身
111         */
112        public ToString println( final String key,final Object val ) {
113                print( key,val );
114
115                buf.append( CR );
116                lastCR = true;
117                return this ;
118        }
119
120        /**
121         * 改行なしのキーと値配列のペアを設定します。
122         * 前回、改行で終わっている場合は、キーから始めます。
123         * そうでない場合、" , " を出力してから、書き始めます。
124         *
125         * @param       key     キー文字列
126         * @param       val     値配列
127         *
128         * @return      自分自身
129         */
130        public ToString print( final String key,final Object[] val ) {
131                String str = Arrays.toString( val );
132                return print( key,str.substring( 1,str.length()-1 ) );
133        }
134
135        /**
136         * 改行ありのキーと値配列のペアを設定します。
137         * 前回、改行で終わっている場合は、キーから始めます。
138         * そうでない場合、" , " を出力してから、書き始めます。
139         *
140         * @param       key     キー文字列
141         * @param       val     値配列
142         *
143         * @return      自分自身
144         */
145        public ToString println( final String key,final Object[] val ) {
146                String str = Arrays.toString( val );
147                return println( key,str.substring( 1,str.length()-1 ) );
148        }
149
150        /**
151         * 改行のみ設定します。
152         *
153         * @return      自分自身
154         */
155        public ToString println() {
156                buf.append( CR );
157                lastCR = true;
158                return this;
159        }
160
161        /**
162         * 改行付きの値のみ設定します。
163         *
164         * @param       val     値
165         *
166         * @return      自分自身
167         */
168        public ToString println( final Object val ) {
169                return println( null,val );
170        }
171
172        /**
173         * 改行付きの値のみ設定します。
174         *
175         * @param       val     値
176         *
177         * @return      自分自身
178         */
179        public ToString println( final Object[] val ) {
180                String str = Arrays.toString( val );
181                return println( null,str.substring( 1,str.length()-1 ) );
182        }
183
184        /**
185         * 先頭のキーの位置を最大値に合わせて、整形します。
186         *
187         * @return      自分自身
188         */
189        public ToString fixForm() {
190                String searchKey = CR + SPACE ;
191                int    skLen = searchKey.length() ;
192
193                char[] ch = new char[maxSize];
194                Arrays.fill( ch,' ' );
195                String MAX_SPACE = new String( ch );
196
197                int adrs = buf.indexOf( searchKey );
198                while( adrs >= 0 ) {
199                        int eq = buf.indexOf( "=",adrs );
200                        if( eq >= 0 && buf.charAt(adrs+skLen) != ' ' ) {
201                                int nextAdrs  = buf.indexOf( searchKey,adrs+skLen );
202                                if( nextAdrs < 0 || eq < nextAdrs ) {
203                                        buf.insert( eq, MAX_SPACE.substring( eq-(adrs+skLen)-1 ) );
204                                }
205                        }
206                        adrs = buf.indexOf( searchKey,adrs+skLen );
207                }
208
209                return this;
210        }
211
212        /**
213         * 内部バッファを文字列にして返します。
214         *
215         * @return      内部バッファを文字列にして返します。
216         */
217        @Override
218        public String toString() {
219                return buf.toString() ;
220        }
221}