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        public LabelData( final String inkey ) {
096                key                     = inkey.intern() ;
097                label           = key ;         // 名称(長)
098                shortLabel      = key ;         // 名称(HTML短)
099                longLabel       = key ;         // 名称(HTML長)
100                description     = ""  ;         // 概要説明
101                official        = false;        // 非正式
102                isFormat        = false;        // 非フォーマット 4.0.0.0 (2007/10/17)
103                rawShortLabel = key;    // 名称(未変換短) 4.3.8.0 (2009/08/01)
104                isFormatDesc = false;   // 概要フォーマット 4.3.7.6 (2009/07/15)
105                rawLongLabel = key;             // 名称(未変換長)5.6.8.2 (2013/09/20)
106        }
107
108        /**
109         * 配列文字列のデータを元に、LabelDataオブジェクトを構築します。
110         * このコンストラクタは、他のパッケージから呼び出せないように、
111         * パッケージプライベートにしておきます。
112         * このコンストラクタは、DBリソースファイルを想定しています。
113         *
114         * @og.rev 5.4.0.1 (2011/11/01) SNAME、概要説明、rawShortLabel 関係の処理を修正
115         * @og.rev 5.6.8.2 (2013/09/20) rawLongLabel対応
116         *
117         * @param       data    CLM,SNAME,LNAME,DESCRIPTION
118         */
119        LabelData( final String[] data ) {
120                key                     = data[CLM].intern() ;                                                  // 項目
121                label           = StringUtil.nval2( data[LNAME],"" ) ;                  // 名称(HTML長)
122                description     = data[DESCRIPTION] ;                                                   // 概要説明
123                official        = true;                                                                                 // 正式
124                isFormat        = label.indexOf( '{' ) >= 0 ;                   // 4.0.0.0 (2007/10/17)
125                String title = null;
126                
127                rawLongLabel = label;           // 名称(未変換長)5.6.8.2 (2013/09/20)
128                if( description == null || description.length() == 0 ) {
129                        isFormatDesc = false;
130                        // 5.4.0.1 (2011/11/01) title と label が間違っている。(SNAME が存在する場合)
131                        title     = StringUtil.htmlFilter( label ) ;
132
133                        // 概要説明がない場合は、そのままラベルを使用する。
134                        longLabel = label;
135                }
136                else {
137                        isFormatDesc = description.indexOf( '{' ) >= 0 ;                // 5.1.8.0 (2010/07/01) nullポインタの参照外し対策
138                        title        = StringUtil.htmlFilter( description ) ;
139
140                        // 概要説明がある場合は、ツールチップにDESCRIPTIONを表示する。
141                        longLabel = "<span title=\""
142                                                        + title
143                                                        + "\">"
144                                                        + label
145                                                        + "</span>" ;
146                }
147
148                String sname = data[SNAME];             // 名称(HTML短)
149                if( sname == null || sname.length() == 0 ) {
150                        // SNAME がない場合は、longLabel を使用する。
151                        shortLabel    = longLabel;
152                        rawShortLabel = label;          // 5.4.0.1 (2011/11/01) longLabel を使うと、ツールチップが加味されるため。
153                }
154                else {
155                        // SNAME が存在する場合、ツールチップにdescriptionかlabelを使用する。
156                        shortLabel = "<span title=\""
157                                                        + title
158                                                        + "\">"
159                                                        + sname
160                                                        + "</span>" ;
161                        rawShortLabel = sname; // 4.3.8.0 (2009/08/01)
162                }
163        }
164
165        /**
166         * ラベルオブジェクトのキーを返します。
167         *
168         * @return      ラベルオブジェクトのキー
169         */
170        public String getKey() { return key; }
171
172        /**
173         * ラベルオブジェクトの名称を返します。
174         * これは、DB上の LNAME(名称(長))に該当します。
175         *
176         * @return      ラベルオブジェクトの名称(短)
177         */
178        public String getLabel() { return label; }
179
180        /**
181         * ラベルオブジェクトの名称(短)を返します。
182         * 概要説明がない場合でかつDB上のSNAMEが未設定の場合は、
183         * LNAME が返されます。SNAMEが設定されている場合は、
184         * ツールチップにLNAME が表示されます。
185         * 概要説明が存在する場合は、ツールチップに概要説明が
186         * 表示されます。
187         *
188         * @return      ラベルオブジェクトの名称(短)
189         */
190        public String getShortLabel() { return shortLabel; }
191
192        /**
193         * ラベルオブジェクトの名称(長)を返します。
194         * 概要説明が存在する場合は、ツールチップに概要説明が
195         * 表示されます。
196         *
197         * @return      ラベルオブジェクトの名称(長)
198         * @see #getLongLabel( String )
199         */
200        public String getLongLabel() { return longLabel; }
201
202        /**
203         * ラベルインターフェースの名称(長)を返します。
204         * ツールチップに表示するタイトル属性(概要説明)を置き換えます。
205         * null の場合は、既存のgetLongLabel()を返します。
206         *
207         * @param       title   ツールチップに表示するタイトル属性
208         *
209         * @return      ラベルインターフェースの名称(長)
210         * @see #getLongLabel()
211         */
212        public String getLongLabel( final String title ) {
213                final String tipsLabel ;
214                if( title == null ) {
215                        tipsLabel = longLabel;
216                }
217                else {
218                        tipsLabel = "<span title=\""
219                                                        + StringUtil.htmlFilter( title )
220                                                        + "\">"
221                                                        + label
222                                                        + "</span>" ;
223                }
224                return tipsLabel ;
225        }
226
227        /**
228         * ラベルインターフェースの引数付きメッセージを返します。
229         * メッセージの引数部分に、文字列配列を適用して、MessageFormat
230         * で変換した結果を返します。(MessageData でのみ有効です。)
231         *
232         * @og.rev 4.0.0.0 (2007/10/17) メッセージリソース統合に伴い、MessageDataより移行
233         * @og.rev 4.3.8.0 (2009/08/01) 引数にHTMLサニタイジング処理
234         * @og.rev 5.0.0.2 (2009/09/15) サニタイジング処理をやめる
235         *
236         * @param       vals    メッセージの引数(文字列配列)
237         *
238         * @return      ラベルインターフェースの引数付きメッセージ
239         */
240        public String getMessage( final String[] vals ) {
241                final String rtn ;
242
243                String[] args = ( vals == null ) ? new String[0] : vals ;
244                if( isFormat ) {
245                        rtn = MessageFormat.format( label,(Object[])args );
246                }
247                else {
248                        StringBuilder buf = new StringBuilder();
249                        buf.append( label );
250                        for( int i=0; i<args.length; i++ ) {
251                                if( args[i] != null && ! args[i].equals( label ) ) {
252                                        buf.append( " " ).append( args[i] );
253                                }
254                        }
255                        rtn = buf.toString();
256                }
257                return rtn ;
258        }
259
260        /**
261         * ラベルオブジェクトの概要説明を返します。
262         * 概要説明が存在する場合は、ラベルのツールチップに
263         * 概要説明が表示されます。
264         *
265         * @return      ラベルオブジェクトの概要説明
266         */
267        public String getDescription() { return description; }
268
269        /**
270         * ラベルオブジェクトの概要説明を返します。
271         * このメソッドでは{0},{1}...をパラメータで置換します。
272         *
273         * @og.rev 4.3.7.6 (2009/07/15) 新規作成
274         * @og.rev 4.3.8.0 (2009/08/01) 引数にHTMLサニタイジング処理
275         * @og.rev 5.0.0.2 (2009/09/15) サニタイジング処理をやめる
276         * @og.rev 5.4.0.1 (2011/11/01) {}が存在しない場合は単に概要を出力
277         *
278         * @param       vals    メッセージの引数(文字列配列)
279         *
280         * @return      ラベルオブジェクトの概要説明
281         */
282        public String getDescription( final String[] vals ) {
283                final String rtn ;
284
285                String[] args = ( vals == null ) ? new String[0] : vals ;
286                if( isFormatDesc ) {
287                        rtn = MessageFormat.format( description,(Object[])args );
288                }
289                else {
290                        // 5.4.0.1 (2011/11/01) {}が存在しない場合は単に概要を出力 ・・・ なら、直接セットに変更
291                        rtn = description;
292                }
293                return rtn ;
294        }
295
296        /**
297         * リソースDBから作成されたかどうかを返します。
298         * 正式な場合は、true / リソースになく、独自に作成された場合は、false になります。
299         *
300         * @return      リソースDBから作成されたかどうか
301         */
302        public boolean isOfficial() { return official; }
303
304        /**
305         * ラベルオブジェクトの名称(長)をそのままの形で返します。
306         * (discription等を付けない)
307         *
308         * @og.rev 5.6.8.2 (2009/08/01) 追加
309         *
310         * @return      ラベルオブジェクトの名称(長)そのままの状態
311         */
312        public String getRawLongLabel() { return rawLongLabel; }
313        
314        /**
315         * ラベルオブジェクトの名称(短)をspanタグを付けない状態で返します。
316         * SNAMEが未設定の場合は、LNAME が返されます。
317         *
318         * @og.rev 4.3.8.0 (2009/08/01) 追加
319         *
320         * @return      ラベルオブジェクトの名称(短)にspanタグを付けない状態
321         */
322        public String getRawShortLabel() { return rawShortLabel; }
323
324        /**
325         * オブジェクトの識別子として,詳細なユーザー情報を返します。
326         *
327         * @return  詳細なユーザー情報
328         */
329        @Override
330        public String toString() {
331                StringBuilder rtn = new StringBuilder( HybsSystem.BUFFER_MIDDLE );
332                rtn.append( "CLM :" ).append( key );
333                rtn.append( " SNAME :" ).append( shortLabel );
334                rtn.append( " LNAME :" ).append( longLabel );
335                rtn.append( " DESCRIPTION :" ).append( description ).append( HybsSystem.CR );
336                return rtn.toString();
337        }
338}