001/*
002 * Copyright (c) 2017 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.fukurou.fileexec;
017
018import java.util.Arrays;
019import java.util.List;
020import java.util.concurrent.ConcurrentMap;
021import java.util.concurrent.ConcurrentHashMap;
022
023import static org.opengion.fukurou.fileexec.CommandLine.GE70;           // enum を簡素化して使用するための定義
024
025/**
026 * MainProcess は、単独で使用する ファイル取込システムのメインクラスです。
027 *
028 *<pre>
029 * このクラスのmainメソッドから起動します。
030 * コマンドラインを処理することで、各種処理を実行します。
031 *
032 *</pre>
033 *
034 * @og.rev 7.0.0.0 (2017/07/07) 新規作成
035 *
036 * @version  7.0
037 * @author   Kazuhiko Hasegawa
038 * @since    JDK1.8,
039 */
040public final class MainProcess {
041        private static final XLogger LOGGER= XLogger.getLogger( MainProcess.class.getName() );  // ログ出力
042
043//      private final ConcurrentMap<Integer,FileExec> execMap = new ConcurrentHashMap<>();
044        private final ConcurrentMap<String,FileExec> execMap = new ConcurrentHashMap<>();               // キーは、systemId + rsrv_no
045
046        /**
047         * デフォルトコンストラクター
048         */
049        public MainProcess() { super(); }                       // 必要ないが、とりあえず。
050
051        /**
052         * 時間起動のタスクオブジェクトを起動します。
053         *
054         * コマンドリストは、予約番号,種別,号機指定,雛形ファイル,開始日時,実行間隔,終了日時,経過終了間隔,パラメータMAP を
055         * 文字列として順番に持っています。
056         * リストの数が、少ない場合は、それぞれ、初期値が使用されます。
057         * 最低、コマンド種別は、必要です。
058         *
059         * @param       cmndLine        CommandLineオブジェクト
060         */
061        public void startTask( final CommandLine cmndLine ) {
062//              // 同一予約番号の過去の依頼は停止しておきます。
063//              final int yoyakuNo = Integer.parseInt( cmndLine.getValue( GE70.RSRV_NO ) );
064//              stopTask( yoyakuNo );                                                                           // 一旦、予約を解除します。
065
066                // タスクオブジェクトの起動前に、一旦過去の依頼は停止しておきます。
067                final String systemId   = cmndLine.getValue( GE70.SYSTEM_ID );          // システムID
068                final String rsrvNo             = cmndLine.getValue( GE70.RSRV_NO );            // 予約番号
069                final String mapKey             = systemId + "_" + rsrvNo ;
070                stopTask( mapKey );                                                                                                     // 一旦、予約を解除します。
071
072                // ※ 取込予約フラグ(FGYKAN)は、DB検索時に、1:登録 4:停止 しか、来ません。
073                final String fgkan = cmndLine.getValue( GE70.FGYKAN );          // 取込予約フラグ 1:登録 2:済 3:実行中 4:停止
074                if( "1".equals( fgkan ) || "3".equals( fgkan ) ) {                      // 取込予約フラグ(FGYKAN)が、1:登録 3:実行中 以外は、過去の依頼を停止した時点で、終了します。
075                        final FileExec fExec = new FileExec( cmndLine );
076
077                        LOGGER.info( () -> "startTask: yoyakuNo=[" + mapKey + "]" );
078
079                        fExec.watchStart();
080//                      execMap.put( yoyakuNo,fExec );
081                        execMap.put( mapKey,fExec );
082                }
083                else {
084                        LOGGER.warning( () -> "【WARNING】startTask: yoyakuNo=[" + mapKey + "] , fgkan=[" + fgkan + "]" );                // 6.8.1.5 (2017/09/08)
085                }
086        }
087
088        /**
089         * 時間起動のタスクオブジェクトをキャンセルします。
090         *
091//       * @param       yoyakuNo        コマンド予約番号
092         * @param       mapKey          コマンド予約番号時のキーワード
093         */
094//      private void stopTask( final int yoyakuNo ) {
095        private void stopTask( final String mapKey ) {
096//              final FileExec  fExec = execMap.remove( yoyakuNo );             // 取り消しなので、Mapから削除します。
097                final FileExec  fExec = execMap.remove( mapKey );               // 取り消しなので、Mapから削除します。
098                if( fExec != null ) {                                                                   // 完了(正常終了、例外、取り消し)以外は、キャンセルします。
099                        fExec.watchStop();
100                }
101
102                LOGGER.info( () -> "stopTask: yoyakuNo=[" + mapKey + "]" );
103        }
104
105        /**
106         * すべての成形機のセッションフォルダの監視を終了します。
107         *
108         */
109        public void watchStop() {
110                execMap.forEach( (no,fExec) -> fExec.watchStop() );
111        }
112
113        /** main メソッドから呼ばれる ヘルプメッセージです。 {@value} */
114        public static final String USAGE = "Usage: java org.opengion.fukurou.fileexec.MainProcess [-LOOP n(秒)] [-help]" ;
115
116        /**
117         * Euromapのミドルウエア(成形条件管理システム)のメインクラスを起動します。
118         *
119         * ベースフォルダを、指定しない場合は、アプリケーションの起動フォルダになります。(./)
120         *
121         * {@value #USAGE}
122         *
123         * @param       args 引数配列
124         */
125        public static void main( final String[] args ) {
126                // ********** 【整合性チェック】 **********
127
128                // ********** 【引数定義】 **********
129                int     loopTime        = 10;                                                   // スキャンするインターバル(秒)
130
131                // ********** 【引数処理】 **********
132                for( int i=0; i<args.length; i++ ) {
133                        final String arg = args[i];
134
135                        if( "-help" .equalsIgnoreCase( arg ) ) { System.out.println( USAGE ); return ; }
136                        else if( "-LOOP" .equalsIgnoreCase( arg ) ) {
137                                loopTime = Integer.parseInt( args[++i] );               // ひとつ進める
138                        }
139                        else {
140                                // MSG2011 = コマンドリストの操作に失敗ました。形式をご確認ください。[{0}]
141                                throw MsgUtil.throwException( "MSG2011" , Arrays.toString( args ) );
142                        }
143                }
144
145                // ********** 【本体処理】 **********
146                final MainProcess mainPrcs = new MainProcess();
147
148                // ほぼ、暫定対応。無限ループで、DBを監視します。
149                boolean isFirst = true;         // 最初だけ、FGYKAN=3:実行中 を検索する必要がある。
150                int cnt = 0;
151                while( true ) {
152                        try {
153                                final List<CommandLine> cmndList = CommandLine.dbCommand( isFirst );
154                                cmndList.forEach( cmndLine -> mainPrcs.startTask( cmndLine ) );
155                                try{ Thread.sleep( loopTime * 1000L ); } catch( final InterruptedException ex ){}
156                                isFirst = false;
157                                System.out.println( StringUtil.getTimeFormat( "yyyyMMdd HH:mm:ss [" + (cnt++) + "]" ) );        // 6.8.1.5 (2017/09/08)
158                        }
159                        catch( final Throwable th ) {
160                                // MSG0021 = 予期せぬエラーが発生しました。\n\tメッセージ=[{0}]
161                                MsgUtil.errPrintln( th , "MSG0021" , th.getMessage() );
162                                try{ Thread.sleep( 10 * loopTime * 1000L ); } catch( final InterruptedException ex ){}
163
164                                mainPrcs.watchStop();
165                        }
166                }
167        }
168}