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
018//import java.text.MessageFormat;                                                                                               // 8.5.2.0 (2023/07/14) Delete
019//import java.util.List;                                                                                                                // 8.5.2.0 (2023/07/14) Delete
020//import java.util.Arrays;                                                                                                              // 6.4.7.0 (2016/06/03) 8.5.2.0 (2023/07/14) Delete
021
022import org.opengion.hayabusa.common.HybsSystem;
023import org.opengion.hayabusa.common.HybsSystemException;
024import org.opengion.hayabusa.common.SystemManager;
025import org.opengion.fukurou.system.LogWriter;
026import org.opengion.fukurou.util.Cleanable;
027import org.opengion.fukurou.util.StringUtil;
028import org.opengion.fukurou.db.ApplicationInfo;
029import org.opengion.fukurou.db.DBUtil;
030
031/**
032 * systemId に対応したユーザー情報を作成するファクトリクラスです。
033 *
034 * UserInfoオブジェクトは、キャッシュせずに、要求都度、データベースを検索します。
035 * これは、ユーザー登録が、他システムより行われる可能性を考慮している為です。
036 * ユーザーオブジェクトの要求は、基本的にログイン時のみで、その後セッションに
037 * キープされます。
038 *
039 * 検索するカラムには、必ず、USERID,LANG,NAME,ROLES がこの順番で含まれており、
040 * 絞込み条件(?パラメータ)として、SYSTEM_ID,USERID がこの順番で指定される必要があります。
041 * (カラム名は関係ありません。並び順と意味が重要です。)
042 * また、検索順(ORDER BY)は、優先順位の低い順に検索してください。使用するのは、一番最後に
043 * 検索された行を使用します。
044 * ユーザーリソースは、RESOURCE_USER_DBID で指定のデータベースから取得します。
045 * 未定義の場合は、RESOURCE_DBID から、それも未定義の場合は デフォルトの接続先を
046 * 使用します。
047 *
048 * SYSTEM_ID='**' は、共通リソースです(ROLESも共通に設定する必要があります。)。
049 * これは、システム間で共通に使用されるリソース情報を登録しておきます。
050 * SYSTEM_ID は、指定のシステムIDと**を検索対象にします。**は、全システム共通の
051 * 指定のシステムIDと**と両方存在する場合は、指定のシステムIDが優先されます。
052 *
053 * ver4 では、デフォルトロールという考え方がなくなりましたので、画面のロールに、
054 * (*)を明示的に追加し、RWMODE を指定する必要があります。
055 *
056 * @og.rev 4.0.0.0 (2004/12/31) 新規作成
057 * @og.rev 8.5.2.0 (2023/07/14) 一部の機能廃止による修正(問合・トラブル 0200010980)
058 * @og.group リソース管理
059 *
060 * @version     4.0
061 * @author      Kazuhiko Hasegawa
062 * @since       JDK5.0,
063 */
064public final class UserInfoFactory {
065
066        private static final String SYSTEM_ID = HybsSystem.sys( "SYSTEM_ID" );
067
068        /** ユーザーリソースの接続先を、取得します。 */
069        private static String dbid = StringUtil.nval(
070                                                                HybsSystem.sys( "RESOURCE_USER_DBID" ) ,
071                                                                HybsSystem.sys( "RESOURCE_DBID" )
072                                                        ) ;
073
074        /** ユーザーリソースのキー指定読み込みのクエリー */
075        private static String query                     = HybsSystem.sys( "RESOURCE_USER_SQL" );
076        private static String queryRole         = HybsSystem.sys( "RESOURCE_USER_ROLE_SQL" );
077
078//      // 5.2.0.0 (2010/09/01) LDAP対応 8.5.2.0 (2023/07/14) Delete
079//      private static String srcType           = HybsSystem.sys( "RESOURCE_USER_SRC_TYPE" );
080//      private static String[] ldapClm         = StringUtil.csv2Array( HybsSystem.sys( "RESOURCE_USER_LDAP_CLM" ) );
081//      private static String ldapFilter        = HybsSystem.sys( "RESOURCE_USER_LDAP_FILTER" );
082//      private static String ldapRoleFilter= HybsSystem.sys( "RESOURCE_USER_ROLE_LDAP_FILTER" );
083
084//      private static String searchScope       = HybsSystem.sys( "LDAP_SEARCH_SCOPE" );
085//      private static String initctx           = HybsSystem.sys( "LDAP_INITIAL_CONTEXT_FACTORY" );
086//      private static String providerURL       = HybsSystem.sys( "LDAP_PROVIDER_URL" );
087//      private static String entrydn           = HybsSystem.sys( "LDAP_ENTRYDN" );
088//      private static String password          = HybsSystem.sys( "LDAP_PASSWORD" );
089//      private static String searchbase        = HybsSystem.sys( "LDAP_SEARCH_BASE" );
090
091        private static final Object LOCK = new Object();                                                        // 6.4.1.1 (2016/01/16) lock → LOCK  refactoring
092
093        /** コネクションにアプリケーション情報を追記するかどうか指定 */
094        public static final boolean USE_DB_APPLICATION_INFO  = HybsSystem.sysBool( "USE_DB_APPLICATION_INFO" ) ;
095
096        /** 4.0.0 (2005/01/31) Cleanable インターフェースによる初期化処理 */
097        static {
098                final Cleanable clr = new Cleanable() {
099                        /**
100                         * 初期化(クリア)します。
101                         * 主に、キャッシュクリアで利用します。
102                         */
103                        public void clear() {
104                                UserInfoFactory.clear();
105                        }
106                };
107
108                SystemManager.addCleanable( clr );
109        }
110
111        /**
112         * デフォルトコンストラクターをprivateにして、
113         * オブジェクトの生成をさせないようにする。
114         */
115        private UserInfoFactory() {}
116
117        /**
118         * UserInfo オブジェクトを取得します。
119         *
120         * UserInfoオブジェクトは、キャッシュせずに、要求都度、データベースを検索します。
121         * これは、ユーザー登録が、他システムより行われる可能性を考慮している為です。
122         * ユーザーオブジェクトの要求は、基本的にログイン時のみで、その後セッションに
123         * キープされます。
124         *
125         * @og.rev 3.7.0.4 (2005/03/18) ゲストログイン機能追加
126         * @og.rev 4.0.0.0 (2007/10/31) ロール指定でのログイン機能追加
127         * @og.rev 4.3.4.0 (2008/12/01) GE20(ユーザー定数)へ登録するかのフラグへの対応
128         * @og.rev 4.4.0.0 (2009/08/02) データロール対応
129         * @og.rev 5.2.0.0 (2010/09/01) LDAP対応
130         * @og.rev 5.3.6.0 (2011/06/01) GE20の読み込みをUserInfo内に移動
131         * @og.rev 7.4.4.0 (2021/06/30) openGionV8事前準備(DataRole.java廃止)
132         * @og.rev 8.5.2.0 (2023/07/14) 一部の機能廃止による修正(問合・トラブル 0200010980)
133         *
134         * @param       userID          ユーザーID
135         * @param       ipAddress       ログイン端末のIPアドレス
136         * @param       roles           データロール
137         * @return      UserInfoオブジェクト
138         */
139        public static UserInfo newInstance( final String userID,final String ipAddress,final String roles ) {
140                // 3.8.7.0 (2006/12/15) アクセスログ取得の為、ApplicationInfoオブジェクトを設定
141                ApplicationInfo appInfo = null ;
142                if( USE_DB_APPLICATION_INFO ) {
143                        appInfo = new ApplicationInfo();
144                        // ユーザーID,IPアドレス,ホスト名
145                        appInfo.setClientInfo( userID,ipAddress,null );
146                        // 画面ID,操作,プログラムID
147                        appInfo.setModuleInfo( "UserInfoFactory",null,"newInstance" );
148                }
149
150                String[][] vals;
151//              if( "LDAP".equalsIgnoreCase( srcType ) ) {                                                              // 8.5.2.0 (2023/07/14) Delete
152//                      vals = getValsByLdap( userID, roles );                                                          // 8.5.2.0 (2023/07/14) Delete
153//              }                                                                                                                                               // 8.5.2.0 (2023/07/14) Delete
154//              else {                                                                                                                                  // 8.5.2.0 (2023/07/14) Delete
155                        vals = getVals( userID, roles, appInfo );
156//              }                                                                                                                                               // 8.5.2.0 (2023/07/14) Delete
157
158                final UserInfo info ;
159                final int len = vals.length ;   // システムID ** を含む。
160        //      if( len >= 1 && vals[0].length >= 5 ) {                                                                 // 7.4.4.0 (2021/06/30) Modify
161                if( len >= 1 && vals[0].length >= 4 ) {
162                        // システムIDでソートされる。SYSTEM_ID="**"は最初に現れるので、最後を取得
163                        info = new UserInfo(
164                                                                userID          ,                       // userID
165                                                                vals[len-1][1]  ,               // lang
166                                                                vals[len-1][2]  ,               // jname
167                                                                vals[len-1][3]  ,               // roles
168        //                                                      vals[len-1][4]  ,               // droles // 4.4.0.0 (2009/08/02) 7.4.4.0 (2021/06/30) Delete
169                                                                SYSTEM_ID               ,               // systemId
170                                                                ipAddress               ,               // ipAddress
171                                                                appInfo                 ) ;             // ApplicationInfo
172                }
173                else {
174        //              final String errMsg = "UserInfo のデータ(USERID,LANG,NAME,ROLES,DROLES)が取得できません。"   // 7.4.4.0 (2021/06/30) Modify
175                        final String errMsg = "UserInfo のデータ(USERID,LANG,NAME,ROLES)が取得できません。"
176                                                + " Key [" + userID + "]"
177                                                + " SQL [" + query + "]" ;
178                        LogWriter.log( errMsg );
179                        throw new HybsSystemException( errMsg );
180                }
181
182                return info ;
183        }
184
185        /**
186         * UserInfoFactoryをクリアします。
187         *
188         * @og.rev 5.2.0.0 (2010/09/01) LDAP対応
189         * @og.rev 8.5.2.0 (2023/07/14) 一部の機能廃止による修正(問合・トラブル 0200010980)
190         */
191        public static void clear() {
192                synchronized( LOCK ) {
193                        dbid = StringUtil.nval(
194                                                                        HybsSystem.sys( "RESOURCE_USER_DBID" ) ,
195                                                                        HybsSystem.sys( "RESOURCE_DBID" )
196                                                                ) ;
197                        query = HybsSystem.sys( "RESOURCE_USER_SQL" );
198                        queryRole = HybsSystem.sys( "RESOURCE_USER_ROLE_SQL" );
199
200//                      // 5.2.0.0 (2010/09/01) LDAP対応 8.5.2.0 (2023/07/14) Delete
201//                      srcType                 = HybsSystem.sys( "RESOURCE_USER_SRC_TYPE" );
202//                      ldapClm                 = StringUtil.csv2Array( HybsSystem.sys( "RESOURCE_USER_LDAP_CLM" ) );
203//                      ldapFilter              = HybsSystem.sys( "RESOURCE_USER_LDAP_FILTER" );
204//                      ldapRoleFilter  = HybsSystem.sys( "RESOURCE_USER_ROLE_LDAP_FILTER" );
205
206//                      searchScope             = HybsSystem.sys( "LDAP_SEARCH_SCOPE" );
207//                      initctx                 = HybsSystem.sys( "LDAP_INITIAL_CONTEXT_FACTORY" );
208//                      providerURL             = HybsSystem.sys( "LDAP_PROVIDER_URL" );
209//                      entrydn                 = HybsSystem.sys( "LDAP_ENTRYDN" );
210//                      password                = HybsSystem.sys( "LDAP_PASSWORD" );
211//                      searchbase              = HybsSystem.sys( "LDAP_SEARCH_BASE" );
212                }
213        }
214
215        /**
216         * DBからユーザーリソースの情報を取得します。
217         *
218         * @og.rev 5.2.0.0 (2010/09/01) 新規作成
219         *
220         * @param       userId  ユーザーID
221         * @param       roles   ロール
222         * @param       appInfo DB接続情報
223         * @return      ユーザーリソース情報
224         */
225        private static String[][] getVals( final String userId, final String roles, final ApplicationInfo appInfo ) {
226                String[] args;
227                String[][] rtn;
228
229                if( roles == null || roles.isEmpty() ) {
230                        args = new String[] { SYSTEM_ID,userId };
231                        synchronized( LOCK ) {
232                                rtn = DBUtil.dbExecute( query,args,appInfo,dbid );
233                        }
234                }
235                // 4.0.0.0 (2007/10/31)
236                else {
237                        args = new String[] { SYSTEM_ID,userId,roles };
238                        synchronized( LOCK ) {
239                                rtn = DBUtil.dbExecute( queryRole,args,appInfo,dbid );
240                        }
241                }
242
243                return rtn;
244        }
245
246//      /**
247//       * LDAPからユーザーリソースの情報を取得します。
248//       *
249//       * @og.rev 5.2.0.0 (2010/09/01) 新規作成
250//       * @og.rev 6.4.7.0 (2016/06/03) IllegalArgumentException が発生した場合に、見えるようにする。
251//       * @og.rev 7.4.4.0 (2021/06/30) openGionV8事前準備(DataRole.java廃止)
252//       * @og.rev 8.5.2.0 (2023/07/14) 一部の機能廃止による修正(問合・トラブル 0200010980)
253//       *
254//       * @param       userId  ユーザーID
255//       * @param       roles   ロール
256//       * @return ユーザーリソース情報
257//       */
258//      private static String[][] getValsByLdap( final String userId, final String roles ) {
259//              final LDAPSearch serch = new LDAPSearch();
260//              serch.setSearchScope( searchScope ) ;
261//              serch.setInitctx( initctx ) ;
262//              serch.setProviderURL( providerURL ) ;
263//              serch.setSearchbase( searchbase ) ;
264//              if( entrydn != null  ) { serch.setEntrydn( entrydn ) ; }
265//              if( password != null ) { serch.setPassword( password ) ; }
266//              serch.setAttributes( ldapClm ) ;
267//              serch.init();
268//
269//              // 6.4.2.1 (2016/02/05) PMD refactoring. Useless parentheses.
270//              String filter = roles == null || roles.isEmpty() ? ldapFilter : ldapRoleFilter;
271//              final String[] args = roles == null || roles.isEmpty() ? new String[] { SYSTEM_ID,userId } : new String[] { SYSTEM_ID,userId,roles };
272//
273//              // 6.4.7.0 (2016/06/03) IllegalArgumentException が発生した場合に、見えるようにする。
274//              try {
275//                      filter = MessageFormat.format( filter,(Object[])args );
276//              }
277//              catch( final IllegalArgumentException ex ) {
278//                      final String errMsg = "MessageFormatエラー:"
279//                                              + " Pattern [" + filter + "]"
280//                                              + " Arguments [" + Arrays.toString( (Object[])args ) + "]" ;
281//                      throw new HybsSystemException( errMsg,ex );
282//              }
283//
284//              final List<String[]> list = serch.search( filter );
285//
286//              String[][] rtn = null;
287//              if( !list.isEmpty() ) {                 // 6.1.1.0 (2015/01/17) refactoring
288//                      rtn = new String[1][];
289//                      rtn[0] = list.get( 0 );
290//                      rtn[0][1] = StringUtil.nval( rtn[0][1], "ja" );                 // 言語のデフォルト値は、'ja'
291//                      rtn[0][2] = StringUtil.nval( rtn[0][2], rtn[0][0] );    // 名称のデフォルト値は、ユーザーID
292//                      rtn[0][3] = StringUtil.nval( rtn[0][3], ldapClm[3] );   // ロールズの初期値は、ロールに設定された項目名
293//      //              rtn[0][4] = StringUtil.nval( rtn[0][4], "" );                   // 7.4.4.0 (2021/06/30) Delete
294//              }
295//
296//              return rtn;
297//      }
298}