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.hayabusa.resource;
017
018import java.text.MessageFormat;
019
020import org.opengion.hayabusa.common.HybsSystem ;
021import org.opengion.fukurou.util.StringUtil ;
022
023/**
024 * systemId , lang に対応したラベルデータを作成します。
025 *
026 * ラベルデータは、項目(CLM)に対して、各種ラベル情報を持っています。
027 * 従来のラベルは、表示名称として、一種類しか持っていませんでしたが、
028 * ラベルデータは、3種類の名称と、1種類の概要を持っています。
029 *
030 *   label       : 名称(長)      従来のラベルと同じで定義された文字そのものです。
031 *   shortLabel  : 名称(HTML短)  概要説明をバルーン表示する短い名称です。
032 *   longLabel   : 名称(HTML長)  概要説明をバルーン表示する長い名称です。
033 *   description : 概要説明      カラムの説明やバルーンに使用します。
034 *
035 * 名称(HTML長)は、従来の表示名称にあたります。これは、一般的なラベルとして
036 * 使用されます。名称(HTML短)は、テーブル一覧のヘッダーの様に、特殊なケースで、
037 * 簡略化された名称を使用するときに利用されます。この切り替えは、自動で判断されます。
038 * 名称(HTML短)に、なにも設定されていない場合は、名称(HTML長)が自動的に使用されますので
039 * 初期データ移行時には、そのまま、通常時もテーブルヘッダー時も同じ文字列が
040 * 使用されます。
041 * ただし、一覧表示のうち、EXCEL出力などのデータには、名称(長)が使用されます。
042 * これは、名称(HTML短)や名称(HTML長)は、Tips表示を行う為のHTML構文を採用している為
043 * テキスト等に出力するには不適切だからです。また、EXCEL等のツールでは、ラベル名が
044 * 長くてもセル幅等で調整できる為、簡略化された名称よりも正式名称で出力します。
045 *
046 * ラベルデータを作成する場合は、同一ラベルで、作成区分(KBSAKU)違いの場合は、
047 * 最も大きな作成区分を持つコードを使用します。
048 * 作成区分(KBSAKU)は、0:システム予約、1:アプリ設定、2:ユーザー設定 という具合に
049 * カスタマイズの度合いに応じて大きな数字を割り当てることで、キー情報を上書き修正
050 * することが可能になります。(削除することは出来ません。)
051 *
052 * @og.rev 4.0.0.0 (2004/12/31) 新規作成
053 * @og.group リソース管理
054 *
055 * @version  4.0
056 * @author   Kazuhiko Hasegawa
057 * @since    JDK5.0,
058 */
059public final class LabelData implements LabelInterface {
060
061        /** 内部データのカラム番号 {@value}        */
062        public static final int CLM                     = 0 ;
063        /** 内部データのカラム番号 {@value}        */
064        public static final int SNAME           = 1 ;
065        /** 内部データのカラム番号 {@value}        */
066        public static final int LNAME           = 2 ;
067        /** 内部データのカラム番号 {@value}        */
068        public static final int DESCRIPTION     = 3 ;
069        /** 内部データのカラム数 {@value} */
070        public static final int DATA_SIZE       = 4 ;
071        /** リソース読み込みのために一時利用 4.3.5.7 (2009/03/22) */
072        public static final int FG_LOAD         = 4 ;
073
074        private final String    key                     ;               // 項目
075        private final String    label           ;               // 名称(長)
076        private final String    shortLabel      ;               // 名称(HTML短)
077        private final String    longLabel       ;               // 名称(HTML長)
078        private final String    description     ;               // 概要説明
079        private final boolean   official        ;               // リソースDBから作成されたかどうか
080        private final boolean   isFormat        ;               // メッセージフォーマット対象かどうか 4.0.0.0 (2007/10/17)
081        private final String    rawShortLabel;          // 名称(未変換短) 4.3.8.0 (2009/08/01)
082        private final boolean   isFormatDesc;           // 概要がフォーマット対象か 4.3.7.6 (2009/07/15)
083        private final String    rawLongLabel;           // 名称(未変換長) 5.6.8.2 (2013/09/20)
084
085        /**
086         * null LabelData オブジェクトを作成します。
087         * このオブジェクトは、DBリソース上に存在しない場合に使用される
088         * null 情報を表す、LabelData オブジェクトです。
089         * 
090         * @og.rev 5.6.8.2 (2013/09/20) rawLongLabel対応
091         * @og.rev 5.7.3.0 (2014/02/07) public に格上げします。
092         *
093         * @param       inkey   キー情報
094         */
095//      LabelData( final String inkey ) {
096        public LabelData( final String inkey ) {
097                key                     = inkey.intern() ;
098                label           = key ;         // 名称(長)
099                shortLabel      = key ;         // 名称(HTML短)
100                longLabel       = key ;         // 名称(HTML長)
101                description     = ""  ;         // 概要説明
102                official        = false;        // 非正式
103                isFormat        = false;        // 非フォーマット 4.0.0.0 (2007/10/17)
104                rawShortLabel = key;    // 名称(未変換短) 4.3.8.0 (2009/08/01)
105                isFormatDesc = false;   // 概要フォーマット 4.3.7.6 (2009/07/15)
106                rawLongLabel = key;             // 名称(未変換長)5.6.8.2 (2013/09/20)
107        }
108
109        /**
110         * 配列文字列のデータを元に、LabelDataオブジェクトを構築します。
111         * このコンストラクタは、他のパッケージから呼び出せないように、
112         * パッケージプライベートにしておきます。
113         * このコンストラクタは、DBリソースファイルを想定しています。
114         *
115         * @og.rev 5.4.0.1 (2011/11/01) SNAME、概要説明、rawShortLabel 関係の処理を修正
116         * @og.rev 5.6.8.2 (2013/09/20) rawLongLabel対応
117         *
118         * @param       data    CLM,SNAME,LNAME,DESCRIPTION
119         */
120        LabelData( final String[] data ) {
121                key                     = data[CLM].intern() ;                                                  // 項目
122                label           = StringUtil.nval2( data[LNAME],"" ) ;                  // 名称(HTML長)
123                description     = data[DESCRIPTION] ;                                                   // 概要説明
124                official        = true;                                                                                 // 正式
125                isFormat = ( label.indexOf( '{' ) >= 0 ) ;                   // 4.0.0.0 (2007/10/17)
126//              isFormatDesc = ( description.indexOf( '{' ) >= 0 ); // 4.3.7.6 (2009/07/15)
127                String title = null;
128                
129                rawLongLabel = label;           // 名称(未変換長)5.6.8.2 (2013/09/20)
130                if( description == null || description.length() == 0 ) {
131                        isFormatDesc = false;
132                        // 5.4.0.1 (2011/11/01) title と label が間違っている。(SNAME が存在する場合)
133//                      title     = StringUtil.htmlFilter( title ) ;
134                        title     = StringUtil.htmlFilter( label ) ;
135
136                        // 概要説明がない場合は、そのままラベルを使用する。
137                        longLabel = label;
138                }
139                else {
140                        isFormatDesc = ( description.indexOf( '{' ) >= 0 );          // 5.1.8.0 (2010/07/01) nullポインタの参照外し対策
141                        title        = StringUtil.htmlFilter( description ) ;
142
143                        // 概要説明がある場合は、ツールチップにDESCRIPTIONを表示する。
144                        longLabel = "<span title=\""
145//                                                      + StringUtil.htmlFilter( description )
146                                                        + title
147                                                        + "\">"
148                                                        + label
149                                                        + "</span>" ;
150                }
151
152                String sname = data[SNAME];             // 名称(HTML短)
153                if( sname == null || sname.length() == 0 ) {
154                        // SNAME がない場合は、longLabel を使用する。
155                        shortLabel    = longLabel;
156//                      rawShortLabel = longLabel;      // 4.3.8.0 (2009/08/01)
157                        rawShortLabel = label;          // 5.4.0.1 (2011/11/01) longLabel を使うと、ツールチップが加味されるため。
158                }
159                else {
160                        // SNAME が存在する場合、ツールチップにdescriptionかlabelを使用する。
161//                      String title = ( description == null || description.length() == 0 ) ? label : description ;
162                        shortLabel = "<span title=\""
163//                                                      + StringUtil.htmlFilter( title )
164                                                        + title
165                                                        + "\">"
166                                                        + sname
167                                                        + "</span>" ;
168                        rawShortLabel = sname; // 4.3.8.0 (2009/08/01)
169                }
170        }
171
172        /**
173         * ラベルオブジェクトのキーを返します。
174         *
175         * @return      ラベルオブジェクトのキー
176         */
177        public String getKey() { return key; }
178
179        /**
180         * ラベルオブジェクトの名称を返します。
181         * これは、DB上の LNAME(名称(長))に該当します。
182         *
183         * @return      ラベルオブジェクトの名称(短)
184         */
185        public String getLabel() { return label; }
186
187        /**
188         * ラベルオブジェクトの名称(短)を返します。
189         * 概要説明がない場合でかつDB上のSNAMEが未設定の場合は、
190         * LNAME が返されます。SNAMEが設定されている場合は、
191         * ツールチップにLNAME が表示されます。
192         * 概要説明が存在する場合は、ツールチップに概要説明が
193         * 表示されます。
194         *
195         * @return      ラベルオブジェクトの名称(短)
196         */
197        public String getShortLabel() { return shortLabel; }
198
199        /**
200         * ラベルオブジェクトの名称(長)を返します。
201         * 概要説明が存在する場合は、ツールチップに概要説明が
202         * 表示されます。
203         *
204         * @return      ラベルオブジェクトの名称(長)
205         * @see #getLongLabel( String )
206         */
207        public String getLongLabel() { return longLabel; }
208
209        /**
210         * ラベルインターフェースの名称(長)を返します。
211         * ツールチップに表示するタイトル属性(概要説明)を置き換えます。
212         * null の場合は、既存のgetLongLabel()を返します。
213         *
214         * @param       title   ツールチップに表示するタイトル属性
215         *
216         * @return      ラベルインターフェースの名称(長)
217         * @see #getLongLabel()
218         */
219        public String getLongLabel( final String title ) {
220                final String tipsLabel ;
221                if( title == null ) {
222                        tipsLabel = longLabel;
223                }
224                else {
225                        tipsLabel = "<span title=\""
226                                                        + StringUtil.htmlFilter( title )
227                                                        + "\">"
228                                                        + label
229                                                        + "</span>" ;
230                }
231                return tipsLabel ;
232        }
233
234        /**
235         * ラベルインターフェースの引数付きメッセージを返します。
236         * メッセージの引数部分に、文字列配列を適用して、MessageFormat
237         * で変換した結果を返します。(MessageData でのみ有効です。)
238         *
239         * @og.rev 4.0.0.0 (2007/10/17) メッセージリソース統合に伴い、MessageDataより移行
240         * @og.rev 4.3.8.0 (2009/08/01) 引数にHTMLサニタイジング処理
241         * @og.rev 5.0.0.2 (2009/09/15) サニタイジング処理をやめる
242         *
243         * @param       vals    メッセージの引数(文字列配列)
244         *
245         * @return      ラベルインターフェースの引数付きメッセージ
246         */
247        public String getMessage( final String[] vals ) {
248//              return label ;
249                final String rtn ;
250//      5.0.0.2 (2009/09/15)
251//              // 4.3.8.0 valsに対してサニタイジングフィルタをかける
252//              if( vals != null && vals.length > 0){
253//                      for( int i=0; i<vals.length; i++ ){
254//                              vals[i] = StringUtil.htmlFilter( vals[i] );
255//                      }
256//              }
257
258                String[] args = ( vals == null ) ? new String[0] : vals ;
259                if( isFormat ) {
260                        rtn = MessageFormat.format( label,(Object[])args );
261                }
262                else {
263                        StringBuilder buf = new StringBuilder();
264                        buf.append( label );
265                        for( int i=0; i<args.length; i++ ) {
266                                if( args[i] != null && ! args[i].equals( label ) ) {
267                                        buf.append( " " ).append( args[i] );
268                                }
269                        }
270                        rtn = buf.toString();
271                }
272                return rtn ;
273        }
274
275        /**
276         * ラベルオブジェクトの概要説明を返します。
277         * 概要説明が存在する場合は、ラベルのツールチップに
278         * 概要説明が表示されます。
279         *
280         * @return      ラベルオブジェクトの概要説明
281         */
282        public String getDescription() { return description; }
283
284        /**
285         * ラベルオブジェクトの概要説明を返します。
286         * このメソッドでは{0},{1}...をパラメータで置換します。
287         *
288         * @og.rev 4.3.7.6 (2009/07/15) 新規作成
289         * @og.rev 4.3.8.0 (2009/08/01) 引数にHTMLサニタイジング処理
290         * @og.rev 5.0.0.2 (2009/09/15) サニタイジング処理をやめる
291         * @og.rev 5.4.0.1 (2011/11/01) {}が存在しない場合は単に概要を出力
292         *
293         * @param       vals    メッセージの引数(文字列配列)
294         *
295         * @return      ラベルオブジェクトの概要説明
296         */
297        public String getDescription( final String[] vals ) {
298                final String rtn ;
299
300//              5.0.0.2 (2009/09/15)
301//              // 4.3.8.0 valsに対してサニタイジングフィルタをかける
302//              if( vals != null && vals.length > 0){
303//                      for( int i=0; i<vals.length; i++ ){
304//                              vals[i] = StringUtil.htmlFilter( vals[i] );
305//                      }
306//              }
307
308                String[] args = ( vals == null ) ? new String[0] : vals ;
309                if( isFormatDesc ) {
310                        rtn = MessageFormat.format( description,(Object[])args );
311                }
312                else {
313//                      StringBuilder buf = new StringBuilder();
314//                      buf.append( description );
315//                      // Descriptionでは{}が存在しない場合は単に概要を出力
316//                      // for( int i=0; i<args.length; i++ ) {
317//                      //      if( args[i] != null && ! args[i].equals( description ) ) {
318//                      //              buf.append( " " ).append( args[i] );
319//                      //      }
320//                      // }
321//                      rtn = buf.toString();
322
323                        // 5.4.0.1 (2011/11/01) {}が存在しない場合は単に概要を出力 ・・・ なら、直接セットに変更
324                        rtn = description;
325                }
326                return rtn ;
327        }
328
329        /**
330         * リソースDBから作成されたかどうかを返します。
331         * 正式な場合は、true / リソースになく、独自に作成された場合は、false になります。
332         *
333         * @return      リソースDBから作成されたかどうか
334         */
335        public boolean isOfficial() { return official; }
336
337        /**
338         * ラベルオブジェクトの名称(長)をそのままの形で返します。
339         * (discription等を付けない)
340         *
341         * @og.rev 5.6.8.2 (2009/08/01) 追加
342         *
343         * @return      ラベルオブジェクトの名称(長)そのままの状態
344         */
345        public String getRawLongLabel() { return rawLongLabel; }
346        
347        /**
348         * ラベルオブジェクトの名称(短)をspanタグを付けない状態で返します。
349         * SNAMEが未設定の場合は、LNAME が返されます。
350         *
351         * @og.rev 4.3.8.0 (2009/08/01) 追加
352         *
353         * @return      ラベルオブジェクトの名称(短)にspanタグを付けない状態
354         */
355        public String getRawShortLabel() { return rawShortLabel; }
356
357        /**
358         * オブジェクトの識別子として,詳細なユーザー情報を返します。
359         *
360         * @return  詳細なユーザー情報
361         */
362        @Override
363        public String toString() {
364                StringBuilder rtn = new StringBuilder( HybsSystem.BUFFER_MIDDLE );
365                rtn.append( "CLM :" ).append( key );
366                rtn.append( " SNAME :" ).append( shortLabel );
367                rtn.append( " LNAME :" ).append( longLabel );
368                rtn.append( " DESCRIPTION :" ).append( description ).append( HybsSystem.CR );
369                return rtn.toString();
370        }
371}