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