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.HashMap;
020import java.util.LinkedHashMap;
021import java.util.Collections;                                                                   // 6.4.3.1 (2016/02/12)
022
023import org.opengion.hayabusa.common.HybsSystem;
024import org.opengion.hayabusa.common.HybsSystemException;
025
026import org.opengion.fukurou.system.DateSet;                                             // 6.4.2.0 (2016/01/29)
027import org.opengion.fukurou.util.HybsDateUtil;                                  // 6.4.2.0 (2016/01/29)
028import org.opengion.fukurou.db.ApplicationInfo;
029import org.opengion.fukurou.db.DBUtil;
030
031/**
032 * ユーザーアクセス画面管理テーブルを維持する為のクラスです。
033 * @og.group リソース管理
034 *
035 * @version  4.1.1.0
036 * @author   Sen.Li
037 * @since    JDK5.0,
038 */
039public final class UserAccessTable {
040        /** 5.3.0.0 (2010/12/01) 画面アクセスの履歴(順番)を管理する機能を追加 */
041        private static final String GEA09_QUERY  = "SELECT GUIKEY,SEQNO,NAME_JA,LAST_ACCESS,FGFAVORITE,CLASSIFY,NEXTGUI FROM GEA09"
042                                                                        + " WHERE SYSTEM_ID=? AND USERID=?"
043                                                                        + " ORDER BY SEQNO,CLASSIFY,GUIKEY";
044        private static final String GEA09_DELETE = "DELETE FROM GEA09"
045                                                                        + " WHERE SYSTEM_ID=? AND USERID=? AND GUIKEY=?";
046        private static final String GEA09_INSERT = "INSERT INTO GEA09(SYSTEM_ID,USERID,GUIKEY,SEQNO,NAME_JA,CLASSIFY,FGJ"
047                                                                        + ",DYSET,USRSET,PGUPD) VALUES(?,?,?,?,?,?,?,?,?,?)";
048        /** 5.3.0.0 (2010/12/01) 画面アクセスの履歴(順番)を管理する機能を追加 */
049        private static final String GEA09_UPDATE = "UPDATE GEA09 SET LAST_ACCESS=?,NEXTGUI=?"
050                                                                        + " WHERE SYSTEM_ID=? AND USERID=? AND GUIKEY=?";
051
052        private static final String DBID = HybsSystem.sys( "RESOURCE_DBID" );
053        private static final int GEA09_GUIKEY           = 0;
054        private static final int GEA09_SEQNO            = 1;
055        private static final int GEA09_NAME_JA          = 2;
056        private static final int GEA09_LAST_ACCESS      = 3;
057        private static final int GEA09_FGFAVORITE       = 4;
058        private static final int GEA09_CLASSIFY         = 5;
059        private static final int GEA09_NEXTGUI          = 6;    // 5.3.0.0 (2010/12/01) 追加
060        private static final String  FGFAVORITE_ON      = "1";
061
062        /** フラグキーの enum */
063        private enum FgKeys { GUIMAP_ONLY,GEA09_ONLY }          // 8.5.4.2 (2024/01/12) PMD 7.0.0 UnnecessarySemicolon
064//      private static enum FgKeys { GUIMAP_ONLY,GEA09_ONLY };
065
066        /**
067         * デフォルトコンストラクターをprivateにして、
068         * オブジェクトの生成をさせないようにする。
069         *
070         * @og.rev 4.3.1.1 (2008/08/23) コンストラクタは、void 宣言を付けません。
071         */
072        private UserAccessTable() { }
073
074        /**
075         * ユーザーアクセス画面管理テーブルを整理します。
076         * このメソッドでは guiMap へのセットをしています(副作用の扱い)。
077         *
078         * @og.rev 4.1.1.0 (2008/01/30) 新規追加
079         * @og.rev 5.3.0.0 (2010/12/01) 画面アクセスの履歴(順番)を管理する機能を追加
080         * @og.rev 6.3.9.0 (2015/11/06) Map.keySet() ではなく、Map.entrySet() を使う様に変更。
081         * @og.rev 6.4.2.0 (2016/01/29) DateSet.getDate( String ) を利用するように修正します。
082         * @og.rev 6.4.2.0 (2016/01/29) HybsDateUtil.getDatePlus( String,int ) を直接利用するように修正します。
083         * @og.rev 6.4.3.1 (2016/02/12) Collections.unmodifiableMap( Map<? extends K,? extends V> ) で作成された変更不可のMapを返します。
084         * @og.rev 6.4.3.4 (2016/03/11) forループを、forEach メソッドに置き換えます。
085         *
086         * @param  guiMap               画面オブジェクトマップへの参照
087         * @param  systemId             システムID
088         * @param  userId               ユーザーID
089         * @param  lang                 言語
090         *
091         * @return      お気に入りマップ(Collections.unmodifiableMapされた書き換え不可のMap)
092         */
093        public static Map<String,FavoriteGUIData> makeAccessDB(
094                                                        final Map<String,GUIInfo> guiMap,final String systemId,final String userId,final String lang ) {
095                final String today                      = DateSet.getDate( "yyyyMMddHHmmss" );                          // 6.4.2.0 (2016/01/29)
096                final Map<String,FgKeys>        fgKeyMap = new HashMap<>();
097                /** コネクションにアプリケーション情報を追記するかどうか指定 */
098                final boolean USE_DB_APPLICATION_INFO  = HybsSystem.sysBool( "USE_DB_APPLICATION_INFO" ) ;
099                ApplicationInfo appInfo = null;
100                if( USE_DB_APPLICATION_INFO ) {
101                        appInfo = new ApplicationInfo();
102                        // ユーザーID,IPアドレス,ホスト名
103                        appInfo.setClientInfo( systemId,HybsSystem.HOST_ADRS,HybsSystem.HOST_NAME );
104                        // 画面ID,操作,プログラムID
105                        appInfo.setModuleInfo( "UserAccessTable",userId,"makeAccessDB" );
106                }
107
108                // guiMapのキーで、新マップを作成、
109                // 6.4.3.4 (2016/03/11) forループを、forEach メソッドに置き換えます。
110                guiMap.keySet().forEach( k -> fgKeyMap.put( k,FgKeys.GUIMAP_ONLY ) );
111
112                final Map<String,FavoriteGUIData> favoriteGuiMap = new LinkedHashMap<>();
113                // 4.1.1.0(2008/01/22)ユーザーアクセスの日付を取得し、accessPastDays 前の日付を計算する。
114                final String accessPastDays     = HybsSystem.sys( "ACCESS_TOKEI_PAST_DAYS" );
115                final int    diffDate   = accessPastDays == null ? 0 : -Integer.parseInt( accessPastDays );
116                final String judgeTime  = HybsDateUtil.getDatePlus( today.substring( 0,8 ),diffDate );                  // 6.4.2.0 (2016/01/29)
117                String lastAccessTime   = null;
118                String key                              = null;
119                // 8.5.4.2 (2024/01/12) PMD 7.0.0 UseShortArrayInitializer
120//              String[]   args                 = new String[] { systemId,userId };
121                final String[]   args1  = { systemId,userId };
122                final String[][] vals   = DBUtil.dbExecute( GEA09_QUERY,args1,appInfo,DBID );
123                final int len                   = vals.length;
124
125                for( int i=0; i<len; i++ ) {
126                        key = vals[i][GEA09_GUIKEY];
127                        final GUIInfo gui = guiMap.get( key );
128                        if( gui == null ) {
129                                fgKeyMap.put( key,FgKeys.GEA09_ONLY );
130                        }
131                        else {
132                                // 5.3.0.0 (2010/12/01) 画面アクセスの履歴(順番)を管理する機能を追加
133                                final String nxtgui = vals[i][GEA09_NEXTGUI];
134                                if( nxtgui != null ) {
135                                        final String[] keys = nxtgui.split( "," );
136                                        for( final String nextKey : keys ) {
137                                                gui.setNextGuiKey( nextKey );           // DB から復活
138                                        }
139                                }
140
141                                fgKeyMap.remove( key );
142                                // 4.1.1.0(2008/01/22)お気に入りマップの作成
143                                if( FGFAVORITE_ON.equals( vals[i][GEA09_FGFAVORITE] ) && gui.isRead() ) {
144                                        favoriteGuiMap.put( key,new FavoriteGUIData( vals[i][GEA09_GUIKEY],vals[i][GEA09_SEQNO]
145                                                ,vals[i][GEA09_NAME_JA],vals[i][GEA09_CLASSIFY] ) );
146                                }
147                                // 4.1.1.0(2008/01/22)ACCESS_TOKEI_PAST_DAYSに定義された期間以内の画面を格上する。
148                                lastAccessTime = vals[i][GEA09_LAST_ACCESS];
149                                // 6.0.0.1 (2014/04/25) These nested if statements could be combined
150                                if( lastAccessTime.length() >= 8 && lastAccessTime.compareTo( judgeTime ) >=0 ) {
151                                        gui.setLevelUp();
152                                }
153                        }
154                }
155
156                final ResourceManager resource = ResourceFactory.newInstance( lang );
157                final String undefined = resource.getLabel( "UNDEFINED" );
158                // 6.3.9.0 (2015/11/06) Map.keySet() ではなく、Map.entrySet() を使う様に変更。
159                for( final Map.Entry<String,FgKeys> entry : fgKeyMap.entrySet() ) {
160                        final String conKey = entry.getKey();
161                        final FgKeys fgKey  = entry.getValue();
162                        // 8.5.5.1 (2024/02/29) switchを、if文に変更
163//                      switch ( fgKey ) {
164//                              case GUIMAP_ONLY:
165//                                      args = new String[] { systemId,userId,conKey,"9999999",guiMap.get(conKey).getLabel()
166//                                                                                ,undefined,"1",today,userId,"UsrAccsTbl" };
167//                                      DBUtil.dbExecute( GEA09_INSERT,args,appInfo,DBID );
168//                                      break;
169//                              case GEA09_ONLY:
170//                                      args = new String[] { systemId,userId,conKey };
171//                                      DBUtil.dbExecute( GEA09_DELETE,args,appInfo,DBID );
172//                                      break;
173//                              default:
174//                                      final String errMsg = "guiMapとGEA09の突合せフラグが GUIMAP_ONLY と GEA09_ONLY 以外の値がセットされています。"
175//                                                                + "画面ID:" + conKey + " フラグ:" + fgKey;
176//                                      throw new HybsSystemException( errMsg );
177//                      }
178                        if( FgKeys.GUIMAP_ONLY == fgKey ) {
179                                final String[] args2 = { systemId,userId,conKey,"9999999",guiMap.get(conKey).getLabel()
180                                                                                        ,undefined,"1",today,userId,"UsrAccsTbl" };
181                                DBUtil.dbExecute( GEA09_INSERT,args2,appInfo,DBID );
182                        }
183                        else if( FgKeys.GEA09_ONLY == fgKey ) {
184                                final String[] args2 = { systemId,userId,conKey };
185                                DBUtil.dbExecute( GEA09_DELETE,args2,appInfo,DBID );
186                        }
187                        else {
188                                final String errMsg = "guiMapとGEA09の突合せフラグが GUIMAP_ONLY と GEA09_ONLY 以外の値がセットされています。"
189                                                          + "画面ID:" + conKey + " フラグ:" + fgKey;
190                                throw new HybsSystemException( errMsg );
191                        }
192                }
193
194                return Collections.unmodifiableMap( favoriteGuiMap );           // 6.4.3.1 (2016/02/12)
195        }
196
197        /**
198         * ユーザーアクセス画面管理テーブルの最終アクセス時間を更新します。
199         *
200         * @og.rev 4.1.1.0 (2008/01/30) 新規追加
201         * @og.rev 5.3.0.0 (2010/12/01) 画面アクセスの履歴(順番)を管理する機能を追加
202         * @og.rev 6.8.4.2 (2017/12/25) nextGuiKeys(NEXTGUI)が、1000Byteのため、文字数制限しておきます。
203         *
204         * @param systemId                      システムID
205         * @param userId                        ユーザーID
206         * @param guiKey                        画面ID
207         * @param lastAccessTime        画面の最終アクセス時間
208         * @param nextGuiKeys           次にアクセスしている画面IDのCSV文字列
209         */
210        public static void updateLastAccessTime( final String systemId,final String userId,final String guiKey,final String lastAccessTime,final String nextGuiKeys ) {
211                /** コネクションにアプリケーション情報を追記するかどうか指定 */
212                final boolean USE_DB_APPLICATION_INFO  = HybsSystem.sysBool( "USE_DB_APPLICATION_INFO" ) ;
213                ApplicationInfo appInfo = null;
214                if( USE_DB_APPLICATION_INFO ) {
215                        appInfo = new ApplicationInfo();
216                        // ユーザーID,IPアドレス,ホスト名
217                        appInfo.setClientInfo( systemId,HybsSystem.HOST_ADRS,HybsSystem.HOST_NAME );
218                        // 画面ID,操作,プログラムID
219                        appInfo.setModuleInfo( "UserAccessTable",userId,"updateLastAccessTime" );
220                }
221
222                // 6.8.4.2 (2017/12/25) nextGuiKeys(NEXTGUI)が、1000Byteのため、文字数制限しておきます。
223                final String nextGui = nextGuiKeys != null && nextGuiKeys.length() > 1000 ? nextGuiKeys.substring( 0,1000 ) : nextGuiKeys ;
224
225                // 5.3.0.0 (2010/12/01) 画面アクセスの履歴(順番)を管理する機能を追加
226                // 8.5.4.2 (2024/01/12) PMD 7.0.0 UseShortArrayInitializer
227//              final String[] args = new String[] { lastAccessTime,nextGui,systemId,userId,guiKey };   // 6.8.4.2 (2017/12/25)
228                final String[] args = { lastAccessTime,nextGui,systemId,userId,guiKey };        // 6.8.4.2 (2017/12/25)
229                DBUtil.dbExecute( GEA09_UPDATE,args,appInfo,DBID );
230        }
231}