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.util.Map;
019import java.util.WeakHashMap ;
020import java.util.Collections ;
021
022import org.opengion.hayabusa.common.HybsSystem;
023import org.opengion.hayabusa.common.HybsSystemException;
024import org.opengion.fukurou.system.LogWriter;                                                   // 8.4.0.0 (2023/01/30)
025import org.opengion.fukurou.util.StringUtil;
026import static org.opengion.fukurou.system.HybsConst.CR ;                                // 6.1.0.0 (2014/12/26)
027import static org.opengion.fukurou.system.HybsConst.BUFFER_MIDDLE;              // 6.1.0.0 (2014/12/26) refactoring
028
029/**
030 * ロールモードは、画面オブジェクトやカラムオブジェクトのロール-モード制御の情報を
031 * 管理するクラスです。
032 * ROLES 情報は、AAA|BBB|CCC と 『|』で区切られた複数のロールを持っています。
033 * 通常、ユーザーロールは画面やカラムの各オブジェクトに対してロール制御可能です。
034 * ログインユーザーは、自分自身のロールを、画面やカラムが持っているかを判定します。
035 * 画面に関しては、従来のデフォルトアクセスがなくなり、ロールを登録する場合は、
036 * 必ず ユーザーロールとの比較が行われます。画面ロールを登録しない場合は、アクセス
037 * 可能と判断されます。つまり、画面の場合は、なにも設定しなければ、アクセス可能と
038 * 判断されます。
039 * カラムロールも同様に、何も設定しなければフルアクセスできます。通常、ほとんどの
040 * ケースでカラムロールが使われることはありません。
041 * RWMODE 情報は、各ロールに対して、3つの項目で表しています。
042 *   1:"-" メニュー非表示   "m" メニュー表示  "p" メニュー表示(強制プルダウン表示)
043 *   2:"-" アクセス拒否     "r" 読取許可      "w" 読取、書込許可
044 *   3:"-" 未対応           "d" ファイル出力  "u" ファイル入力  "f" ファイル入出力
045 *       uではエディットメニューそのものが、d,fでは【表示項目設定】タブは表示されません。
046 *       "o" 表示順編集のみ可  … この設定では、【表示項目設定】 タブで位置と表示順のみ変更できます。
047 *       "e" 画面編集可        … この設定で、編集機能がフルに使えます。
048 *       互換性の関係より、"" は、"e"  と同等とします。
049 *       設定キーの関係より、"o" か "e" を設定すると、"f" と同じ権限が自動的に設定されます。
050 *
051 * この3項目を順次つないで、"--","-r","-w","mr","mw" などの設定を行います。
052 * モードが設定されている場合は、共通モードとして、すべてのロールに同じモードを
053 * 割り当てます。個別に割り当てる場合は、ROLES 情報の後ろに () 付きで追記します。
054 * 例えば、AAA|BBB(-r)|CCC とすれば、BBB ロールの場合は、読取専用になります。
055 * ロールをぶつける場合は、AND 演算になります。
056 * 過去(Ver3)のモードとの互換性をとる場合、"rw" は "mw" へ、"r-" は"mr" へ変換
057 * してください。
058 *
059 * @og.rev 4.0.0.0 (2004/01/31) 新規作成
060 * @og.rev 4.3.3.0 (2008/10/01) pモード追加
061 * @og.group リソース管理
062 *
063 * @version  4.0
064 * @author   Kazuhiko Hasegawa
065 * @since    JDK5.0,
066 */
067public final class RoleMode {
068        /** 6.4.3.1 (2016/02/12) Collections.synchronizedMap で同期処理を行います。 */
069        private static final Map<String,RoleMode> ROLE_MAP = Collections.synchronizedMap( new WeakHashMap<>( BUFFER_MIDDLE ) ); // 6.4.1.1 (2016/01/16) roleMap → ROLE_MAP  refactoring
070
071        // 5.5.5.2 (2012/08/10) oを追加するため、ビット表現を拡張
072        // 5.7.4.3 (2014/03/28) publicをprivateに変更します。
073        /** MODE 定義 全許可                         ( mwe ) */
074        private static final byte FULL_MODE = (byte)0x7f;       // mwe = 01 11 11 11 = 0x7f
075        /** MODE 定義 メニュー表示                      ( m-- ) */
076        private static final byte M_MODE    = (byte)0xc0;       // m-- = 11 00 00 00 = 0xc0
077        /** MODE 定義 強制プルダウン表示   ( p-- ) */
078        private static final byte P_MODE    = (byte)0x40;       // p-- = 01 00 00 00 = 0x40
079
080        /** MODE 定義 読取許可                                ( -r- ) */
081        private static final byte R_MODE    = (byte)0x10;       // -r- = 00 01 00 00 = 0x10
082        /** MODE 定義 書込許可                                ( -w- ) */
083        private static final byte W_MODE    = (byte)0x30;       // -w- = 00 11 00 00 = 0x30
084
085        /** MODE 定義 ファイル出力                      ( --d ) */
086        private static final byte D_MODE    = (byte)0x04;       // --d = 00 00 01 00 = 0x04
087        /** MODE 定義 ファイル入力                      ( --u ) */
088        private static final byte U_MODE    = (byte)0x08;       // --u = 00 00 10 00 = 0x08
089        /** MODE 定義 ファイル入出力             ( --f ) */
090        private static final byte F_MODE    = (byte)0x0c;       // --f = 00 00 11 00 = 0x0c
091
092        /** MODE 定義 表示順編集のみ可            ( --o ) */
093        private static final byte O_MODE    = (byte)0x0e;       // --o = 00 00 11 10 = 0x0e
094                                                                                                                //                ~   ←【出力方法設定】タブの表示
095                                                                                                                //                 ~  ←【表示項目設定】タブの表示順使用
096        /** MODE 定義 画面編集可                       ( --e ) */
097        private static final byte E_MODE    = (byte)0x0f;       // --e = 00 00 11 11 = 0x0f
098
099        /** 初期のモード */
100        public static final String DEFAULT_MODE = "mwe";
101
102        private final String    roles ;                 // ロールズ
103        private final String    rwmode ;                // モード
104        private final String[]  roleArray ;             // ロール配列
105        private final byte[]    bitModes ;              // モードのビット版(-:00, p:01, m:11,
106                                                                                        //                                      -:00, r:01, w:11,
107                                                                                        //                                      -:000, d:010, u:100, f:110, o:111, e:111)
108        private final boolean   fullAccessFlag; // フルアクセス許可時のフラグ
109
110        private final String    modeErrMsg ;    // 8.4.0.0 (2023/01/31) RoleMode でthrow しても、インスタンスは生成する。その時のエラーメッセージ
111
112        private static final RoleMode FULL_ACCESS_ROLE_MODE_OBJ = new RoleMode() ;
113
114        /**
115         * フルアクセスの RoleMode を構築します。
116         *
117         * デフォルトコンストラクターをprivateにして、
118         * オブジェクトの生成をさせないようにする。
119         *
120         * @og.rev 4.3.0.0 (2008/07/04) ロールモードマルチ対応
121         * @og.rev 8.4.0.0 (2023/01/31) RoleMode でthrow しても、インスタンスは生成する。
122         */
123        private RoleMode() {
124                roles                   = "FullAccess";
125                rwmode                  = DEFAULT_MODE;
126                roleArray               = null;
127                bitModes                = new byte[] { FULL_MODE };             // mwf = 01111111 = 0x7f
128                fullAccessFlag  = true;
129                modeErrMsg              = null;                                 // 8.4.0.0 (2023/01/31)
130        }
131
132        /**
133         * ロールとモードを元に、RoleModeオブジェクトを構築します。
134         * このコンストラクタは、他のパッケージから呼び出せないように、
135         * パッケージプライベートにしておきます。
136         *
137         * @og.rev 4.3.0.0 (2008/07/04) ロールモードマルチ対応
138         * @og.rev 6.2.2.3 (2015/04/10) fullAccessロール指定に、モードのみ指定機能を追加
139         * @og.rev 8.4.0.0 (2023/01/31) RoleMode でthrow しても、インスタンスは生成する。
140         *
141         * @param       roles   "|"で区切られた ロール文字列
142         * @param       mode    "|"で区切られ、ロール文字列と対応付けられたモード文字列。唯一の場合は共通モードになる。
143         * @param       errMsg  オブジェクト生成段階で発生したエラーメッセージ(正常時は null をセットする)
144         */
145//      private RoleMode( final String roles,final String mode ) {
146        private RoleMode( final String roles,final String mode,final String errMsg ) {
147                this.roles      = roles ;               // ロールズ
148                this.rwmode     = mode ;                // モード
149
150                // roles="root" または、roleArray がない場合は、フルアクセス
151                // 6.2.2.3 (2015/04/10) fullAccessロール指定に、モードのみ指定機能を追加
152                fullAccessFlag = "root".equals( roles ) || roles == null || roles.isEmpty() || roles.charAt(0) == '(' ;
153
154                roleArray = StringUtil.csv2Array( roles,HybsSystem.GUI_DELIMITER ) ;    // ロール配列
155
156                // bitModes を求めます。最低1つは作成します。同時に、roleArray もセットします。
157                // 8.4.0.0 (2023/01/31) RoleMode でthrow しても、インスタンスは生成する。
158        //      bitModes = makeBitMode( roleArray,rwmode );
159                String tempMsg = errMsg ;
160                byte[] tempBit = null ;
161                try {
162                        tempBit = makeBitMode( roleArray,rwmode );
163                }
164                catch( final Throwable th ) {
165                        tempMsg = th.getMessage();
166                        tempBit = new byte[] { FULL_MODE } ;
167                }
168                bitModes   = tempBit;
169                modeErrMsg = tempMsg;
170
171                if( modeErrMsg != null ) {
172                        LogWriter.log( modeErrMsg );                                                    // 8.4.0.0 (2023/01/30)
173                        System.err.println( modeErrMsg );
174                }
175        }
176
177        /**
178         * ロールとモードを元に、RoleModeオブジェクトを構築します。
179         * 条件が同じ RoleModeオブジェクト があれば、キャッシュから返します。
180         * キャッシュになければ、新規に作成します。
181         * このキャッシュは、完全な内部キャッシュなので、いつクリアされるか保障がありません。
182         *
183         * @og.rev 4.3.0.0 (2008/07/04) ロールモードマルチ対応
184         *
185         * @param       roles   "|"で区切られた ロール文字列
186         *
187         * @return      RoleModeオブジェクト
188         * @og.rtnNotNull
189         */
190        public static RoleMode newInstance( final String roles ) {
191                // 6.4.1.1 (2016/01/16) PMD refactoring. A method should have only one exit point, and that should be the last statement in the method
192                return roles == null || roles.isEmpty() ? FULL_ACCESS_ROLE_MODE_OBJ : newInstance( roles,DEFAULT_MODE );
193        }
194
195        /**
196         * ロールとモードを元に、RoleModeオブジェクトを構築します。
197         * 条件が同じ RoleModeオブジェクト があれば、キャッシュから返します。
198         * キャッシュになければ、新規に作成します。
199         * このキャッシュは、完全な内部キャッシュなので、いつクリアされるか保障がありません。
200         *
201         * @og.rev 4.3.0.0 (2008/07/04) ロールモードマルチ対応
202         * @og.rev 6.4.3.3 (2016/03/04) Map#computeIfAbsent で対応する。
203         * @og.rev 8.4.0.0 (2023/01/31) RoleMode でthrow しても、インスタンスは生成する。
204         *
205         * @param       roles   "|"で区切られた ロール文字列
206         * @param       mode    "|"で区切られ、ロール文字列と対応付けられたモード文字列。唯一の場合は共通モードになる。
207         *
208         * @return      RoleModeオブジェクト
209         * @og.rtnNotNull
210         */
211        public static RoleMode newInstance( final String roles,final String mode ) {
212                // 8.5.5.1 (2024/02/29) FULL_ACCESS判定を先に持ってきます。
213                if( ( roles == null || roles.isEmpty() ) && ( "mw".equals( mode ) || DEFAULT_MODE.equals( mode ) ) ) {
214                        return FULL_ACCESS_ROLE_MODE_OBJ ;
215                }
216
217                if( mode == null || mode.length() < 2 ) {
218                        final String errMsg = "RWMODE の桁数は、2桁以上必要です。"
219                                                + " roles [" + roles + "]  mode [" + mode + "]"
220                                                + CR;
221        //              throw new HybsSystemException( errMsg );
222                        return new RoleMode( roles,DEFAULT_MODE,errMsg );
223                }
224
225//              if( ( roles == null || roles.isEmpty() ) &&
226//                      ( "mw".equals( mode ) || DEFAULT_MODE.equals( mode ) ) ) {
227//                              return FULL_ACCESS_ROLE_MODE_OBJ ;
228//              }
229
230                final String key = roles + mode ;
231                // Map#computeIfAbsent : 戻り値は、既存の、または計算された値。追加有り、置換なし、削除なし
232//              return ROLE_MAP.computeIfAbsent( key, k -> new RoleMode( roles,mode ) );
233                return ROLE_MAP.computeIfAbsent( key, k -> new RoleMode( roles,mode,null ) );   // 正常登録
234        }
235
236        /**
237         * ロールズを返します。
238         *
239         * @return ロールズ文字列
240         */
241        public String getRoles() { return roles; }
242
243        /**
244         * モード配列を返します。
245         *
246         * @return モード配列
247         */
248        public String getMode() { return rwmode; }
249
250        /**
251         * 指定のユーザーロールに対する最終的なアクセス条件を取得します。
252         * アクセス条件は、複数あるユーザーロールの中で、最大のアクセス条件を算出します。
253         * 例えば、AAA(-r)|BBB(-w)|CCC(mr) の3つのロール/モードが設定されている場合、
254         * ユーザーが、AAA だけの場合は、-r ですが、AAA|BBB を持っている場合は、-w になります。
255         * さらに、BBB|CCC と持っている場合は、(-w:書き込み許可)と(mr:メニューから読取許可)の
256         * 権限により、mw:メニューからの書き込み許可が与えられます。
257         * モード指定がある場合は、AND演算になります。
258         * 例えば、AAA(-r)|BBB(-w)|CCC(mr) と BBB|CCC(-r) の場合、(-r)+(-w)+(mr)*(-r)=-w に
259         * なります。ロールは、OR ですが、モードは、同一ロールでのAND になります。
260         * 実際には、メニュー表示の可否は、ポップアップ系によく用いられますので、上記のような
261         * 許可が実際にあるかどうかは不明ですが、すべてのモードのOR条件での結合になります。
262         *
263         * @og.rev 4.3.0.0 (2008/07/04) ロールモードマルチ対応
264         *
265         * @param       other   ロールモード
266         *
267         * @return アクセスビット
268         */
269        public byte getAccessBitMode( final RoleMode other ) {
270                if( fullAccessFlag || other.fullAccessFlag ) {
271                        return (byte)(bitModes[0] & other.bitModes[0]) ;
272                }
273
274                final String[] othRoleArray = other.roleArray ;         // ロール配列
275                final byte[]     othBitModes  = other.bitModes ;                // モードのビット
276
277                byte bitMode = 0;
278                for( int i=0; i<roleArray.length; i++ ) {
279                        for( int j=0; j<othRoleArray.length; j++ ) {
280                                if( roleArray[i].equals( othRoleArray[j] ) ) {
281                                        bitMode |= (byte)(bitModes[i] & othBitModes[j]) ;
282                                        if( bitMode == FULL_MODE ) { return FULL_MODE; }        // 途中打ち切り
283                                }
284                        }
285                }
286
287                return bitMode;
288        }
289
290        /**
291         * RoleMode 構築時に発生したエラーメッセージを返します。
292         * エラーがない場合は、null を返します。
293         *
294         * @og.rev 8.4.0.0 (2023/01/31) RoleMode でthrow しても、インスタンスは生成する。
295         *
296         * @return エラーメッセージ(正常時は、null)
297         */
298        public String getModeErrMsg() { return modeErrMsg; }
299
300        /**
301         * ビットロールのメニュー表示可否を返します。
302         *
303         * ロールが、m## , p## の場合に、true になります。
304         * これは、メニューに表示されるかどうかの判定に使われます。
305         *
306         * @param       bitMode ビットロール
307         *
308         * @return メニュー表示できる(true)/出来ない(false)
309         */
310        public static boolean isMenu( final byte bitMode ) {
311                return (bitMode & M_MODE) != 0 ;                // 6.0.2.4 (2014/10/17) findbugs (ビット演算の符号をチェック)
312        }
313
314        /**
315         * ビットロールのプルダウン化を返します。
316         *
317         * ロールが、p## の場合に、true になります。
318         * ボタンメニュー時でも強制的に従来のプルダウンにします。
319         * 今後は廃止の方向です。
320         *
321         * @og.rev 4.3.3.0 (2008/10/01) メソッド追加
322         * @param       bitMode ビットロール
323         *
324         * @return true:プルダウン化
325         */
326        public static boolean isPulldown( final byte bitMode ) {
327                // M_MODEとの比較でP_MODEの場合は強制プルダウン化
328                return (bitMode & M_MODE) == P_MODE ;
329        }
330
331        /**
332         * ビットロールの読込アクセス可否を返します。
333         *
334         * ロールが、#r# , #w# の場合に、true になります。
335         * 読み取り属性がある場合、画面が利用可能になります。
336         * #-# の場合は、画面へのアクセスができないため、
337         * メニューアクセス許可を与える、m-# の設定は無意味です。
338         * この場合は、メニューにも表示されません。
339         *
340         * @param       bitMode ビットロール
341         *
342         * @return 読込アクセスできる(true)/出来ない(false)
343         */
344        public static boolean isRead( final byte bitMode ) {
345                return (bitMode & R_MODE) != 0 ;                // 6.0.2.4 (2014/10/17) findbugs (ビット演算の符号をチェック)
346        }
347
348        /**
349         * ビットロールの書込アクセス可否を返します。
350         *
351         * ロールが、#w# の場合に、true になります。
352         *
353         * これは、読込、書込みの判断ではなく、書込みができるか
354         * どうかの判断をしています。
355         * 画面にアクセスできるかどうかの判断は、isAccess を使用してください。
356         *
357         * @param       bitMode ビットロール
358         *
359         * @return 書込アクセスできる(true)/出来ない(false)
360         */
361        public static boolean isWrite( final byte bitMode ) {
362                // 注意:W_MODE は、R_MODE と合成されているので、> 0 で判断できない。
363                return (bitMode & W_MODE) == W_MODE ;
364        }
365
366        /**
367         * ビットロールの画面アクセス可否を返します。
368         *
369         * これは、画面にアクセスできるかどうかの判断です。
370         * ロールが、#r# , #w# の場合に、true になります。
371         * 現時点では、isRead(byte) と計算方法は異なりますが、同じ結果になっています。
372         * これは、たまたま、現時点のロールの種類がそうなっているだけで、将来的に
373         * 同じかどうかは、保障されていません。
374         * よって、読み取り許可と、画面アクセス許可は、分けて考えてください。
375         *
376         * @param       bitMode ビットロール
377         *
378         * @return 画面アクセスできる(true)/出来ない(false)
379         */
380        public static boolean isAccess( final byte bitMode ) {
381                return (bitMode & W_MODE) != 0 ;                // 6.0.2.4 (2014/10/17) findbugs (ビット演算の符号をチェック)
382        }
383
384        /**
385         * ビットロールのファイル出力可否を返します。
386         *
387         * ロールが、##d , ##f , ##o , ##e(= ##) の場合に、true になります。
388         * ##u の場合に、false になります。
389         * ファイル出力の可否を判定します。
390         * ## は、互換性の関係で、##e と同じです。
391         *
392         * @param       bitMode ビットロール
393         *
394         * @return ファイル出力できる(true)/出来ない(false)
395         */
396        public static boolean isDownload( final byte bitMode ) {
397                return (bitMode & D_MODE) != 0 ;                // 6.0.2.4 (2014/10/17) findbugs (ビット演算の符号をチェック)
398        }
399
400        /**
401         * ビットロールのファイル入力可否を返します。
402         *
403         * ロールが、##u , ##f , ##o , ##e(= ##) の場合に、true になります。
404         * ##d の場合に、false になります。
405         * ファイル入力の可否を判定します。
406         * ## は、互換性の関係で、##e と同じです。
407         * ダウンロードはさせないが、アップロードを行う場合に使います。
408         * ここでのアップロードとは、基本的にデータの取り込みになりますので、
409         * アップロードのみという扱いは、あまりありません。
410         *
411         * @param       bitMode ビットロール
412         *
413         * @return ファイル入力できる(true)/出来ない(false)
414         */
415        public static boolean isUpload( final byte bitMode ) {
416                return (bitMode & U_MODE) != 0 ;                // 6.0.2.4 (2014/10/17) findbugs (ビット演算の符号をチェック)
417        }
418
419        /**
420         * ビットロールの画面編集可否を返します。
421         *
422         * ロールが、##o , ##e(= ##) の場合に、true になります。
423         * このビットロールだけ特殊で、フラグが ON の場合に、機能制限がかかります。
424         *
425         * @og.rev 5.4.2.0 (2011/12/01) 新規作成
426         * @og.rev 5.5.5.2 (2012/08/10) oモード追加に伴い変更
427         *
428         * @param       bitMode ビットロール
429         *
430         * @return アクセスできる(true)/出来ない(false)
431         */
432        public static boolean isEdit( final byte bitMode ) {
433                // return ( (bitMode & E_MODE) == E_MODE );
434                return (bitMode & O_MODE) == O_MODE ;
435        }
436
437        /**
438         * ビットロールの画面編集のフルコントロール可否を返します。
439         *
440         * ロールが、##e(= ##) の場合に、true になります。
441         * これは、フルコントロールの状態を指します。
442         *
443         * @og.rev 5.5.5.2 (2012/08/10) 新規作成
444         *
445         * @param       bitMode ビットロール
446         *
447         * @return アクセスできる(true)/出来ない(false)
448         */
449        public static boolean isFullEdit( final byte bitMode ) {
450                // return ( (bitMode & E_MODE) == E_MODE );
451                return (bitMode & E_MODE) == E_MODE ;
452        }
453
454        /**
455         * この画面のmode アクセス条件をビット化します。
456         *
457         * RWMODE 情報は、各ロールに対して、3つの項目で表しています。
458         *   1:"-" メニュー非表示   "m" メニュー表示  "p" メニュー表示(強制プルダウン表示)
459         *   2:"-" アクセス拒否     "r" 読取許可      "w" 読取、書込許可
460         *   3:"-" 未対応           "d" ファイル出力  "u" ファイル入力  "f" ファイル入出力
461         *       … このd,u,f では、【出力方法設定】タブは表示されません。
462         *       "o" 表示順編集のみ可  … この設定では、【表示項目設定】 タブで位置と表示順のみ変更できます。
463         *       "e" 画面編集可        … この設定で、編集機能がフルに使えます。
464         *       互換性の関係より、"" は、"e"  と同等とします。
465         *
466         * 区切り文字『|』で同じ順序で指定します。
467         * roles がないか、modes が一つか、roles と modes の個数が異なる場合
468         * 唯一のモード(共通モード)として、modes[0] を割り当てます。
469         * 互換性のため、"rw" と "r-" も処理できるようにします。
470         * この3項目を順次つないで、"--","-r","-w","mr","mw" などの設定を行います。
471         * モードが設定されている場合は、共通モードとして、すべてのロールに同じモードを
472         * 割り当てます。個別に割り当てる場合は、ROLES 情報の後ろに () 付きで追記します。
473         * 例えば、AAA|BBB(-r)|CCC とすれば、BBB ロールの場合は、読取専用になります。
474         * ロールをぶつける場合は、AND 演算になります。
475         *
476         * @og.rev 4.3.0.0 (2008/07/04) ロールモードマルチ対応
477         *
478         * @param       roles   画面ロール配列
479         * @param       mode    画面モード
480         *
481         * @return  ビットモード配列 "--:000","-r:001","-w:010","mr:101","mw:110" に対応した数字(0,1,2,5,6)
482         */
483        private byte[] makeBitMode( final String[] roles,final String mode ) {
484                byte[] bits ;                                                           // 6.3.9.1 (2015/11/27) Found 'DD'-anomaly for variable 'bits'(PMD)
485
486                final byte commnMode = bitMode( mode );         // 共通MODEの設定
487
488                final int size = roles.length ;
489                if( size == 0 ) {
490                        bits = new byte[] { commnMode };
491                }
492                else {
493                        bits = new byte[size] ;
494                        for( int i=0; i<size; i++ ) {
495                                String roleMode = null;
496                                final String role = roles[i];
497                                // 6.4.1.1 (2016/01/16) PMD refactoring. Avoid if (x != y) ..; else ..;
498                                final int adrs = role == null ? -1 : role.indexOf( '(' ) ;
499                                if( adrs >= 0 ) {
500                                        roleMode = role.substring( adrs+1,role.length() -1 );
501                                        // 注意:roleArray に書き戻しています。(副作用処理)
502                                        roles[i] = role.substring( 0,adrs );
503                                }
504                                bits[i] = (byte)(commnMode & bitMode( roleMode )) ;
505                        }
506                }
507
508                return bits ;
509        }
510
511        /**
512         * モード文字列に対するビット変換を行います。
513         *
514         * RWMODE 情報は、3つの項目で表しています。
515         *   1:"-" メニュー非表示   "m" メニュー表示
516         *   2:"-" アクセス拒否     "r" 読取許可      "w" 読取、書込許可
517         *   3:"-" 未対応           "d" ファイル出力  "u" ファイル入力  "f" ファイル入出力
518         *       … このd,u,f では、【出力方法設定】タブは表示されません。
519         *       "o" 表示順編集のみ可  … この設定では、【表示項目設定】 タブで位置と表示順のみ変更できます。
520         *       "e" 画面編集可        … この設定で、編集機能がフルに使えます。
521         *       互換性の関係より、"" は、"e"  と同等とします。
522         *
523         * それぞれのキーワードに対して、ビット制御を行います。
524         * このメソッドには、ロールモード(ロール単位に追加するモード)の判定も
525         * 行う事が出来るように、引数が null の場合は、FULL_MODE を返します。
526         *
527         *       全許可                                    ( mwe )  FULL_MODE
528         *       メニュー表示                 ( m-- )  M_MODE
529         *       強制プルダウン表示              ( p-- )  P_MODE
530         *       読取許可                           ( -r- )  R_MODE
531         *       書込許可                           ( -w- )  W_MODE
532         *       ファイル出力                 ( --d )  D_MODE
533         *       ファイル入力                 ( --u )  U_MODE
534         *       ファイル入出力                        ( --f )  F_MODE
535         *       表示順編集のみ可               ( --o )  O_MODE
536         *       画面編集可                          ( --e )  E_MODE
537         *
538         * @og.rev 4.3.0.0 (2008/07/04) ロールモードマルチ対応
539         * @og.rev 4.3.3.0 (2008/10/01) pモード対応(mと同じ扱い)
540         * @og.rev 5.4.2.0 (2011/12/01) eモード対応
541         * @og.rev 5.5.5.2 (2012/08/10) oモード対応
542         * @og.rev 8.5.5.1 (2024/02/29) switch文にアロー構文を使用
543         *
544         * @param       mode    モード文字列
545         *
546         * @return      ビットモード
547         */
548        private byte bitMode( final String mode ) {
549                byte bit = 0x00;
550
551                if( mode == null ) {
552                        bit = FULL_MODE;
553                }
554                else {
555                        final int len = mode.length();
556                        for( int i=0; i<len; i++ ) {
557                        // 8.5.5.1 (2024/02/29) switch文にアロー構文を使用
558//                      switch( mode.charAt(i) ) {
559//                                      case 'm' : bit |= M_MODE; break;
560//                                      case 'p' : bit |= P_MODE; break; // 4.3.3.0 (2008/10/01) Pモード追加
561//                                      case 'r' : bit |= R_MODE; break;
562//                                      case 'w' : bit |= W_MODE; break;
563//                                      case 'd' : bit |= D_MODE; break;
564//                                      case 'u' : bit |= U_MODE; break;
565//                                      case 'f' : bit |= F_MODE; break;
566//                                      case 'e' : bit |= E_MODE; break; // 5.4.2.0 (2011/12/01) Eモード追加
567//                                      case 'o' : bit |= O_MODE; break; // 5.5.5.2 (2011/12/10) Oモード追加
568//                                      case '-' : break;
569//                                      default  :
570//                                              final String errMsg = "RWMODE に不正な記号が使用されています。"
571//                                                                      + " mrwdufe- のみ、使用可能です。"
572//                                                                      + " roles [" + roles + "]  mode [" + mode + "]"
573//                                                                      + CR;
574//                                              throw new HybsSystemException( errMsg );
575//                              }
576//                      }
577                        switch( mode.charAt(i) ) {
578                                        case 'm' -> bit |= M_MODE;
579                                        case 'p' -> bit |= P_MODE;              // 4.3.3.0 (2008/10/01) Pモード追加
580                                        case 'r' -> bit |= R_MODE;
581                                        case 'w' -> bit |= W_MODE;
582                                        case 'd' -> bit |= D_MODE;
583                                        case 'u' -> bit |= U_MODE;
584                                        case 'f' -> bit |= F_MODE;
585                                        case 'e' -> bit |= E_MODE;              // 5.4.2.0 (2011/12/01) Eモード追加
586                                        case 'o' -> bit |= O_MODE;              // 5.5.5.2 (2011/12/10) Oモード追加
587                                        case '-' -> { /* 何もしない */ }
588                                        default  -> {
589                                                final String errMsg = "RWMODE に不正な記号が使用されています。"
590                                                                        + " mrwdufe- のみ、使用可能です。"
591                                                                        + " roles [" + roles + "]  mode [" + mode + "]"
592                                                                        + CR;
593                                                throw new HybsSystemException( errMsg );
594                                        }
595                                }
596                        }
597                        if( len < 3 ) { bit |= E_MODE; }        // 互換性暫定対応 // 5.4.2.0 (2011/12/01)
598
599                        // RWアクセスできない場合は、ファイルアクセスも禁止します。
600                        if( ( bit & W_MODE ) == 0 ) { bit = 0x00; }
601                }
602
603                return bit ;
604        }
605
606        /**
607         * オブジェクトの識別子として、詳細なユーザー情報を返します。
608         *
609         * @return  詳細な画面情報
610         * @og.rtnNotNull
611         */
612        @Override
613        public String toString() {
614                final StringBuilder rtn = new StringBuilder( BUFFER_MIDDLE )
615                        .append( "roles  : " ).append( roles  ).append( CR )
616                        .append( "rwmode : " ).append( rwmode ).append( CR );
617                return rtn.toString();
618        }
619}