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 org.opengion.hayabusa.common.HybsSystem ;
019import java.util.Map;
020import java.util.HashSet;
021import java.util.LinkedHashMap ;
022import java.util.Arrays;
023import static org.opengion.fukurou.util.StringUtil.nval2;
024import static org.opengion.fukurou.system.HybsConst.BUFFER_MIDDLE;                              // 6.1.0.0 (2014/12/26) refactoring
025
026/**
027 * systemId と lang に対応したコードデータを作成します。
028 *
029 * コードデータは、項目(CLM)に対して、複数のコード(CODE)を持っています。
030 * この複数のコードを表示順に持つことで、プルダウンメニュー等の表示順を指定します。
031 *
032 * コードデータを作成する場合は、同一項目・コードで、作成区分違いの場合は、
033 * 最も大きな作成区分を持つコードを使用します。
034 * 作成区分(KBSAKU)は、他のリソースと異なり、基本的には使用しません。
035 * これは、通常は項目単位に作成区分を持つべきところを、コード単位でしか
036 * 持てないデータベースの設計になっている為です。アプリケーション側で設定条件を
037 * きちんと管理すれば、作成区分を使用できますが、一般にはお奨めできません。
038 *
039 * @og.rev 4.0.0.0 (2004/12/31) 新規作成
040 * @og.group リソース管理
041 *
042 * @version  4.0
043 * @author   Kazuhiko Hasegawa
044 * @since    JDK5.0,
045 */
046public final class CodeData {
047        private final boolean USE_MULTI_KEY_SELECT = HybsSystem.sysBool( "USE_MULTI_KEY_SELECT" ) ;
048
049        private static final String SPC = "";
050
051        /** 内部データのカラム番号 {@value}        */
052        public static final int CLM                     = 0 ;
053        public static final int CODE            = 1 ;
054        public static final int LNAME           = 2 ;
055        public static final int SNAME           = 3 ;
056        public static final int CODELVL         = 4 ;
057        public static final int CODEGRP         = 5 ;
058        public static final int CODE_PARAM      = 6 ;
059        public static final int ROLES           = 7 ;
060        public static final int SYSTEM_ID       = 8 ;
061        public static final int KBSAKU          = 9 ;
062        public static final int RSNAME          = 10;   // 4.3.8.0 (2009/08/01) spanが付かない名前短
063        public static final int RLNAME          = 11;   // 5.6.8.2 (2013/09/20) rawLongLabel対応
064        public static final int DESCRIPT        = 12;   // 6.2.0.0 (2015/02/27) description追加
065        public static final int MAX_LENGTH      = 13;   // 6.2.0.0 (2015/02/27) 変更
066
067        private final String    column ;                        // 項目
068        private final String[]  code ;                          // コード
069        private final String[]  longLabel ;                     // コード名称(長)
070        private final String[]  shortLabel ;            // コード名称(短)
071        private final String[]  codeLevel ;                     // コードレベル   ("1":option要素、"0":optgroup要素)
072        private final String[]  codeGroup ;                     // コードグループ (指定のグループキーで選別する)
073        private final String[]  codeParam ;                     // コードパラメータ
074        private final String[]  roles ;                         // ロール
075        private final boolean[] isUseFlag ;                     // 5.1.9.0 (2010/08/01) サブセット化するときの有効/無効を指定
076        private final int               size ;                          // コード項目数
077        private final boolean   isMultiSelect ;         // マルチセレクト
078        private final boolean   isUseLevel ;            // 5.1.9.0 (2010/08/01) コードレベル機能を利用するかどうか
079        private final boolean   isUseParam ;            // 5.1.9.0 (2010/08/01) パラメータを利用するかどうか
080        private final boolean   isUseGroup ;            // 5.1.9.0 (2010/08/01) コードグループを利用するかどうか
081        private final boolean   isUseRoleMode ;         // 5.1.9.0 (2010/08/01) ロールモードを利用するかどうか
082
083        private final RoleMode[] roleModes ;            // 4.3.0.0 (2008/07/04) ロールズとモードを管理するオブジェクト
084        private final String[]  rawShortLabel;          // 4.3.8.0 (2009/08/01) spanが付かない名前短
085        private final String[]  rawLongLabel;           // 5.6.8.2 (2013/09/20) 未加工名前長い
086        private final String[]  description;            // 6.2.0.0 (2015/02/27) 概要説明
087
088        /**
089         * 配列文字列のデータを元に、CodeDataオブジェクトを構築します。
090         * このコンストラクタは、他のパッケージから呼び出せないように、
091         * パッケージプライベートにしておきます。
092         * このコンストラクタは、マスタリソースファイルを想定しています。
093         *
094         * 引数の並び順は、CLM,CODE,LNAME,SNAME,CODELVL,CODEGRP,CODE_PARAM,ROLES,SYSTEM_ID,KBSAKU,RSNAME,RLNAME,DESCRIPT
095         *
096         * @og.rev 5.1.9.0 (2010/08/01) 新規追加
097         * @og.rev 6.3.6.0 (2015/08/16) System.arraycopy が使える箇所は、置き換えます。
098         *
099         * @param       clm     カラム名
100         * @param       data    規定の順番の文字列配列を格納
101         * @param       useFlag 使用フラグ配列(サブセット化するときの有効/無効を指定)
102         */
103        CodeData( final String clm, final Map<String,String[]> data , final boolean[] useFlag  ) {
104                this( clm,data );
105
106                if( useFlag != null && size == useFlag.length ) {
107                        // 6.3.6.0 (2015/08/16) System.arraycopy が使える箇所は、置き換えます。
108                        System.arraycopy( useFlag,0,isUseFlag,0,size );         // 6.3.6.0 (2015/08/16)
109                }
110        }
111
112        /**
113         * 配列文字列のデータを元に、CodeDataオブジェクトを構築します。
114         * このコンストラクタは、他のパッケージから呼び出せないように、
115         * パッケージプライベートにしておきます。
116         * このコンストラクタは、マスタリソースファイルを想定しています。
117         *
118         * 引数の並び順は、CLM,CODE,LNAME,SNAME,CODELVL,CODEGRP,CODE_PARAM,ROLES,SYSTEM_ID,KBSAKU,RSNAME,RLNAME,DESCRIPT
119         *
120         * @og.rev 4.3.0.0 (2008/07/04) ロールモードマルチ対応
121         * @og.rev 4.3.8.0 (2009/08/01) rawShortLabel追加
122         * @og.rev 4.3.8.0 (2009/08/01) グループ機能とパラメータの判定、isUseFlag フラグの追加
123         * @og.rev 5.2.2.0 (2010/11/01) "_" の取り扱いの変更
124         * @og.rev 5.6.8.2 (2103/09/20) rawlongLabel追加
125         * @og.rev 6.2.0.0 (2015/02/27) description 概要説明 追加
126         *
127         * @param       clm     カラム名
128         * @param       data    規定の順番の文字列配列を格納
129         */
130        CodeData( final String clm, final Map<String,String[]> data) {
131                column  = clm;
132
133                size = data.size();
134                final String[] cdKeys = data.keySet().toArray( new String[size] );
135
136                code            = new String[size];
137                shortLabel      = new String[size];
138                longLabel       = new String[size];
139                codeLevel       = new String[size];
140                codeGroup       = new String[size];
141                codeParam       = new String[size];
142                roles           = new String[size];
143                roleModes       = new RoleMode[size];
144                isUseFlag       = new boolean[size];            // 5.1.9.0 (2010/08/01) サブセットフラグの追加
145                rawShortLabel   = new String[size];
146                rawLongLabel    = new String[size];             // 5.6.8.2 (2103/09/20)
147                description             = new String[size];             // 6.2.0.0 (2015/02/27) 概要説明 追加
148
149                // 1文字目の重複判定により、マルチセレクトの可否を判断します。
150                final HashSet<String> set = new HashSet<>();
151                boolean isSel = USE_MULTI_KEY_SELECT;   // 判定処理を行う。false なら判定処理も行わない。
152
153                // 5.1.9.0 (2010/08/01) コードレベル、コードグループ、パラメータ、ロールの使用可否のフラグ
154                boolean isLbl  = false;
155                boolean isPrm  = false;
156                boolean isRole = false;
157                boolean isGrp  = false;
158
159                for( int i=0; i<size; i++ ) {
160                        final String[] vals = data.get( cdKeys[i] );
161
162                        code[i] = nval2( vals[CODE],SPC );
163
164                        final String lname = nval2( vals[LNAME],SPC ) ;
165                        longLabel[i] = lname;
166
167                        // null か ゼロ文字列 : LNAME をセット
168                        // "_"                : ゼロ文字列
169                        // それ以外           : そのまま SNAME をセット
170                        shortLabel[i] = nval2( vals[SNAME]     ,lname , SPC );  // 5.2.2.0 (2010/11/01)
171
172                        codeLevel[i]  = nval2( vals[CODELVL]   , SPC ) ;
173                        codeGroup[i]  = nval2( vals[CODEGRP]   , SPC ) ;
174                        codeParam[i]  = nval2( vals[CODE_PARAM], SPC ) ;
175                        roles[i]          = nval2( vals[ROLES]     , SPC ) ;
176
177                        // 5.1.9.0 (2010/08/01) コードレベル機能と、パラメータの使用判定
178                        if( !isLbl )  { isLbl  = "0".equals(   codeLevel[i] );  }
179                        if( !isPrm )  { isPrm  = ! SPC.equals( codeParam[i] );  }
180                        if( !isRole ) { isRole = ! SPC.equals( roles[i] );              }
181                        if( !isGrp )  { isGrp  = ! SPC.equals( codeGroup[i] );  }
182
183                        roleModes[i]    = RoleMode.newInstance( roles[i] );                     // ロールモード
184                        rawShortLabel[i]= nval2( vals[RSNAME] , lname , SPC  );         // 5.2.2.0 (2010/11/01)
185                        rawLongLabel[i] = nval2( vals[RLNAME] , lname , SPC  );         // 5.6.8.2 (2013/09/20)
186                        description[i]  = nval2( vals[DESCRIPT]       , SPC  );         // 6.2.0.0 (2015/02/27)
187
188                        if( isSel && lname.length() > 0 ) {
189                                isSel = set.add( lname.substring(0,1) );        // 重複時は false
190                        }
191                }
192
193                Arrays.fill( isUseFlag,true );  // 5.1.9.0 (2010/08/01) サブセットフラグの追加
194
195                isMultiSelect = USE_MULTI_KEY_SELECT && ! isSel ;       // flag の反転に注意
196                isUseLevel    = isLbl;          // 5.1.9.0 (2010/08/01) コードレベル機能を利用するかどうか
197                isUseParam    = isPrm;          // 5.1.9.0 (2010/08/01) パラメータを利用するかどうか
198                isUseRoleMode = isRole;         // 5.1.9.0 (2010/08/01) ロールモードを利用するかどうか
199                isUseGroup    = isGrp;          // 5.1.9.0 (2010/08/01) コードグループを利用するかどうか
200        }
201
202        /**
203         * コードデータのキーを返します。
204         *
205         * @return コードデータのキー
206         */
207        public String getColumn() { return column; }
208
209        /**
210         * コードデータのキーを返します。
211         *
212         * @param       seqNo   表示順
213         *
214         * @return コードデータのキー
215         */
216        public String getCodeKey( final int seqNo ) { return code[seqNo] ; }
217
218        /**
219         * コードデータの表示名を返します。
220         *
221         * @param       seqNo   表示順
222         *
223         * @return コードデータの表示名
224         */
225        public String getLongLabel( final int seqNo ) { return longLabel[seqNo]; }
226
227        /**
228         * コードデータの短縮表示名を返します。
229         *
230         * @param seqNo 表示順
231         *
232         * @return コードデータの短縮表示名
233         */
234        public String getShortLabel( final int seqNo ) { return shortLabel[seqNo]; }
235
236        /**
237         * コード階層を返します。
238         *
239         * 通常のメニューは、階層が "1" になります。optgroup要素として使用する場合は、
240         * 階層を "0" で登録します。
241         *
242         * @param seqNo 表示順
243         *
244         * @return コード階層( "1":option要素、"0":optgroup要素 )
245         */
246        public String getCodeLevel( final int seqNo ) { return codeLevel[seqNo]; }
247
248        /**
249         * このコードが、使用できるかどうかを、返します。
250         *
251         * コードグループや、コードリストなどで、サブセットを作成する場合、
252         * プルダウンなどの選択肢は、制限しますが、レンデラーのラベルは、制限しません。
253         * これは、既存データを表示させる必要がある為です。
254         * このフラグは、選択肢を作成するときに利用します。
255         * 標準状態で作成した場合は、すべての項目が、true になっています。
256         *
257         * @og.rev 5.1.9.0 (2010/08/01) 新規追加
258         *
259         * @param       seqNo   表示順
260         *
261         * @return 使用可能な場合は、true
262         */
263        public boolean isUse( final int seqNo ) { return isUseFlag[seqNo]; }
264
265        /**
266         * コードパラメータを返します。
267         *
268         * コードパラメータは、メニューの各要素(option要素)に設定するタグの内容を追記します。
269         * ここに記述した文字列をそのまま追記します。
270         *
271         * @param seqNo 表示順
272         *
273         * @return コードパラメータ
274         */
275        public String getCodeParam( final int seqNo ) { return codeParam[seqNo]; }
276
277        /**
278         * コードロールを取得します。
279         *
280         * @param       seqNo   表示順
281         *
282         * @return      コードロール
283         */
284        public String getRoles( final int seqNo ) { return roles[seqNo]; }
285
286        /**
287         * カラムオブジェクトのロールモードを返します。
288         *
289         * @og.rev 4.3.0.0 (2008/07/04) ロールモードマルチ対応
290         *
291         * @param       seqNo   表示順
292         *
293         * @return カラムオブジェクトのロールモード
294         */
295        public RoleMode getRoleMode( final int seqNo ) { return roleModes[seqNo]; }
296
297        /**
298         * ロールモードを、使用しているかどうかを、返します。
299         *
300         * ロールモードを使用している場合は、ロール制御の処理が必要です。
301         * 使用している/いないを事前に判断することで、無駄な処理を削減できます。
302         *
303         * @og.rev 5.1.9.0 (2010/08/01) 新規追加
304         *
305         * @return ロールモードを使用している場合は、true
306         */
307        public boolean useRoleMode() { return isUseRoleMode; }
308
309        /**
310         * マッチするコードデータのアドレスを返します。
311         * 一致するデータが存在しない場合は、-1 を返します。
312         *
313         * @param       key     検索するキー文字列
314         *
315         * @return コードデータのアドレス(なければ、-1)
316         */
317        public int getAddress( final String key ) {
318                int selected = -1;
319                for( int i=0; i<size; i++ ) {
320                        if( code[i].equals( key ) ) {
321                                selected = i;
322                                break;
323                        }
324                }
325                return selected;
326        }
327
328        /**
329         * コードデータの配列数を返します。
330         *
331         * @return コードデータの配列数
332         */
333        public int getSize() { return size; }
334
335        /**
336         * マルチ・キーセレクトを使用するかどうかを返します。
337         * true:使用する。false:使用しない です。
338         * 使用するにした場合でも、ラベルの先頭文字が重複しない場合は、
339         * IEの自動選択機能によりセレクト可能なため、JavaScript は出力しません。
340         *
341         * @return  選択リストで、マルチ・キーセレクトを使用するかどうか(true:使用する)
342         */
343        public boolean useMultiSelect() { return isMultiSelect; }
344
345        /**
346         * コードレベル機能を利用するかどうかを返します。
347         * true:使用する。false:使用しない です。
348         * コードレベル機能を利用する場合は、optgroup タグを出力します。
349         * 設定としては、レベル 0 に指定のカラムを optgroup として出力します。
350         *
351         * @og.rev 5.1.9.0 (2010/08/01) 新規追加
352         *
353         * @return  コードレベル機能を利用するかどうか(初期値:false:使用しない)
354         */
355        public boolean useLevel() { return isUseLevel; }
356
357        /**
358         * パラメータを利用するかどうかを返します。
359         * true:使用する。false:使用しない です。
360         * このパラメータは、class 属性として設定される値です。
361         * これを使用して、各種レイアウトなどの指定が可能です。
362         *
363         * @og.rev 5.1.9.0 (2010/08/01) 新規追加
364         *
365         * @return  パラメータを利用するかどうか(初期値:false:使用しない)
366         */
367        public boolean useParam() { return isUseParam; }
368
369        /**
370         * コードグループを利用するかどうかを返します。
371         * true:使用する。false:使用しない です。
372         * このコードグループは、リソースの引数で設定した CSV形式に
373         * 対して、値が設定されていたかどうかを返します。
374         * これにより、不要な処理を行う必要がなくなります。
375         *
376         * @og.rev 5.1.9.0 (2010/08/01) 新規追加
377         *
378         * @return  パラメータを利用するかどうか(初期値:false:使用しない)
379         */
380        public boolean useGroup() { return isUseGroup; }
381
382        /**
383         * オブジェクトの識別子として,詳細なコード情報を返します。
384         * キー:ラベル ・・の繰り返し文字列を返します。
385         *
386         * @og.rev 4.1.0.0 (2008/01/18) 新規追加
387         *
388         * @return  詳細なコード情報
389         */
390        public String toCodeString() {
391                final StringBuilder rtn = new StringBuilder( BUFFER_MIDDLE );
392                for( int i=0; i<size; i++ ) {
393                        final String key = code[i] + ":" ;
394                        if( ! longLabel[i].startsWith( key ) ) {
395                                rtn.append( key );
396                        }
397                        rtn.append( longLabel[i] );
398                        rtn.append( ' ' );              // 6.0.2.5 (2014/10/31) char を append する。
399                }
400                return rtn.toString().trim();
401        }
402
403        /**
404         * コードデータの短縮表示名(spanタグ無し)を返します。
405         *
406         * @og.rev 4.3.8.0 (2009/08/01) 新規追加
407         *
408         * @param seqNo 表示順
409         *
410         * @return コードデータの短縮表示名(spanタグ無し)
411         */
412        public String getRawShortLabel( final int seqNo ) { return rawShortLabel[seqNo]; }
413
414        /**
415         * 未加工の名前長を返します。
416         *
417         * @og.rev 5.6.8.2 (2013/09/13) 新規追加
418         *
419         * @param seqNo 表示順
420         *
421         * @return コードデータの短縮表示名(spanタグ無し)
422         */
423        public String getRawLongLabel( final int seqNo ) { return rawLongLabel[seqNo]; }
424
425        /**
426         * 概要説明 を返します。
427         *
428         * この概要説明は、個々の コードに対する説明です。
429         * optionタグに、title属性として使用すれば、説明文になります。
430         *
431         * @og.rev 6.2.0.0 (2015/02/27) description 概要説明 追加
432         *
433         * @param seqNo 表示順
434         *
435         * @return コードデータの概要説明
436         */
437        public String getDescription( final int seqNo ) { return description[seqNo]; }
438
439        /**
440         * 指定のコードに限定された CodeData を構築して返します。
441         * このサブセットは、コードのCSV文字列に基づいて作成されます。
442         *
443         * この CodeData は、本当のサブセットではなく、プルダウンメニューなどの選択肢のリストを
444         * 制限します。これは、一覧表示(レンデラー)では、すべての既存の設定値を表示しておく
445         * 必要があるからです。そして、変更時(エディター)に、選択肢を制限します。
446         *
447         * 引数の codeCsv が、null,ゼロ文字列の場合は、自分自身を返します。(同一です)
448         *
449         * @og.rev 5.1.9.0 (2010/08/01) 新規追加
450         * @og.rev 5.6.8.2 (2013/09/20) rawLongLabel対応
451         * @og.rev 6.2.0.0 (2015/02/27) description 概要説明 追加
452         *
453         * @param       codeCsv 指定のコードをカンマで連結されたもの
454         *
455         * @return 指定のコードに限定された CodeData
456         * @og.rtnNotNull
457         */
458        public CodeData subsetList( final String codeCsv ) {
459                if( codeCsv == null || codeCsv.isEmpty() ) {
460                        return this;
461                }
462
463                final String codes = "," + codeCsv + "," ;
464
465                boolean[] useFlag = new boolean[size] ;
466
467                final Map<String,String[]> data = new LinkedHashMap<>();
468                for( int adrs=0; adrs<size; adrs++ ) {
469                        final String key = code[adrs] ;
470                        useFlag[adrs] = codes.indexOf( "," + key + "," ) >= 0 ; // 存在する場合のみ、true
471                        String[] vals = new String[MAX_LENGTH];
472                        vals[CLM]               = column ;
473                        vals[CODE]              = key ;
474                        vals[LNAME]             = longLabel[adrs] ;
475                        vals[SNAME]             = shortLabel[adrs] ;
476                        vals[CODELVL]   = codeLevel[adrs] ;
477                        vals[CODEGRP]   = codeGroup[adrs] ;
478                        vals[CODE_PARAM]= codeParam[adrs] ;
479                        vals[ROLES]             = roles[adrs] ;
480                        vals[SYSTEM_ID] = null ;
481                        vals[KBSAKU]    = null ;
482                        vals[RSNAME]    = rawShortLabel[adrs] ;
483                        vals[RLNAME]    = rawLongLabel[adrs] ;  // 5.6.8.2 (2013/09/20)
484                        vals[DESCRIPT]  = description[adrs] ;   // 6.2.0.0 (2015/02/27)
485
486                        data.put( key,vals );
487                }
488
489                return new CodeData( column,data,useFlag );
490        }
491
492        /**
493         * 指定のgroupに所属する限定された CodeData を構築して返します。
494         * このサブセットは、コードグループのCSV文字列に指定に基づいて作成されます。
495         *
496         * この CodeData は、本当のサブセットではなく、プルダウンメニューなどの選択肢のリストを
497         * 制限します。これは、一覧表示(レンデラー)では、すべての既存の設定値を表示しておく
498         * 必要があるからです。そして、変更時(エディター)に、選択肢を制限します。
499         *
500         * 引数の group が、null,ゼロ文字列、または、内部でグループを使用していない場合は、
501         * 自分自身を返します。(同一です)
502         * 引数の group も、内部設定のグループも、CSV形式CSV で複数のグループを指定できます。
503         * この場合は、各グループのうち、どれか一つでも該当すれば、使用(true)になります。
504         *
505         * @og.rev 5.1.9.0 (2010/08/01) 新規追加
506         * @og.rev 5.6.8.0 (2013/09/20) rawLongLabel対応
507         * @og.rev 6.2.0.0 (2015/02/27) description 概要説明 追加
508         *
509         * @param       group   指定のコードグループのCSV文字列
510         *
511         * @return 指定のgroupに所属する限定された CodeData
512         * @og.rtnNotNull
513         */
514        public CodeData subsetGroup( final String group ) {
515                if( group == null || group.isEmpty() || !isUseGroup ) {
516                        return this;
517                }
518
519                final String[] keys = group.split( "," ) ;
520
521                boolean[] useFlag = new boolean[size] ;
522
523                final Map<String,String[]> data = new LinkedHashMap<>();
524                for( int adrs=0; adrs<size; adrs++ ) {
525                        final String cdGrp = codeGroup[adrs];
526
527                        boolean flag = SPC.equals( cdGrp );
528                        if( !flag ) {
529                                final String grpCsv = "," + cdGrp + "," ;
530                                for( int i=0; i<keys.length; i++ ) {
531                                        flag = grpCsv.indexOf( keys[i] ) >= 0 ;
532                                        if( flag ) { break; }
533                                }
534                        }
535
536                        useFlag[adrs] = flag;
537
538                        String[] vals = new String[MAX_LENGTH];
539                        vals[CLM]               = column ;
540                        vals[CODE]              = code[adrs] ;
541                        vals[LNAME]             = longLabel[adrs] ;
542                        vals[SNAME]             = shortLabel[adrs] ;
543                        vals[CODELVL]   = codeLevel[adrs] ;
544                        vals[CODEGRP]   = codeGroup[adrs] ;
545                        vals[CODE_PARAM]= codeParam[adrs] ;
546                        vals[ROLES]             = roles[adrs] ;
547                        vals[SYSTEM_ID] = null ;
548                        vals[KBSAKU]    = null ;
549                        vals[RSNAME]    = rawShortLabel[adrs] ;
550                        vals[RLNAME]    = rawLongLabel[adrs] ;  // 5.6.8.0 (2013/09/20)
551                        vals[DESCRIPT]  = description[adrs] ;   // 6.2.0.0 (2015/02/27)
552
553                        data.put( code[adrs],vals );
554                }
555
556                return new CodeData( column,data,useFlag );
557        }
558
559        /**
560         * 指定のコードに限定された CodeData を構築して返します。
561         * このサブセットは、ロールの指定に基づいて作成されます。
562         *
563         * この CodeData は、本当のサブセットではなく、プルダウンメニューなどの選択肢のリストを
564         * 制限します。これは、一覧表示(レンデラー)では、すべての既存の設定値を表示しておく
565         * 必要があるからです。そして、変更時(エディター)に、選択肢を制限します。
566         *
567         * 引数の role が、null または、内部でロールを使用していない場合は、自分自身を返します。(同一です)
568         *
569         * @og.rev 5.1.9.0 (2010/08/01) 新規追加
570         * @og.rev 5.6.8.2 (2013/09/13) rawLongLabel対応
571         * @og.rev 6.2.0.0 (2015/02/27) description 概要説明 追加
572         *
573         * @param       userRole        指定のロール(ユーザーロール)
574         *
575         * @return 指定のコードに限定された CodeData
576         * @og.rtnNotNull
577         */
578        public CodeData subsetRole( final RoleMode userRole ) {
579                if( userRole == null || !isUseRoleMode ) {
580                        return this;
581                }
582
583                boolean[] useFlag = new boolean[size] ;
584
585                final Map<String,String[]> data = new LinkedHashMap<>();
586                for( int adrs=0; adrs<size; adrs++ ) {
587                        final byte rw = userRole.getAccessBitMode( roleModes[adrs] );
588
589                        useFlag[adrs] = RoleMode.isWrite( rw ) ;        // 書き込み可能な場合のみ、true
590
591                        String[] vals = new String[MAX_LENGTH];
592                        vals[CLM]               = column ;
593                        vals[CODE]              = code[adrs] ;
594                        vals[LNAME]             = longLabel[adrs] ;
595                        vals[SNAME]             = shortLabel[adrs] ;
596                        vals[CODELVL]   = codeLevel[adrs] ;
597                        vals[CODEGRP]   = codeGroup[adrs] ;
598                        vals[CODE_PARAM]= codeParam[adrs] ;
599                        vals[ROLES]             = roles[adrs] ;
600                        vals[SYSTEM_ID] = null ;
601                        vals[KBSAKU]    = null ;
602                        vals[RSNAME]    = rawShortLabel[adrs] ;
603                        vals[RLNAME]    = rawLongLabel[adrs] ;
604                        vals[DESCRIPT]  = description[adrs] ;   // 6.2.0.0 (2015/02/27)
605
606                        data.put( code[adrs],vals );
607                }
608
609                return new CodeData( column,data,useFlag );
610        }
611
612        /**
613         * オブジェクトの識別子として,詳細なコード情報を返します。
614         *
615         * @og.rev 4.1.0.0 (2008/01/18) メソッド修正(改行コード削除)
616         *
617         * @return  詳細なコード情報
618         * @og.rtnNotNull
619         */
620        @Override
621        public String toString() {
622                return "column = " + toCodeString() ;
623        }
624}