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.HashMap; 019import java.util.Locale; 020import java.util.Map; 021 022import org.opengion.fukurou.db.DBUtil; 023import org.opengion.fukurou.util.ApplicationInfo; 024import org.opengion.fukurou.util.StringUtil; 025import org.opengion.hayabusa.common.HybsSystem; 026 027/** 028 * データロールは、データへのアクセス権限を管理するクラスです。 029 * 030 * データロール情報は、データロールマスタ(GEA06)で管理されます。 031 * 032 * あるユーザーのデータロール情報に対してひもつくデータロールマスタの 033 * カラム、条件値、条件式の一覧に対して、カラム単位に条件式を構築します。 034 * 035 * このクラスでは、インスタンス作成時にデータロールマスタのDBを直接検索しています。 036 * このため、データ変更時の変更内容を次回ログイン時から反映させるため、 037 * 自身のオブジェクトキャッシュは保持していません。 038 * 039 * また、各条件式について、1つのカラムに対して複数の条件式が適用される場合、 040 * 条件式が"="または"LIKE"だけの場合は、"OR"結合されます。 041 * "!="及び"NOT LIKE"条件が1つでも含まれる場合は、"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 */ 070public 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 clm = null; 147 String cvalue =null; 148 String valcdtn = null; 149 for( int i=0; i<drole.length; i++ ) { 150 String[] args = new String[] { systemId, drole[i] }; 151 String[][] vals = DBUtil.dbExecute( QUERY_GEA06_SELECT,args,appInfo, DBID ); // 5.5.5.1 (2012/08/07) 152 for( int j=0; j<vals.length; j++ ) { 153 clm = vals[j][IDX_CLM]; 154 cvalue = vals[j][IDX_CVALUE]; 155 valcdtn = vals[j][IDX_VALCDTN]; 156 157 String cdtn = cdtnMap.get( clm ); 158 if( cdtn == null ) { cdtn = ""; } 159 else if( "=".equals( valcdtn ) || "LIKE".equalsIgnoreCase( valcdtn ) ) { 160 cdtn += " or "; 161 } 162 else { 163 cdtn += " and "; 164 } 165 cdtn += clm + " " + valcdtn + " '" + cvalue; 166 if( valcdtn.toUpperCase( Locale.JAPAN ).indexOf( "LIKE" ) >= 0 ) { 167 cdtn += "%"; 168 } 169 cdtn += "'"; 170 171 if( cdtn.indexOf( " and " ) >= 0 ) { cdtn = cdtn.replace( " or ", "and" ); } 172 173 cdtnMap.put( clm, cdtn ); 174 } 175 } 176 } 177 178 /** 179 * ロール文字列から、データロールマスタ(GEA05)を検索し、カラム単位の 180 * 条件式を生成します。 181 * 182 * @param droles "|"で区切られた データロール文字列 183 * @param systemId システムID 184 * @param appInfo 接続情報 185 * 186 * @return データロールオブジェクト 187 */ 188 public static DataRole newInstance( final String droles, final String systemId, final ApplicationInfo appInfo ) { 189 if( droles == null || droles.length() == 0 ) { 190 return FULL_ACCESS_DATAROLE_OBJ; 191 } 192 else if( FULL_DENY_DROLES_KEY.equals( droles ) ) { 193 return FULL_DENY_DATAROLE_OBJ; 194 } 195 196 return new DataRole( droles, systemId, appInfo ); 197 } 198 199 /** 200 * ロールズを返します。 201 * 202 * @return ロールズ文字列 203 */ 204 public String getDataRoles() { return droles; } 205 206 /** 207 * ロールズを返します。 208 * 209 * @og.rev 4.4.0.1 (2009/08/08) テーブルIDが付加されている場合の条件を追加 210 * 211 * @param clm カラム名 212 * 213 * @return ロールズ文字列 214 */ 215 public String getCondition( final String clm ) { 216 if( isFullAcess ) { return FULL_ACCESS_CONDITION; } 217 if( isFullDeny ) { return "(" + clm + FULL_DENY_CONDITION + ")"; } 218 219 String rtn = null; 220 if( clm.indexOf( '.' ) >= 0 ) { 221 String clmTmp = clm.substring( clm.lastIndexOf( '.' ) + 1 ); 222 rtn = cdtnMap.get( clmTmp ); 223 if( rtn == null || rtn.length() == 0 ) { 224 return "(" + clm + FULL_DENY_CONDITION + ")"; 225 } 226 return "(" + rtn.replace( clmTmp, clm ) + ")"; 227 } 228 else { 229 rtn = cdtnMap.get( clm ); 230 if( rtn == null || rtn.length() == 0 ) { 231 return "(" + clm + FULL_DENY_CONDITION + ")"; 232 } 233 return "(" + rtn + ")"; 234 } 235 } 236 237 /** オブジェクトの識別子として,詳細なユーザー情報を返します。 238 * 239 * @return 詳細な画面情報 240 */ 241 @Override 242 public String toString() { 243 StringBuilder rtn = new StringBuilder( HybsSystem.BUFFER_MIDDLE ); 244 rtn.append( "droles : " ).append( droles ).append( HybsSystem.CR ); 245 return rtn.toString(); 246 } 247}