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     */
016    package org.opengion.hayabusa.resource;
017    
018    import java.util.HashMap;
019    import java.util.Locale;
020    import java.util.Map;
021    
022    import org.opengion.fukurou.db.DBUtil;
023    import org.opengion.fukurou.util.ApplicationInfo;
024    import org.opengion.fukurou.util.StringUtil;
025    import org.opengion.hayabusa.common.HybsSystem;
026    
027    /**
028     * ãƒ??タロールは、データへのアクセス権限を管ç�?�™るクラスですã?
029     *
030     * ãƒ??タロールæƒ??は、データロールマスタ(GEA06)で管ç�?�•れますã?
031     *
032     * あるユーザーのãƒ??タロールæƒ??に対してひもつくデータロールマスタの
033     * カラãƒ??条件値、条件式ã?ä¸?¦§に対して、カラãƒ?�˜位に条件式を構築しますã?
034     *
035     * こã?クラスでは、インスタンス作æ?時にãƒ??タロールマスタのDBを直接検索してã�?�¾すã?
036     * こã?ため、データ変更時ã?変更å†?®¹を次回ログイン時から反æ˜?�•せるためã€?
037     * 自身のオブジェクトキャãƒ?‚·ュは保持してã�?�¾せんã€?
038     *
039     * またã?å�?�¡件式につã�?�¦ã€?つのカラãƒ?�«対してè¤?•°の条件式が適用されるå?合ã?
040     * 条件式が"="またã?"LIKE"ã�?�‘の場合ã?ã€?OR"結合されますã?
041     * "!="及ã?"NOT LIKE"条件ã�?つでも含まれる場合ã?ã€?AND"結合されますã?
042     *
043     * ãƒ??タロールがNULLの場合ã?全ãƒ??タへのアクセス可能となりã?条件式としてはã€?
044     *  "LIKE '%'" が付加されますã?
045     * またã?'--'の場合ã?全ãƒ??タへのアクセスが不可能となりã?条件式としてはã€?
046     *  "NOT LIKE '%'" が付加されますã?
047     * ユーザーのãƒ??タロールが指定されてã�?‚‹にも関わらずã?ãƒ??タロールの検索ができなã�?
048     * 場合ã?、å?禁止になりますã?
049     *
050     * 検索条件を取得する際に、テーブル名又は、テーブル名ã?別名がæŒ?®šされた場合ã?
051     * 条件の取得する際には、テーブル名ã?無視されますが、返される条件には、テーブルå�?
052     * は付加された状態になりますã?
053     *
054     * ä¾?
055     *  ABC(=)              BCD(=)          �(CLM = 'ABC' or CLM = 'BCD' )
056     *  ABC(=)              BCD(LIKE)       �(CLM = 'ABC' or CLM like 'BCD%' )
057     *  ABC(=)              BCD(!=)         �(CLM = 'ABC' and CLM != 'BCD' )
058     *  ABC(LIKE)   BCD(LIKE)       �(CLM like 'ABC%' or CLM like 'BCD%' )
059     *  ABC(LIKE)   BCD(!=)         �(CLM like 'ABC%' and CLM != 'BCD' )
060     *  ABC(LIKE)   BCD(!=)         �(CLM != 'ABC' and CLM != 'BCD' )
061     *  ABC(=)              BCD(=)          â‡?(A.CLM = 'ABC' or A.CLM = 'BCD' ) ※ {@SEC.A.CLM}でアクセス
062     *
063     * @og.rev 4.4.0.0 (2009/08/02) 新規作æ?
064     * @og.group リソース管ç�?
065     *
066     * @version  4.0
067     * @author   Hiroki Nakamura
068     * @since    JDK5.0,
069     */
070    public final class DataRole {
071            private static final String QUERY_GEA06_SELECT
072                                            = "select CLM, CVALUE, VALCDTN from GEA06"
073                                                    + " where SYSTEM_ID = ? and DROLE = ? and FGJ = '1'";
074    
075            private static final int IDX_CLM        = 0;
076            private static final int IDX_CVALUE     = 1;
077            private static final int IDX_VALCDTN= 2;
078    
079            private static final DataRole FULL_ACCESS_DATAROLE_OBJ = new DataRole( true ) ;
080            private static final DataRole FULL_DENY_DATAROLE_OBJ = new DataRole( false ) ;
081    
082            private static final String FULL_ACCESS_CONDITION = null ;
083            private static final String FULL_DENY_CONDITION = " NOT LIKE '%'" ;
084            private static final String FULL_DENY_DROLES_KEY = "--";
085    
086            private final Map<String,String> cdtnMap = new HashMap<String,String>( HybsSystem.BUFFER_SMALL );
087    
088            private final String                    droles ;                // ãƒ??タロールズ
089            private final String                    systemId ;              // シスãƒ?ƒ ID
090            private final ApplicationInfo   appInfo ;
091            private final String DBID = HybsSystem.sys( "RESOURCE_DBID" );          // 5.5.5.1 (2012/08/07) リソース系DBID 付け忘れ対å¿?
092    
093            private boolean         isFullAcess             = false;
094            private boolean         isFullDeny              = false;
095    
096            /**
097             * 固定データロール(全アクセス可 or 全アクセス不可)のインスタンスを生成しますã?
098             *
099             * @param isFull true:全アクセス可 false:全アクセス不可
100             */
101            private DataRole( final boolean isFull ) {
102                    droles = null;
103                    systemId = null;
104                    appInfo = null;
105    
106                    if( isFull )    { isFullAcess = true; }
107                    else                    { isFullDeny = true; }
108            }
109    
110            /**
111             * ロールæ–?­—å?から、データロールマスタ(GEA05)を検索しã?カラãƒ?�˜位ã?
112             * 条件式を生æ?しますã?
113             *
114             * @param droles "|"で区åˆ?‚‰れた ãƒ??タロールæ–?­—å?
115             * @param systemId シスãƒ?ƒ ID
116             * @param appInfo 接続情報
117             */
118            private DataRole( final String droles,final String systemId, final ApplicationInfo appInfo ) {
119                    this.droles = droles ;          // ãƒ??タロールズ
120                    this.systemId = systemId;       // シスãƒ?ƒ ID
121                    this.appInfo = appInfo ;
122    
123                    if( appInfo != null ) {
124                            appInfo.setModuleInfo( "DataRole",null,"CreateInstance" );
125                    }
126    
127                    String[] drole = StringUtil.csv2Array( droles, '|' );
128                    if( drole == null || drole.length == 0 ) {
129                            isFullAcess = true;
130                            return;
131                    }
132                    else {
133                            makeConditionMap( drole );
134                    }
135            }
136    
137            /**
138             * ロールæ–?­—å?から、データロールマスタ(GEA05)を検索しã?カラãƒ?�˜位ã?
139             * 条件式を生æ?しますã?
140             *
141             * @og.rev 5.5.5.1 (2012/08/07) リソース系DBID 付け忘れ対ç­?
142             *
143             * @param drole ãƒ??タロールæ–?­—å?の配å?
144             */
145            private void makeConditionMap( final String[] drole ) {
146    //              String[][] vals = null;
147                    String clm = null;
148                    String cvalue =null;
149                    String valcdtn = null;
150                    for( int i=0; i<drole.length; i++ ) {
151                            String[] args = new String[] { systemId, drole[i] };
152    //                      String[][] vals = DBUtil.dbExecute( QUERY_GEA06_SELECT,args,appInfo );
153                            String[][] vals = DBUtil.dbExecute( QUERY_GEA06_SELECT,args,appInfo, DBID );    // 5.5.5.1 (2012/08/07)
154                            for( int j=0; j<vals.length; j++ ) {
155                                    clm = vals[j][IDX_CLM];
156                                    cvalue = vals[j][IDX_CVALUE];
157                                    valcdtn = vals[j][IDX_VALCDTN];
158    
159                                    String cdtn = cdtnMap.get( clm );
160                                    if( cdtn == null ) { cdtn = ""; }
161                                    else if( "=".equals( valcdtn ) || "LIKE".equalsIgnoreCase( valcdtn ) ) {
162                                            cdtn += " or ";
163                                    }
164                                    else {
165                                            cdtn += " and ";
166                                    }
167                                    cdtn += clm + " " + valcdtn + " '" + cvalue;
168                                    if( valcdtn.toUpperCase( Locale.JAPAN ).indexOf( "LIKE" ) >= 0 ) {
169                                            cdtn += "%";
170                                    }
171                                    cdtn += "'";
172    
173                                    if( cdtn.indexOf( " and " ) >= 0 ) { cdtn = cdtn.replace( " or ", "and" ); }
174    
175                                    cdtnMap.put( clm, cdtn );
176                            }
177                    }
178            }
179    
180            /**
181             * ロールæ–?­—å?から、データロールマスタ(GEA05)を検索しã?カラãƒ?�˜位ã?
182             * 条件式を生æ?しますã?
183             *
184             * @param       droles  "|"で区åˆ?‚‰れた ãƒ??タロールæ–?­—å?
185             * @param systemId シスãƒ?ƒ ID
186             * @param appInfo 接続情報
187             *
188             * @return ãƒ??タロールオブジェクãƒ?
189             */
190            public static DataRole newInstance( final String droles, final String systemId, final ApplicationInfo appInfo ) {
191                    if( droles == null || droles.length() == 0 ) {
192                            return FULL_ACCESS_DATAROLE_OBJ;
193                    }
194                    else if( FULL_DENY_DROLES_KEY.equals( droles ) ) {
195                            return FULL_DENY_DATAROLE_OBJ;
196                    }
197    
198    //              DataRole dataRole = new DataRole( droles, systemId, appInfo );
199    //              return dataRole;
200                    return new DataRole( droles, systemId, appInfo );
201            }
202    
203            /**
204             * ロールズを返しますã?
205             *
206             * @return ロールズæ–?­—å?
207             */
208            public String getDataRoles() { return droles; }
209    
210            /**
211             * ロールズを返しますã?
212             *
213             * @og.rev 4.4.0.1 (2009/08/08) ãƒ??ブルIDが付加されてã�?‚‹場合ã?条件を追åŠ?
214             *
215             * @param clm カラãƒ?��
216             *
217             * @return ロールズæ–?­—å?
218             */
219            public String getCondition( final String clm ) {
220                    if( isFullAcess ) { return FULL_ACCESS_CONDITION; }
221                    if( isFullDeny ) { return "(" + clm + FULL_DENY_CONDITION + ")"; }
222    
223                    String rtn = null;
224                    if( clm.indexOf( '.' ) >= 0 ) {
225                            String clmTmp = clm.substring( clm.lastIndexOf( '.' ) + 1 );
226                            rtn = cdtnMap.get( clmTmp );
227                            if( rtn == null || rtn.length() == 0 ) {
228                                    return "(" + clm + FULL_DENY_CONDITION + ")";
229                            }
230                            return "(" + rtn.replace( clmTmp, clm ) + ")";
231                    }
232                    else {
233                            rtn = cdtnMap.get( clm );
234                            if( rtn == null || rtn.length() == 0 ) {
235                                    return "(" + clm + FULL_DENY_CONDITION + ")";
236                            }
237                            return "(" + rtn + ")";
238                    }
239            }
240    
241            /** オブジェクトã?識別子として?Œ詳細なユーザーæƒ??を返しますã?
242             *
243             * @return  詳細な画面æƒ??
244             */
245            @Override
246            public String toString() {
247                    StringBuilder rtn = new StringBuilder( HybsSystem.BUFFER_MIDDLE );
248                    rtn.append( "droles  : " ).append( droles ).append( HybsSystem.CR );
249                    return rtn.toString();
250            }
251    }