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.xml;
017    
018    import org.xml.sax.Attributes;
019    import java.util.List;
020    import java.util.ArrayList;
021    
022    /**
023     * 属æ?リストをã‚らã‚ã™ã€OGAttributes クラスを定義ã—ã¾ã™ã?
024     *
025     * 属æ?リストã?ã€ã‚­ãƒ¼ã¨å€¤ã®ãƒšã‚¢ã‚’ã?並ã³é ?§ç®¡ç?—ã¦ã?‚‹ãƒªã‚¹ãƒˆã‚’ä¿æŒã—ã¦ã?¾ã™ã?
026     * å†?ƒ¨çš?«ã¯ã€?org.xml.sax.Attributes ã‹ã‚‰ã®å€¤ã®è¨­å®šã¨ã€ã‚¿ãƒ–ã?属æ?ã®æ•´åˆ—を行ã†ãŸã‚ã®
027     * 属æ?タブã?属æ?ã®æ”¹è¡Œã?制御ã€å±žæ?ã®é•·ã•ã?制御 ãªã©ã‚’行ã„ã¾ã™ã?
028     *
029     * @og.rev 5.1.8.0 (2010/07/01) æ–°è¦ä½œæ?
030     *
031     * @version  5.0
032     * @author   Kazuhiko Hasegawa
033     * @since    JDK6.0,
034     */
035    public class OGAttributes {
036            /** シスãƒ?ƒ æ”¹è¡Œã‚³ãƒ¼ãƒ?**/
037            public static final String      CR     = System.getProperty("line.separator");
038    
039            /** 属æ?ã®å€‹æ•°åˆ¶é™ã?ã“ã?å€‹æ•°ã§æ”¹è¡Œã‚’行ã†ã€?{@value} */
040            public static final int         CR_CNT = 4;
041            /** 属æ?ã®é•·ã•制é™ã?ã“れ以上ã?å ´åˆã?ã€æ”¹è¡Œã‚’行ã†ã€?{@value} */
042            public static final int         CR_LEN = 80;
043    
044            private final List<OGAtts>        attList = new ArrayList<OGAtts>();
045    
046    //      private String  attTab  = CR + "  ";            // ã‚¿ã‚°ã®å‰æ–¹ã‚¹ãƒšã?ス
047    //      private String  attTab  = "  ";                         // 属æ?ã®å‰æ–¹ã‚¹ãƒšã?ス
048            private boolean useCR   = false;                        // 属æ?ã®æ”¹è¡Œå?力を行ã†ã‹ã©ã?‹ã€‚å?数制é™ãŒ?‘ã¨åŒã˜
049            private int     maxValLen       = 0;                            // 属æ?ã®åå‰ã®æœ?¤§æ–?­—æ•°
050            private String  id              = null;                         // 特別ãªå±žæ?。id ã§æ¤œç´¢ã‚’高é?化ã™ã‚‹ãŸã‚ã?
051    
052            /**
053             * ãƒ?ƒ•ォルトトコンストラクター
054             *
055             * å–りã‚ãˆãšã?属æ?オブジェクトを構築ã™ã‚‹å?åˆã«ä½¿ç”¨ã—ã¾ã™ã?
056             * 属æ?タブã?ã€æ”¹è¡Œï¼‹ã‚¿ãƒ?ã€å±žæ?リストã?ã€ç©ºã®ãƒªã‚¹ãƒˆã?属æ?改行ã?ã€false ã‚’å?期設定ã—ã¾ã™ã?
057             *
058             */
059            public OGAttributes() {
060                    // Document empty method ãƒã‚§ãƒ?‚¯å¯¾ç­?
061            }
062    
063            /**
064             * 属æ?タブã?属æ?リストã?属æ?改行ã?有無を指定ã—ã¦ã®ãƒˆã‚³ãƒ³ã‚¹ãƒˆãƒ©ã‚¯ã‚¿ãƒ¼
065             *
066             * 属æ?タブã?属æ?リスト㫠null を指定ã™ã‚‹ã¨ã€ãƒ‡ãƒ•ォルトトコンストラクターã®è¨­å®šã¨
067             * åŒã˜çŠ¶æ…‹ã«ãªã‚Šã¾ã™ã?
068             *
069             * 注æ„?属æ?å€¤ã®æ­£è¦åŒ–ã¯å¿?šè¡Œã‚れã¾ã™ã?
070             * 属æ?値ã«å«ã¾ã‚Œã‚‹CR(復帰), LF(改è¡?, TAB(ã‚¿ãƒ?ã¯ã€?åŠè§’スペã?スã«ç½®ãæ›ãˆã‚‰ã‚Œã¾ã™ã?
071             * XMLã®è¦å®šã§ã¯ã€å±žæ?ã®ä¸¦ã³é ??ä¿éšœã•れã¾ã›ã‚“ãŒã?SAXã®Attributesã¯ã€XMLã«è¨˜è¿°ã•れãŸé?番ã§
072             * å–å¾—ã§ãã¦ã?¾ã™ã?ã§ã€ã“ã®ã‚¯ãƒ©ã‚¹ã§ã®å±žæ?リストもã€è¨˜è¿°é ?§ã®ä¸¦ã³é ?«ãªã‚Šã¾ã™ã?
073             *
074             * @og.rev 5.1.9.0 (2010/08/01) id 属æ?ã®ã¿ç‰¹åˆ¥ã«ã‚­ãƒ£ãƒ?‚·ãƒ¥ã—ã¦ãŠãã€?
075             *
076             * @param attri         属æ?リスãƒ?
077             */
078    //      public OGAttributes( final String attTab , final Attributes attri , final boolean useCR ) {
079            public OGAttributes( final Attributes attri ) {
080    //              if( attTab != null ) {
081    ////                    this.attTab = CR + attTab + "  ";
082    //                      this.attTab = attTab;
083    //              }
084    //              this.useCR  = useCR;
085    
086                    int num = (attri == null)? 0 : attri.getLength();
087                    int maxLen = 0;
088                    for (int i = 0; i < num; i++) {
089    //                      OGAtts atts = new OGAtts( attri.getQName(i),attri.getValue(i) );
090                            String key = attri.getQName(i);
091                            String val = attri.getValue(i);
092                            OGAtts atts = new OGAtts( key,val );
093                            attList.add( atts );
094                            maxLen = atts.maxKeyLen( maxLen );
095    
096                            if( "id".equals( key ) ) { id = val; }          // 5.1.9.0 (2010/08/01)
097                    }
098    
099                    maxValLen = maxLen;
100            }
101    
102            /**
103             * 属æ?タブを設定ã—ã¾ã™ã?
104             *
105             * 属æ?タブã?ã€è?身ã®ã‚¨ãƒ¬ãƒ¡ãƒ³ãƒˆã?書ãå?ã—ä½ç½®ã¾ã§ã®æ–?­—å?ã‚’æŒã£ã¦ã?¾ã™ã?
106             * 属æ?ã‚’ã?ãã?ã¾ã¾ã€ã‚¿ã‚°ã®æ¨ªã«å‡ºã™ã¨ã€?¼‘行ã«åŽã¾ã‚‰ãªã?‚±ãƒ¼ã‚¹ãŒã‚りã¾ã™ã?
107             * ãã?å ´åˆã?自身ã®ä½ç½®?‹ã‚¿ãƒ–を属æ?ã®æ›¸ãå?ã—ã«ä½¿ç”¨ã—ã¾ã™ã?
108             * ãã?æ–?­—å?を定義ã—ã¦ã?¾ã™ã?
109             *
110             * 引数ã¯ã€è?身ã®ã‚¨ãƒ¬ãƒ¡ãƒ³ãƒˆã?書ãå?ã—ä½ç½®ã§ã™ã?
111             *
112             * @og.rev 5.1.9.0 (2010/08/01) å»?­¢
113             *
114             * å†?ƒ¨çš?«ã€?½¢CR + attTab + タブ」 ã«åŠ?·¥ã•れã¾ã™ã?
115             *
116             * @param       attTab  属æ?ã‚¿ãƒ?
117             */
118    //      public void setAttrTab( final String attTab ) {
119    //              if( attTab != null ) {
120    ////                    this.attTab = CR + attTab + "\t";
121    //                      this.attTab = attTab;
122    //              }
123    //      }
124    
125            /**
126             * 属æ?改行ã?有無を設定ã—ã¾ã™ã?
127             *
128             * ã‚¿ã‚°ã«ã‚ˆã£ã¦ã€å±žæ?ãŒå¤šããªã£ãŸã‚Šã€æ„味ãŒé‡è¦ãªå ´åˆã?ã€å±žæ??‘ã¤ã¥ã¤ã«æ”¹è¡Œã‚’
129             * 行ã„ãŸã„ケースãŒã‚りã¾ã™ã?
130             * 属æ?改行をtrue ã«è¨­å®šã™ã‚‹ã¨ã€å±žæ?ä¸?¤ã¥ã¤ã§ã€æ”¹è¡Œã‚’行ã„ã¾ã™ã?
131             *
132             * false ã®å ´åˆã?ã€è?å‹•çš„ãªæ”¹è¡Œå?ç?Œè¡Œã‚れã¾ã™ã?
133             * ã“れã¯ã€å±žæ?ã®å€‹æ•°åˆ¶é™?CR_CNT)ã‚’è¶?ˆã‚‹å?åˆã?ã€æ”¹è¡Œã‚’行ã„ã¾ã™ã?
134             *
135             * @param       useCR   属æ?改行ã?有無(true:?‘属æ?å˜ä½ã?改è¡?
136             * @see #CR_CNT
137             * @see #CR_LEN
138             */
139            public void setUseCR( final boolean useCR ) {
140                    this.useCR  = useCR;
141            }
142    
143            /**
144             * 属æ?リストã?個数をå–å¾—ã—ã¾ã™ã?
145             *
146             * @return      属æ?リストã?個数
147             */
148            public int size() {
149                    return attList.size();
150            }
151    
152            /**
153             * 属æ?リストã‹ã‚‰ã?æŒ?®šã?é…å?番å·ã®ã€å±žæ?キーをå–å¾—ã—ã¾ã™ã?
154             *
155             * @param       adrs    é…å?番å·
156             *
157             * @return      属æ?キー
158             */
159            public String getKey( final int adrs ) {
160                    return attList.get(adrs).KEY ;
161            }
162    
163            /**
164             * 属æ?リストã‹ã‚‰ã?æŒ?®šã?é…å?番å·ã®ã€?•·ã•補正ãŒè¡Œã‚れãŸå±žæ?キーをå–å¾—ã—ã¾ã™ã?
165             *
166             * useCR=true ã®å ´åˆã«ã€å±žæ?ã®æ”¹è¡ŒãŒè¡Œã‚れã¾ã™ãŒã€ãã®ã¨ãã«ã€ã‚­ãƒ¼ãŒç¸¦ã«ä¸¦ã³ã¾ã™ã?
167             * ãã—ã¦ã€å?も縦ã«ä¸¦ã¶ãŸã‚ã€?–“ã® ?¢?」記å·ã®ä½ç½®ã‚’ãã‚ãˆã¦ã€è¡¨ç¤ºã—ã¾ã™ã?
168             * 属æ?リストã?æœ?¤§é•·ã•+ï¼?ã«ãªã‚‹ã‚ˆã?«ã€ã‚­ãƒ¼ã®æ–?­—å?ã«ã‚¹ãƒšã?スを埋ã‚ã¾ã™ã?
169             * ã“れã«ã‚ˆã‚Šã€å±žæ?を改行ã—ã¦è¡¨ç¤ºã—ã¦ã‚‚ã?値ã®è¡¨ç¤ºä½ç½®ãŒãã‚ã„ã¾ã™ã?
170             *
171             * @param       adrs    é…å?番å·
172             *
173             * @return      属æ?リスト群ã®é•·ã•補正ãŒè¡Œã‚れãŸã€å±žæ?キー?‹ç©ºç™½æ–?­—å?
174             */
175    //      private String getAlignKey( final int adrs ) {
176    //              return attList.get(adrs).KEY + SPACE.substring( attList.get(adrs).LEN,maxValLen ) ;
177    //      }
178    
179            /**
180             * 属æ?リストã‹ã‚‰ã?æŒ?®šã?é…å?番å·ã®ã€å±žæ?値をå–å¾—ã—ã¾ã™ã?
181             *
182             * @param       adrs    é…å?番å·
183             *
184             * @return      属æ?値
185             */
186            public String getVal( final int adrs ) {
187                    return attList.get(adrs).VAL ;
188            }
189    
190            /**
191             * 属æ?リストã‹ã‚‰ã?æŒ?®šã?属æ?キーã®ã€å±žæ?値をå–å¾—ã—ã¾ã™ã?
192             *
193             * ã“ã?処ç??ã€å±žæ?リストをã™ã¹ã¦ã‚¹ã‚­ãƒ£ãƒ³ã—ã¦ã€ã‚­ãƒ¼ã«ãƒžãƒƒãƒã™ã‚?
194             * 属æ?オブジェクトを見ã¤ã‘ã?ãã“ã‹ã‚‰ã€å±žæ?値をå–りå?ã™ã?ã§ã€?
195             * パフォーマンスã«å•題ãŒã‚りã¾ã™ã?
196             * 基本çš?«ã¯ã€ã‚¢ãƒ‰ãƒ¬ã‚¹æŒ?®šã§ã€å±žæ?値をå–りå?ã™ã‚ˆã?«ã—ã¦ãã ã•ã„ã€?
197             *
198             * @og.rev 5.1.9.0 (2010/08/01) æ–°è¦è¿½åŠ?
199             *
200             * @param       key     属æ?キー
201             *
202             * @return      属æ?値
203             */
204            public String getVal( final String key ) {
205                    String val = null;
206    
207                    if( key != null ) {
208                            for( OGAtts atts : attList ) {
209                                    if( key.equals( atts.KEY ) ) {
210                                            val = atts.VAL;
211                                            break;
212                                    }
213                            }
214                    }
215    
216                    return val;
217            }
218    
219            /**
220             * 属æ?リストã‹ã‚‰ã?æŒ?®šã?属æ?キーã®ã€ã‚¢ãƒ‰ãƒ¬ã‚¹ã‚’å–å¾—ã—ã¾ã™ã?
221             *
222             * ã©ã¡ã‚‰ã‹ã¨ã?†ã¨ã€ã‚­ãƒ¼ã®å­˜åœ¨ãƒã‚§ãƒ?‚¯ã«è¿‘ã„処ç?‚’行ã„ã¾ã™ã?
223             * ã“ã?処ç??ã€å±žæ?リストをã™ã¹ã¦ã‚¹ã‚­ãƒ£ãƒ³ã—ã¦ã€ã‚­ãƒ¼ã«ãƒžãƒƒãƒã™ã‚?
224             * 属æ?オブジェクトを見ã¤ã‘ã?ãã“ã‹ã‚‰ã€å±žæ?値をå–りå?ã™ã?ã§ã€?
225             * パフォーマンスã«å•題ãŒã‚りã¾ã™ã?
226             *
227             * @og.rev 5.1.9.0 (2010/08/01) æ–°è¦è¿½åŠ?
228             *
229             * @param       key     属æ?キー
230             *
231             * @return      アドレス キーãŒå­˜åœ¨ã—ãªã??åˆã?ã€?1 ã‚’è¿”ã™ã€?
232             */
233            public int getAdrs( final String key ) {
234                    int adrs = -1;
235    
236                    if( key != null ) {
237                            for( int i=0; i<attList.size(); i++ ) {
238                                    if( key.equals( attList.get(i).KEY ) ) {
239                                            adrs = i;
240                                            break;
241                                    }
242                            }
243                    }
244    
245                    return adrs;
246            }
247    
248            /**
249             * 属æ?リストã‹ã‚‰ã?id属æ?ã®ã€å±žæ?値をå–å¾—ã—ã¾ã™ã?
250             *
251             * id属æ? ã¯ã€å?部çš?«ã‚­ãƒ£ãƒ?‚·ãƒ¥ã—ã¦ãŠã‚Šã€ã™ãã«å–り出ã›ã¾ã™ã?
252             * タグを特定ã™ã‚‹å?åˆã?ä¸?ˆ¬å±žæ?ã®ã‚­ãƒ¼ã¨å€¤ã§é¸åˆ¥ã™ã‚‹ã®ã§ã¯ãªãã?
253             * id属æ?を付与ã—ã¦é¸åˆ¥ã™ã‚‹ã‚ˆã†ã«ã™ã‚Œã°ã€?«˜é?ã«è¦‹ã¤ã‘ã‚‹ã“ã¨ãŒå¯èƒ½ã«ãªã‚Šã¾ã™ã?
254             *
255             * @og.rev 5.1.9.0 (2010/08/01) æ–°è¦è¿½åŠ?
256             *
257             * @return      id属æ?値
258             */
259            public String getId() { return id; }
260    
261            /**
262             * 属æ?リストã?ã€æŒ‡å®šã?é…å?番å·ã«ã€å±žæ?値を設定ã—ã¾ã™ã?
263             *
264             * @og.rev 5.1.9.0 (2010/08/01) id 属æ?ã®ã¿ç‰¹åˆ¥ã«ã‚­ãƒ£ãƒ?‚·ãƒ¥ã—ã¦ãŠãã€?
265             *
266             * @param       adrs    é…å?番å·
267             * @param       val     属æ?値
268             */
269            public void setVal( final int adrs , final String val ) {
270                    OGAtts atts = attList.remove(adrs) ;
271                    attList.add( adrs , new OGAtts( atts.KEY,val ) );
272    
273                    if( "id".equals( atts.KEY ) ) { id = val; }             // 5.1.9.0 (2010/08/01)
274            }
275    
276            /**
277             * 属æ?リストã«ã€æŒ‡å®šã?キーã€å±žæ?値を設定ã—ã¾ã™ã?
278             * ã‚‚ã—ã€å±žæ?リストã«ã€æŒ‡å®šã?キーãŒã‚れã?ã€å±žæ?値を変更ã—ã¾ã™ã?
279             * ãªã‘れã°ã€æœ€å¾Œã«è¿½åŠ?—ã¾ã™ã?
280             *
281             * @og.rev 5.6.1.2 (2013/02/22) æ–°è¦è¿½åŠ?
282             *
283             * @param       key     属æ?キー
284             * @param       val     属æ?値
285             */
286            public void setVal( final String key , final String val ) {
287                    int adrs = getAdrs( key );
288                    if( adrs < 0 ) { add( key,val ); }
289                    else           { setVal( adrs,val ); }
290            }
291    
292            /**
293             * 属æ?リストã«ã€å±žæ?(キーã€å?ã®ã‚»ãƒ?ƒˆ)を設定ã—ã¾ã™ã?
294             *
295             * 属æ?リストã?ä¸?•ªæœ?¾Œã«ã€å±žæ?(キーã€å?ã®ã‚»ãƒ?ƒˆ)を設定ã—ã¾ã™ã?
296             *
297             * @og.rev 5.1.9.0 (2010/08/01) id 属æ?ã®ã¿ç‰¹åˆ¥ã«ã‚­ãƒ£ãƒ?‚·ãƒ¥ã—ã¦ãŠãã€?
298             *
299             * @param       key     属æ?リストã?キー
300             * @param       val     属æ?リストã?値
301             */
302            public void add( final String key , final String val ) {
303    
304                    OGAtts atts = new OGAtts( key,val );
305                    attList.add( atts );
306                    maxValLen = atts.maxKeyLen( maxValLen );
307    
308                    if( "id".equals( key ) ) { id = val; }          // 5.1.9.0 (2010/08/01)
309            }
310    
311            /**
312             * æŒ?®šã?アドレスã®å±žæ?リストã«ã€å±žæ?(キーã€å?ã®ã‚»ãƒ?ƒˆ)を設定ã—ã¾ã™ã?
313             *
314             * æŒ?®šã?アドレスã®å±žæ?ã‚’ç½®ãæ›ãˆã‚‹ã®ã§ã¯ãªã追åŠ?—ã¾ã™ã?
315             *
316             * @og.rev 5.1.9.0 (2010/08/01) id 属æ?ã®ã¿ç‰¹åˆ¥ã«ã‚­ãƒ£ãƒ?‚·ãƒ¥ã—ã¦ãŠãã€?
317             *
318             * @param       adrs    属æ?リストã?アドレス
319             * @param       key     属æ?リストã?キー
320             * @param       val     属æ?リストã?値
321             */
322            public void add( final int adrs , final String key , final String val ) {
323    
324                    OGAtts atts = new OGAtts( key,val );
325                    attList.add( adrs , atts );
326                    maxValLen = atts.maxKeyLen( maxValLen );
327    
328                    if( "id".equals( key ) ) { id = val; }          // 5.1.9.0 (2010/08/01)
329            }
330    
331            /**
332             * æŒ?®šã?アドレスã®å±žæ?リストã‹ã‚‰ã?属æ?æƒ??を削除ã—ã¾ã™ã?
333             *
334             * æŒ?®šã?アドレスã®å±žæ?ã‚’ç½®ãæ›ãˆã‚‹ã®ã§ã¯ãªã追åŠ?—ã¾ã™ã?
335             *
336             * @og.rev 5.1.9.0 (2010/08/01) id 属æ?ã®ã¿ç‰¹åˆ¥ã«ã‚­ãƒ£ãƒ?‚·ãƒ¥ã—ã¦ãŠãã€?
337             *
338             * @param       adrs    属æ?リストã?アドレス
339             */
340            public void remove( final int adrs ) {
341    //              attList.remove(adrs) ;
342    
343                    OGAtts atts = attList.remove(adrs) ;
344    
345                    if( "id".equals( atts.KEY ) ) { id = null; }            // 5.1.9.0 (2010/08/01)
346    
347                    // 削除ã—ãŸã‚­ãƒ¼ã?maxValLen ã?£ãŸã¨ã—ã¦ã‚‚ã?å†è¨ˆç®—ã?ã€è¡Œã„ã¾ã›ã‚“ã€?
348                    // å†è¨ˆç®—ã¨ã¯ã€æ¬¡ã®é•·ã•を見ã¤ã‘ã‚‹å¿?¦ãŒã‚ã‚‹ã®ã§ã€ã™ã¹ã¦ã® OGAtts ã‚’ã‚‚ã?¸?º¦
349                    // ãƒã‚§ãƒ?‚¯ã™ã‚‹å¿?¦ãŒå‡ºã¦ãã‚‹ãŸã‚ã§ã™ã?
350            }
351    
352            /**
353             * オブジェクトã?æ–?­—å?表ç¾ã‚’è¿”ã—ã¾ã™ã?
354             *
355             * 属æ?ã«ã¤ã?¦ã¯ã€ä¸¦ã³é ??ã€ç™»éŒ²é ?Œä¿éšœã•れã¾ã™ã?
356             *
357             * 属æ?ã¯ã€?¼“ã¤ã®ãƒ‘ã‚¿ãƒ¼ãƒ³ã§æ–?­—å?化を行ã„ã¾ã™ã?
358             *  ・useCR=true ã®å ´å?
359             *     ã“ã?å ´åˆã?ã€å±žæ?を1行ãšã¤æ”¹è¡Œã—ãªãŒã‚‰ä½œæ?ã—ã¾ã™ã?属æ?キーã¯ã€?
360             *     æœ?¤§é•·?‹ï¼?ã§ã‚¹ãƒšã?ス埋ã‚ã•れã¦ã€æ•´å½¢ã•れã¾ã™ã?
361             *  ・useCR=false ã®å ´å?
362             *     ・属æ?ã®å€‹æ•°åˆ¶é™?CR_CNT)å˜ä½ã«ã€æ”¹è¡ŒãŒè¡Œã‚れã¾ã™ã?
363             *       ã“れã¯ã€å±žæ?ãŒå³ã«å¤šã並ã³ã™ãŽã‚‹ã?を防ãŽã¾ã™ã?
364             *     ・属æ?ã®é•·ã•制é™?CR_LEN)å˜ä½ã§ã€æ”¹è¡ŒãŒè¡Œã‚れã¾ã™ã?
365             *       ã“れã¯ã€ãŸã¨ãˆã?属æ?ã®å€‹æ•°ãŒå°‘ãªãã¦ã‚‚ã?æ–?­—å?ã¨ã—ã¦é•·ã??åˆã?ã€?
366             *       改行ã•ã›ã¾ã™ã?
367             *
368             * @og.rev 5.6.1.2 (2013/02/22) 改行å?ç??修正。最後ã?属æ?処ç??後ã«ã‚‚改行を入れるã€?
369             * @og.rev 5.6.4.4 (2013/05/31) 改行å?ç??修正。attTabãŒã?ゼロæ–?­—å?ã®å ´åˆã?対応ã?
370             *
371             * @param       attTab  Nodeã®éšŽå±¤ã‚’è¡¨ã™æ–‡å­—å?ã€?
372             * @return      ã“ã?オブジェクトã?æ–?­—å?表ç¾
373             * @see OGNode#toString()
374             * @see #setUseCR( boolean )
375             */
376    //      @Override
377    //      public String toString() {
378            public String getText( final String attTab ) {
379                    StringBuilder buf = new StringBuilder();
380    
381                    String crTab = (attTab.length() > 0) ? attTab : CR + "\t" ;
382    
383                    if( useCR ) {
384                            for( int i=0; i<size(); i++ ) {
385                                    OGAtts atts = attList.get(i);
386    //                              buf.append( attTab );
387                                    buf.append( crTab );
388                                    buf.append( atts.getAlignKey( maxValLen ) ).append( " = " ).append( atts.QRT_VAL );
389                            }
390                            // 5.6.1.2 (2013/02/22) 改行å?ç??修正。最後ã?属æ?処ç??後ã«ã‚‚改行を入れるã€?
391                            buf.append( CR );
392                    }
393                    else {
394                            int crCnt = 0;
395                            int crLen = 0;
396                            for( int i=0; i<size(); i++ ) {
397                                    OGAtts atts = attList.get(i);
398                                    crCnt++ ;
399                                    crLen += atts.LEN;
400                                    if( i>0 && (crCnt > CR_CNT || crLen > CR_LEN) ) {
401    //                                      buf.append( attTab );
402                                            buf.append( crTab );
403                                            buf.append( atts.KEY ).append( "=" ).append( atts.QRT_VAL );
404                                            crCnt = 0;
405                                            crLen = 0;
406                                    }
407                                    else {
408                                            buf.append( " " ).append( atts.KEY ).append( "=" ).append( atts.QRT_VAL );
409                                    }
410                            }
411    //                      buf.append( " " );
412                    }
413    
414                    return buf.toString();
415            }
416    
417            /**
418             * オブジェクトã?æ–?­—å?表ç¾ã‚’è¿”ã—ã¾ã™ã?
419             *
420             * @og.rev 5.6.1.2 (2013/02/22) 改行å?ç??修正。最後ã?属æ?処ç??後ã«ã‚‚改行を入れるã€?
421             *
422             * @return      ã“ã?オブジェクトã?æ–?­—å?表ç¾
423             * @see OGNode#toString()
424             */
425            @Override
426            public String toString() {
427                    return getText( " " );
428            }
429    }
430    
431    /**
432     * 属æ?キーã¨å±žæ?値を管ç?™ã‚?クラス
433     *
434     * 属æ?自身ã¯ã€å±žæ?キーã¨å±žæ?値ã®ã¿ã§åå?ã§ã™ãŒã€æ”¹è¡Œå?ç?‚„æ–?­—å?ã®é•·ã•設定ã§ã€?
435     * 予ã‚å†?ƒ¨å‡¦ç?‚’ã—ã¦ãŠããŸã„ãŸã‚ã€ã‚¯ãƒ©ã‚¹åŒ–ã—ã¦ã?¾ã™ã?
436     *
437     * å†?ƒ¨å¤‰æ•°ã¯ã€final ã™ã‚‹ã“ã¨ã§å®šæ•°åŒ–ã—ã€ã‚¢ã‚¯ã‚»ã‚¹ãƒ¡ã‚½ãƒ?ƒ‰çµŒç”±ã§ã¯ãªãã?直接å†?ƒ¨å¤‰æ•°ã‚?
438     * å‚ç?ã•ã›ã‚‹ã“ã¨ã§ã€è¦‹æ?ã•を優先ã—ã¦ã?¾ã™ã?
439     */
440    final class OGAtts {
441            /** 属æ?ã®é•·ã•ã‚’ãã‚ãˆã‚‹ãŸã‚ã®ç©ºç™½æ–?­—ã?æƒ?? **/
442            private static final String     SPACE  = "                    ";        // 5.1.9.0 (2010/09/01) public â‡?private ã¸å¤‰æ›´
443    
444            /** 属æ?キー **/
445            public          final String  KEY ;
446            /** 属æ?値 **/
447            public          final String  VAL ;
448            private         final int     KLEN ;
449                                    final int     LEN ;
450                                    final String  QRT_VAL;
451    
452            /**
453             * 引数を指定ã—ã¦æ§‹ç¯‰ã™ã‚‹ã?コンストラクター
454             *
455             * 属æ?キーã¨ã€å±žæ?値 を指定ã—ã¦ã€ã‚ªãƒ–ジェクトを構築ã—ã¾ã™ã?
456             *
457             * @param       key     属æ?キー
458             * @param       val     属æ?値
459             */
460            public OGAtts( final String key , final String val ) {
461                    KEY  = key;
462    //              VAL  = (val == null) ? "" : val ;
463                    VAL  = (val == null) ? "" : htmlFilter(val) ;
464                    KLEN = key.length();
465                    LEN  = KLEN + VAL.length();
466    
467                    QRT_VAL = ( VAL.indexOf( '"' ) >= 0 ) ? "'" + VAL + "'" : "\"" + VAL + "\"" ;
468            }
469    
470            /**
471             * ã‚­ãƒ¼ã®æ–?­—é•·ã•ã?比è¼?§ã€å¤§ãã„æ•°å­—ã‚’è¿”ã—ã¾ã™ã?
472             *
473             * 属æ?ã‚­ãƒ¼ã®æœ?¤§ã®æ–?­—å?長を求ã‚ã‚‹ãŸã‚ã?引数ã®é•·ã•ã¨ã€å±žæ?キーã®é•·ã•を比è¼?—ã¦ã€?
474             * 大ããªå€¤ã®æ–¹ã‚’è¿”ã—ã¾ã™ã?
475             * ã“ã?処ç?‚’ã€å±žæ?ã™ã¹ã¦ã«è¡Œãˆã°ã€æœ€çµ‚çš„ã«æœ?‚‚大ããªå€¤ãŒæ®‹ã‚‹ã“ã¨ã«ãªã‚Šã¾ã™ã?
476             *
477             * @param       maxLen  属æ?ã‚­ãƒ¼ã®æœ?¤§é•·ã?
478             *
479             * @return      属æ?リスト群ã®é•·ã•補正ãŒè¡Œã‚れãŸã€å±žæ?キー?‹ç©ºç™½æ–?­—å?
480             */
481            protected int maxKeyLen( final int maxLen ) {
482                    return (maxLen > KLEN) ? maxLen : KLEN ;
483            }
484    
485            /**
486             * é•·ã•補正ãŒè¡Œã‚れãŸå±žæ?キーをå–å¾—ã—ã¾ã™ã?
487             *
488             * useCR=true ã®å ´åˆã«ã€å±žæ?ã®æ”¹è¡ŒãŒè¡Œã‚れã¾ã™ãŒã€ãã®ã¨ãã«ã€ã‚­ãƒ¼ãŒç¸¦ã«ä¸¦ã³ã¾ã™ã?
489             * ãã—ã¦ã€å?も縦ã«ä¸¦ã¶ãŸã‚ã€?–“ã® ?¢?」記å·ã®ä½ç½®ã‚’ãã‚ãˆã¦ã€è¡¨ç¤ºã—ã¾ã™ã?
490             * 属æ?リストã?æœ?¤§é•·ã•+ï¼?ã«ãªã‚‹ã‚ˆã?«ã€ã‚­ãƒ¼ã®æ–?­—å?ã«ã‚¹ãƒšã?スを埋ã‚ã¾ã™ã?
491             * ã“れã«ã‚ˆã‚Šã€å±žæ?を改行ã—ã¦è¡¨ç¤ºã—ã¦ã‚‚ã?値ã®è¡¨ç¤ºä½ç½®ãŒãã‚ã„ã¾ã™ã?
492             *
493             * @param       maxLen  属æ?ã‚­ãƒ¼ã®æœ?¤§é•·ã?
494             *
495             * @return      属æ?リスト群ã®é•·ã•補正ãŒè¡Œã‚れãŸã€å±žæ?キー?‹ç©ºç™½æ–?­—å?
496             */
497            protected String getAlignKey( final int maxLen ) {
498                    return KEY + SPACE.substring( KLEN,maxLen ) ;
499            }
500    
501            /**
502             * HTML上ã?エスケープ文字を変æ›ã—ã¾ã™ã?
503             *
504             * HTMLã§è¡¨ç¤ºã™ã‚‹å ´åˆã«ãã¡ã‚“ã¨ã‚¨ã‚¹ã‚±ãƒ¼ãƒ—文字ã«å¤‰æ›ã—ã¦ãŠã‹ãªã?¨
505             * Script を実行ã•れãŸã‚Šã?ä¸è¦ãªHTMLコマンドを潜り込ã¾ã•れãŸã‚Šã™ã‚‹ãŸã‚ã€?
506             * セキュリãƒ?‚£ãƒ¼ãƒ›ã?ルã«ãªã‚‹å¯èƒ½æ€§ãŒã‚ã‚‹ã?ã§ã€æ³¨æ„ã—ã¦ãã ã•ã„ã€?
507             *
508             * ※ オリジナルã¯ã€org.opengion.fukurou.util.StringUtil#htmlFilter( String )
509             * ã§ã™ãŒã€ãƒ€ãƒ–ルクオートã?シングルクオートã?変æ›å‡¦ç?‚’çœã„ã¦ã?¾ã™ã?
510             *
511             * @param       input HTMLエスケープå‰ã®æ–?­—å?
512             *
513             * @return      エスケープ文字ã«å¤‰æ›å¾Œã?æ–?­—å?
514             * @see  org.opengion.fukurou.util.StringUtil#htmlFilter( String )
515             */
516            private String htmlFilter( final String input ) {
517                    if( input == null || input.length() == 0 ) { return ""; }
518                    StringBuilder rtn = new StringBuilder();
519                    char ch;
520                    for(int i=0; i<input.length(); i++) {
521                            ch = input.charAt(i);
522                            switch( ch ) {
523                                    case '<'  : rtn.append("&lt;");   break;
524                                    case '>'  : rtn.append("&gt;");   break;
525                    //              case '"'  : rtn.append("&quot;"); break;
526                    //              case '\'' : rtn.append("&#39;");  break;
527                                    case '&'  : rtn.append("&amp;");  break;
528                                    default   : rtn.append(ch);
529                            }
530                    }
531                    return( rtn.toString() );
532            }
533    }