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     */
016    package org.opengion.fukurou.util;
017    
018    /**
019     * TagBuffer.java は、å?通的に使用されã‚?簡易タグ作æ?クラスですã?
020     * タグヘッãƒ??は、オブジェクト作æ?時に登録する為、後ã?変更は出来ませんã€?
021     * BODY部ã‚??属æ?は、ä¸?º¦登録すると書き換えできませんã€?
022     * またã?同ä¸?±žæ?チェãƒ?‚¯は行いません。登録した属æ?のキーã‚??値を取りå?すこともå?来ませんã€?
023     * あくまで、タグæ–?­—å?をストレートに作æ?することに特化したクラスですã?
024     * これらã?高度な機è?がå¿?¦�であれば、{@link org.opengion.fukurou.util.Attributes } をご参ç?くださいã€?
025     *
026     * makeTag() メソãƒ?ƒ‰を呼び出した時点で、å?部にタグæ–?­—å?をキャãƒ?‚·ュしますã?
027     * それ以降ã?変更は、å?来ませんã€?
028     *
029     * å†?ƒ¨çš?�«は、構é?化されてã�?�¾せん。あくまで、文字å?連çµ?StringBuilder)の
030     * 簡易クラスとして、使用してくださいã€?
031     *
032     * @og.group ユーãƒ?‚£リãƒ?‚£
033     *
034     * @version  4.0
035     * @author       Kazuhiko Hasegawa
036     * @since    JDK5.0,
037     */
038    public final class TagBuffer {
039            private final StringBuilder buf = new StringBuilder(100);
040            private final String tagName ;
041            private       String tagBody     = null;
042            private       String cacheTag = null;
043    
044            /**
045             * ãƒ?ƒ•ォルトコンストラクター
046             * こã?コンストラクターを使用すると、タグ名をæŒ?®šできなã�?�Ÿめã?
047             * 完æ?形のタグは、作æ?できません。属æ?リスãƒ?key="value")の
048             * 連結形式を得る場合にのみ、使用して下さã�??
049             *
050             */
051            public TagBuffer() {
052                    this.tagName = null;
053            }
054    
055            /**
056             * コンストラクター
057             * タグ名に null を指定すると、デフォルトコンストラクターと同様にã€?
058             * 完æ?形のタグは、作æ?できません。属æ?リスãƒ?key="value")の
059             * 連結形式を得る場合にのみ、タグå�?にnull を指定して下さã�??
060             *
061             * @param       tagName  タグ名称
062             */
063            public TagBuffer( final String tagName ) {
064                    this.tagName = tagName;
065                    if( tagName != null ) {
066                            buf.append( "<" ).append( tagName ).append( " " );
067                    }
068            }
069    
070            /**
071             * タグの BODY部を登録しますã?
072             * 登録しなã�??合ã?、BODY部のなã�?‚¿グ(空要ç´?‚¿グ)を生成しますã?
073             * BODY部を指定するとã€?lt;tagName key="val" ?¥?¥?¥ &gt;body&lt;/tagName&gt; 形式になりますã?
074             * BODY部がã?null の場合ã?ã€?&lt;tagName key="val" ?¥?¥?¥ /&gt; 形式になりますã?
075             * こã?メソãƒ?ƒ‰は、makeTag() が呼ばれた後ã?、登録できなくなりますã?
076             *
077             *      @deprecated {@link TagBuffer#addBody(String)}
078             * @param       body     タグのBODY部
079             */
080            public void setBody( final String body ) {
081                    if( cacheTag != null ) {
082                            String errMsg = "makeTag() 実行後に、BODY部の値を書き換えることは出来ませんã€? ;
083                            throw new RuntimeException( errMsg );
084                    }
085    
086                    this.tagBody = body;
087            }
088            
089            /**
090             * タグの BODY部を追åŠ?™»録しますã?
091             *
092             * すでに、登録済みの場合ã?、その値に、追記しますã?
093             * そうでなã�??å�?初めての場å�?は、その値をセãƒ?ƒˆしますã?
094             * null を登録した場合ã?、何もしませんã€?
095             * ※ 従来あっã�?#setBody(String)の様に、null を登録した場合ã?Body ã‚?
096             * リセãƒ?ƒˆする機è?はありません。新しいオブジェクトを作æ?してくださいã€?
097             *
098             * こã?メソãƒ?ƒ‰は、makeTag() が呼ばれた後ã?、登録できなくなりますã?
099             *
100             * @og.rev 5.8.4.1 (2015/02/20) 6.1.1.0é€?§»æ¤?#setBody(String) の代替えメソãƒ?ƒ‰として、新規追åŠ?
101             *
102             * @param       body     タグのBODY部に追åŠ?�™る文字å?
103             *
104             * @return      自åˆ??身
105             * @og.rtnNotNull
106             */
107            public TagBuffer addBody( final String body ) {
108                    return addBody( body,true );
109            }
110            
111            /**
112             * タグの BODY部を追åŠ?™»録しますã?
113             *
114             * すでにã€?setBody(String) で、登録済みの場合ã?、その値に、追記しますã?
115             * そうでなã�??合ã?ã€?setBody(String) と同じ動作になりますã?
116             * null を登録した場合ã?、何もしませんã€?
117             * 
118             * flag に、false を指定すると、追åŠ?™»録しません。これã?、if( flag ) { tagBuffer.addBody( body ); }
119             * の様な判定å?ç�?‚’、tagBuffer.body( body,flag ); に簡ç´?Œ–するために使用できますã?
120             * TagBuffer は、StringBuilderの様に、メソãƒ?ƒ‰の戻りå?は、è?åˆ??身のオブジェクトなのでã€?
121             * 上記ã? flag を使用して、å?れ目なくé?結させることが可能になりますã?
122             *
123             * こã?メソãƒ?ƒ‰は、makeTag() が呼ばれた後ã?、登録できなくなりますã?
124             *
125             * @og.rev 5.8.4.1 (2015/02/20) 6.1.1.0é€?§»æ¤?戻りå?に、è?åˆ??身を返すようにしますã?
126             *
127             * @param       body    タグのBODY部に追åŠ?�™る文字å?
128             * @param       flag    タグのBODY部に追åŠ?�‹どã�?�‹を決めるフラグ(true:追åŠ?�™ã‚?false:何もしなã�?
129             *
130             * @return      自åˆ??身
131             * @og.rtnNotNull
132             */
133            public TagBuffer addBody( final String body,final boolean flag ) {
134                    if( cacheTag != null ) {
135                            final String errMsg = "makeTag() 実行後に、BODY部の値を書き換えることは出来ませんã€? ;
136                            throw new RuntimeException( errMsg );
137                    }
138    
139                    if( flag && body != null ) {
140                            if( tagBody !=null ) { tagBody += body; }
141                            else                             { tagBody =  body; }
142                    }
143    
144                    return this ;
145            }
146    
147            /**
148             * タグの 属æ?(key="value")を登録しますã?
149             * 属æ?は、key="value" のæ–?­—å?を作æ?しますã?key かã?value のどちらかã�?null
150             * の場合ã?、登録しませんã€?
151             * value に、ダブルコーãƒ??ション(")が含まれてã�?‚‹場合ã?、属æ?値をシングルコーãƒ??ション
152             * でくくりますã?
153             * 両方含まれてã�?‚‹場合ã?、シングルコーãƒ??ションをエスケープ文字に変換しますã?
154             * こã?メソãƒ?ƒ‰は、makeTag() が呼ばれた後ã?、登録できなくなりますã?
155             *
156             * @og.rev 3.8.6.1 (2006/10/20) シングルとãƒ?ƒ–ルが混在する場合ã?、シングルをエスケープすã‚?
157             *
158             * @param       key      属æ?キー (null の場合ã?、なにもしなã�?
159             * @param       val      属æ?値 (null の場合ã?、なにもしなã�?
160             */
161            public void add( final String key,final String val ) {
162                    if( cacheTag != null ) {
163                            String errMsg = "makeTag() 実行後に、属æ?を追åŠ?�™ることは出来ませんã€? ;
164                            throw new RuntimeException( errMsg );
165                    }
166    
167                    if( key != null && val != null ) {
168                            if( val.indexOf( '\"' ) >= 0 ) {
169                                    String temp = val ;
170                                    if( val.indexOf( "'" ) >= 0 ) { temp = val.replaceAll( "'","&#39;" ); }
171                                    buf.append( key ).append( "='" ).append( temp ).append( "' " );
172                            }
173                            else {
174                                    buf.append( key ).append( "=\"" ).append( val ).append( "\" " );
175                            }
176                    }
177            }
178    
179            /**
180             * タグの属æ?に、追åŠ?™»録しますã?
181             * æ–?­—å?として、key="value" の形式データを与えてください。é?結時は、後ろに
182             * スペã?スをä¸?�¤挟みますã?で、与える引数自体に連結用スペã?スを追åŠ?�—ておく
183             * å¿?¦�ã?ありませんã€?
184             * 通常は、tagName なしで作æ?した、Tagbuffer オブジェクトã? makeTag() メソãƒ?ƒ‰の
185             * 返り値を渡しますが、Attributes.getAttribute() の返り値でも使用できますã?
186             * 引数ã�?null の場合ã?、なにもしませんã€?
187             * こã?メソãƒ?ƒ‰は、makeTag() が呼ばれた後ã?、登録できなくなりますã?
188             *
189             * @param       str     タグバッファーを追åŠ?�—ますã?
190             * @see         #makeTag()
191             * @see         Attributes#getAttribute()
192             */
193            public void add( final String str ) {
194                    if( cacheTag != null ) {
195                            String errMsg = "makeTag() 実行後に、属æ?を追åŠ?�™ることは出来ませんã€? ;
196                            throw new RuntimeException( errMsg );
197                    }
198    
199                    if( str != null ) {
200                            buf.append( str ).append( " " );
201                    }
202            }
203    
204            /**
205             * タグの 整形された文字å?ã‚?作æ?しますã?
206             * こã?メソãƒ?ƒ‰は、tagName,body,属æ?より タグの完æ?形のæ–?­—å?を作æ?しますã?
207             * 作æ?された文字å?は、å?部でキャãƒ?‚·ュされますã?
208             * BODY部を指定するとã€?lt;tagName key="val" ?¥?¥?¥ &gt;body&lt;/tagName&gt; 形式になりますã?
209             * BODY部がã?null の場合ã?ã€?&lt;tagName key="val" ?¥?¥?¥ /&gt; 形式になりますã?
210             * タグ名をæŒ?®šしなã�?null)と、完æ?形のタグは、作æ?できませんã€?
211             * 属æ?リスãƒ?key="value")の連結形式を返しますã?
212             *
213             * こã?メソãƒ?ƒ‰の呼び出し以降では、setBody() ã‚?add() も実行できませんã€?
214             *
215             * @return      整形されã�?タグæ–?­—å?
216             */
217            public String makeTag() {
218                    if( cacheTag == null ) {
219                            if( tagName != null ) {
220                                    if( tagBody == null ) {
221                                            buf.append( "/>" );
222                                    }
223                                    else {
224                                            buf.append( ">" ).append( tagBody );
225                                            buf.append( "</" ).append( tagName ).append( ">" );
226                                    }
227                            }
228                            cacheTag = buf.toString();
229                    }
230    
231                    return cacheTag;
232            }
233    
234            /**
235             * 行番号付きのタグの 整形された文字å?ã‚?作æ?しますã?
236             * こã?メソãƒ?ƒ‰は、makeTag() の結果より、[I] æ–?­—å?を引数の行番号と変換しますã?
237             * これにより、動çš?�«行番号つきã?æƒ??を属æ?に付与することが可能になりますã?
238             * å†?ƒ¨にキャãƒ?‚·ュされるå?は、[I] 記号を変換してã�?�ªã�?ж態ã?æ–?­—å?ですã?
239             * よって、このメソãƒ?ƒ‰は、rowNo を変えて、何度でも呼び出すことは可能ですがã€?
240             * setBody() ã‚?add() は実行できませんã€?
241             *
242             * @param       rowNo   行番号([I] æ–?­—å?を変換しますã?)
243             * @param       val     設定å?([V] æ–?­—å?を変換しますã?)
244             *
245             * @return      整形されã�?タグæ–?­—å?
246             */
247            public String makeTag( final int rowNo,final String val ) {
248                    String tag = makeTag();
249                    tag = StringUtil.replace( tag,"[I]",String.valueOf( rowNo ) );
250                    tag = StringUtil.replace( tag,"[V]",val );
251    
252                    return tag ;
253            }
254    }