    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.SystemManager;
    020import org.opengion.fukurou.db.DBUtil;
    021import org.opengion.fukurou.util.Cleanable;
    022import org.opengion.fukurou.util.ApplicationInfo;
    023
    024import java.util.Map;
    025import java.util.WeakHashMap;
    026
    027/**
    028 * 事業所(CDJGS) , 年月(YYYYMM) に対応した休日カレンダデータを作成するファクトリクラスです。
    029 *
    030 * カレンダデータは、１日(DY1)〜３１日(DY31)までの日付け欄に対して、0:平日 1:休日 という
    031 * データを持っています。実際には、内部では true:平日 false:休日 という持ち方をします。
    032 * (カレンダＤＢは、文字列ですが、内部で持つ場合は、数字で管理しています。)
    033 *
    034 * 通常のカレンダでは、月毎に、(２月は、年によって)最大日付けが変わります。
    035 * これは、カレンダデータクラスとしては、-1 を設定しておきます。
    036 *
    037 * カレンダデータには、３つのレベルのオブジェクト作成方法が適用されます。
    038 * 他のリソースの３つのレベルとは異なり、エンジンリソースからの読み取りは
    039 * 存在しなく、第４の方法が加わった事により、３つの方法になっています。
    040 *
    041 * まず、読込フラグ(FGLOAD)='1'のカレンダデータは、このCalendarFactoryオブジェクトが
    042 * 構築された時に、すべてキャッシュとして内部メモリに読み取ります。
    043 * 読込フラグが、'1' 以外のデータは、初期起動時には、メモリにキャッシュされず
    044 * 実際に使用されるまで、オブジェクトが作成されません。
    045 * カレンダの場合、過去の使用される可能性が低いデータまで、キャッシュしない様に、
    046 * このフラグを使用して、メモリの節約を図ることが可能になります。
    047 *
    048 * 読込フラグ(FGLOAD)自動設定機能を使用すれば、読み取ったラベルデータに対して、
    049 * 読込フラグ(FGLOAD)に '1' を自動的にセットします。この機能により、一度でも
    050 * 読み取ったことがあるデータに '1' を付け、次回起動時には、メモリキャッシュさせる
    051 * 事と、一度も読み取っていないデータを判別して、データ削除等のメンテナンスに
    052 * 使用することが可能です。
    053 * カレンダに限定すれば、当面使用されない先のカレンダ(１年分など)を登録する時に、
    054 * 読込フラグ(FGLOAD)='0' にしておけば、実際に読み取られるまで、メモリキャッシュ
    055 * されないため、さらにメモリ効率が向上します。
    056 *
    057 * ２つめの方法は、キャッシュに存在しない場合は、ＤＢから読み取ります。
    058 *
    059 * ３つめは、カレンダ特有の方法で、ＤＢにデータが存在しない場合の設定です。
    060 * これは、カレンダテーブル未設定時でも、カレンダとして使用できるように
    061 * 自動的にカレンダデータを作成します。日曜日を休日として自動設定します。
    062 *
    063 * @og.rev 3.6.0.0 (2004/09/17) 新規作成
    064 * @og.group リソース管理
    065 *
    066 * @version  4.0
    067 * @author   Kazuhiko Hasegawa
    068 * @since    JDK5.0,
    069 */
    070public final class CalendarFactory {
    071        private static final Map<String,CalendarData> pool = new WeakHashMap<String,CalendarData>();                                // 4.0.0 (2005/01/31)
    072        private static final Map<String,CalendarQuery> queryClassPool = new WeakHashMap<String,CalendarQuery>();            // 4.0.0 (2005/01/31)
    073        // 4.0.0.0 PGカレンダーの初期設定をシステムリソースに変更
    074//      private static final CalendarData PG_CALENDAR_DATA = new CalendarPGData();
    075        private static CalendarData pgCalData = null;
    076        private static final String PG_CALENDAR_DATA_CLASS = HybsSystem.sys( "DEFAULT_CALENDAR_CLASS");
    077        private static final Object lock = new Object();
    078
    079        // カレンダＤＢの接続先を、取得します。
    080        private static final String DBID  = HybsSystem.sys( "RESOURCE_CALENDAR_DBID" );
    081
    082        // カレンダＤＢを使用するかどうかを指定します。(互換モード)
    083        private static boolean useDB = HybsSystem.sysBool( "USE_CALENDAR_DATABASE" );
    084
    085        // 3.8.7.0 (2006/12/15) アクセスログ取得の為,ApplicationInfoオブジェクトを設定
    086        private static final ApplicationInfo appInfo;
    087
    088        // 4.0.0 (2005/01/31) Cleanable インターフェースによる初期化処理
    089        static {
    090                Cleanable clr = new Cleanable() {
    091                        public void clear() {
    092                                CalendarFactory.clear();
    093                        }
    094                };
    095
    096                SystemManager.addCleanable( clr );
    097
    098                /** コネクションにアプリケーション情報を追記するかどうか指定 */
    099                boolean USE_DB_APPLICATION_INFO  = HybsSystem.sysBool( "USE_DB_APPLICATION_INFO" ) ;
    100
    101                // 3.8.7.0 (2006/12/15) アクセスログ取得の為,ApplicationInfoオブジェクトを設定
    102                if( USE_DB_APPLICATION_INFO ) {
    103                        String SYSTEM_ID = HybsSystem.sys( "SYSTEM_ID" );
    104                        appInfo = new ApplicationInfo();
    105                        // ユーザーID,IPアドレス,ホスト名
    106                        appInfo.setClientInfo( SYSTEM_ID,HybsSystem.HOST_ADRS,HybsSystem.HOST_NAME );
    107                        // 画面ID,操作,プログラムID
    108                        appInfo.setModuleInfo( "CalendarFactory",null,null );
    109                }
    110                else {
    111                        appInfo = null;
    112                }
    113        }
    114
    115        /**
    116         * コンストラクタ
    117         * ファクトリクラスの為、private 化しています。
    118         *
    119         */
    120        private CalendarFactory() { }
    121
    122        /**
    123         * CalendarData オブジェクトを取得します。
    124         * 作成したCalendarDataオブジェクトは，内部にプールしておき，同じリソース要求が
    125         * あったときは，プールの CalendarDataを返します。
    126         * ＤＢにデータが存在しない場合は、自動でカレンダを作成します。
    127         *
    128         * @og.rev 3.8.7.0 (2006/12/15) アクセスログ取得の為,ApplicationInfoオブジェクトを設定
    129         * @og.rev 4.0.0.0 (2007/08/29) カレンダーテーブルが存在しない場合のデフォルトのカレンダーデータをシステムリソースで設定する
    130         *
    131         * @param       cls     CalendarQueryオブジェクトを名称を指定します。
    132         * @param       arg1    データベース検索時の第１引数
    133         * @param       arg2    データベース検索時の第２引数
    134         * @param       arg3    データベース検索時の第３引数
    135         * @param       arg4    データベース検索時の第４引数
    136         *
    137         * @return      CalendarDataオブジェクト
    138         */
    139        public static CalendarData getCalendarData( final String cls,final String arg1,final String arg2,final String arg3,final String arg4 ) {
    140
    141                // 4.0.0.0 PGカレンダーの初期設定をシステムリソースに変更
    142                synchronized( lock ) {
    143                        if(pgCalData == null) {
    144                                pgCalData = (CalendarData)HybsSystem.newInstance(PG_CALENDAR_DATA_CLASS);
    145                        }
    146                }
    147
    148//              if( ! useDB || cls == null ) { return PG_CALENDAR_DATA; }
    149                if( ! useDB || cls == null ) { return pgCalData; }
    150
    151                CalendarData calData ;
    152
    153                String key = cls + ":" + arg1 + ":" + arg2 + ":" + arg3 + ":" + arg4 ;
    154                synchronized( lock ) {
    155                        calData = pool.get( key ) ;
    156                }
    157
    158                if( calData == null ) {
    159                        CalendarQuery query ;
    160                        synchronized( lock ) {
    161                                query = queryClassPool.get( cls );
    162                                if( query == null ) {
    163                                        String queryClass = HybsSystem.sys( "CalendarQuery_" + cls );
    164                                        query = (CalendarQuery)HybsSystem.newInstance( queryClass );
    165                                        queryClassPool.put( cls,query );
    166                                }
    167                        }
    168
    169                        String[] args = query.checkArgment( arg1,arg2,arg3,arg4 );
    170                        String[][] vals = DBUtil.dbExecute( query.getQuery(),args,appInfo,DBID );       // 3.8.7.0 (2006/12/15)
    171                        boolean  isFlat = query.isFlatTable();
    172
    173                        if( vals != null && vals.length > 0 ) {
    174                                calData = new CalendarDBData( vals,isFlat );
    175                                // 完全同期ではない。DB処理中に別にもDB処理を行い、
    176                                // 先に put されたとしても、同一キーに同じ属性のオブジェクトを
    177                                // 登録するだけなので、実質的な問題は発生しない。
    178                                // これが、List などの順序が関係すると、このコードは使えない。
    179                                synchronized( lock ) {
    180                                        pool.put( key,calData );
    181                                }
    182                        }
    183                        else {
    184                                // カレンダテーブルにデータが存在しない場合。
    185                                // 4.0.0.0 PGカレンダーの初期設定をシステムリソースに変更
    186//                              calData = PG_CALENDAR_DATA;
    187                                calData = pgCalData;
    188                        }
    189                }
    190                return calData ;
    191        }
    192
    193        /**
    194         * キャッシュ(プール)から、すべてのオブジェクトをクリアします。
    195         *
    196         */
    197        public static void clear() {
    198                synchronized( lock ) {
    199                        pool.clear();
    200                        queryClassPool.clear();
    201                        useDB = HybsSystem.sysBool( "USE_CALENDAR_DATABASE" );
    202                }
    203        }
    204}