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.ArrayList; 021import java.util.Map; // Collections.unmodifiableMap で使用 022import java.util.HashMap; // Collections.unmodifiableMap で使用 023import java.util.StringJoiner; 024import java.util.Collections; 025import java.util.concurrent.ConcurrentMap; 026import java.util.concurrent.ConcurrentHashMap; 027 028import static org.opengion.fukurou.fileexec.CommandLine.GE70.* ; // enum を簡素化して使用するための定義 029 030/** 031 * CommandLine は、コマンドリストを管理するクラスです。 032 * 033 *<pre> 034 * コマンドリストは、GE70 テーブルからコマンドを取り出します。 035 * 036 * このクラスは、マルチスレッドに対応していません。 037 *</pre> 038 * @og.rev 7.0.0.0 (2017/07/07) 新規作成 039 * 040 * @version 7.0 041 * @author Kazuhiko Hasegawa 042 * @since JDK1.8, 043 */ 044public final class CommandLine { 045 private static final XLogger LOGGER= XLogger.getLogger( CommandLine.class.getName() ); // ログ出力 046 047 /** GE70 テーブルのカラム定義の enum */ 048 public static enum GE70 { 049 /** GE70 テーブルから検索するカラム名 */ 050 SYSTEM_ID,RSRV_NO,NAME_JA,EXECID,FGYKAN,DIR_BASE,DIR_SUB,DIR_WORK,DIR_BKUP_OK,DIR_BKUP_NG,FILE_FILTER ; 051 052 /** order by で、予約番号(RSRV_NO)順に処理されるようにしておきます。 */ 053 // 取込予約フラグ 1:登録 2:済 3:実行中 4:停止 5:保留 054 // 起動直後に処理する条件。3:実行中 を含む 055 private static final String FROM_WHERE = " from GE70 where FGJ='1' and FGYKAN in " ; 056 057 // 取込予約フラグ 1:登録 2:済 3:実行中 4:停止 5:保留 058 // 通常のループ時に処理する条件 059 private static final String ORDER_BY = " order by SYSTEM_ID,RSRV_NO" ; 060 061 private static final String FGYKAN1 = "('1','3','4')" ; // 起動直後 062 private static final String FGYKAN2 = "('1','4')" ; // ループ処理 063 064 /** 列挙子のCSV形式文字列 のキャッシュ */ 065 public static final String SELECT1 ; // 起動直後 066 public static final String SELECT2 ; // ループ処理 067 static { 068 final StringJoiner sj = new StringJoiner( "," , "select " , FROM_WHERE ); 069 Arrays.stream( values() ).forEachOrdered( v -> sj.add( v.name() ) ); 070 SELECT1 = sj.toString() + FGYKAN1 + ORDER_BY ; 071 SELECT2 = sj.toString() + FGYKAN2 + ORDER_BY ; 072 } 073 074 /** 列挙子の序数(カラムの並び順) */ 075 public final int NO ; 076 077 /** private コンストラクター */ 078 private GE70() { NO = ordinal(); } 079 }; 080 081 // 予約フラグ は、値に応じて、セットする値が異なる。 082 /** Collections.unmodifiableMap を使用。 */ 083 @SuppressWarnings( "serial" ) 084 private static final Map<String,String> IN2OUT = Collections.unmodifiableMap( 085 new HashMap<String, String>() {{ 086 put( "1" , "3" ); // 1:登録 → 3:実行中 087 put( "4" , "2" ); // 4:停止 → 2:済 088 }}); 089 090// // 予約フラグ は、値に応じて、セットする値が異なる。 091// // static イニシャライザで行う場合、エンジンのソースチェックで、警告5 が出るため、一時保留 092// private static final Map<String,String> IN2OUT; 093// static { 094// final Map<String,String> in2out = new HashMap<>(); 095// in2out.put( "1" , "3" ); // 1:登録 → 3:実行中 096// in2out.put( "4" , "2" ); // 4:停止 → 2:済 097// IN2OUT = Collections.unmodifiableMap( in2out ); 098// } 099 100 // GE70 で、IN2OUT に対応した予約フラグ を更新します。 101 private static final String[] UPD_KEYS = new String[] { "FGYKAN","DYUPD","PGUPD" }; 102 private static final String UPD_WHERE = "SYSTEM_ID=? and RSRV_NO=? and FGJ='1'"; 103 104 private static final String UPD_QUER = DBUtil.getUpdateSQL( "GE70",UPD_KEYS,null,null,UPD_WHERE ); 105 106 private final String[] cmndData ; 107 private final String cmndStr ; // toString() 時に使用する、cmndList の文字列表現 108 109 private final ConcurrentMap<String,String> kvMap = new ConcurrentHashMap<>(); // パラメータ(key1=val1 key2=val2 ・・・ のリスト)のMap 110 111 /** 112 * データを引数にとるコンストラクタ 113 * 114 * SYSTEM_ID,RSRV_NO,NAME_JA,EXECID,FGYKAN,DIR_BASE,DIR_SUB,DIR_WORK,DIR_BKUP_OK,DIR_BKUP_NG,FILE_FILTER 115 * システムID,予約番号,名称,処理ID,取込予約フラグ,取込ベースフォルダ,取込サブフォルダ,処理フォルダ(WORK),処理済フォルダ(正常),処理済フォルダ(異常),検索条件 を 116 * 文字列として順番に持っています。 117 * 118 * @og.rev 6.8.1.5 (2017/09/08) LOGGER.debug 情報の追加 119 * 120 * @param values データ 121 * @throws RuntimeException 引数に不整合があった場合。 122 */ 123 private CommandLine( final String[] values ) { 124 cmndData = Arrays.copyOf( values, values.length ); 125 126 cmndStr = Arrays.toString( cmndData ); 127 LOGGER.debug( () -> "① values=" + cmndStr ); 128 129 if( cmndData[RSRV_NO.NO] == null || cmndData[EXECID.NO] == null ) { 130 // MSG2001 = コマンドリストに、予約番号,取込ID,処理IDは必須です。[{0}] 131 throw MsgUtil.throwException( "MSG2001" , cmndStr ); 132 } 133 134 // key=val のパラメータ文字列を、Map化します。 135 final String filter = cmndData[FILE_FILTER.NO]; // 検索条件となるフィルター情報 136 if( filter != null && !filter.trim().isEmpty() && filter.indexOf( '=' ) >= 0 ) { 137 // 6番目のparamsは、key=valの羅列 138 for( final String kvStr : filter.split( " " ) ) { // スペースで分割 139 final int ad = kvStr.indexOf( '=' ); // key=val を見つける。 140 if( ad > 0 ) { 141 final String key = kvStr.substring( 0,ad ).trim(); 142 final String val = kvStr.substring( ad+1 ).trim(); 143 if( !key.isEmpty() ) { kvMap.put( key , val ); } // keyが空文字の場合は、無視 144 } 145 } 146 } 147 } 148 149 /** 150 * 設定値を返します。 151 * 152 * @param clm GE70テーブルを定義したenum 153 * @return 設定値 154 */ 155 public String getValue( final GE70 clm ) { return cmndData[ clm.NO ]; } 156 157 /** 158 * パラメータ(key1=val1 key2=val2 ・・・ のリスト)のMapを返します。 159 * 160 * @return パラメータ(key1=val1 key2=val2 ・・・ のリスト)のMap 161 * @og.rtnNotNull 162 */ 163 public ConcurrentMap<String,String> getKeyValMap() { return kvMap ; } 164 165 /** 166 * 指定のGE70テーブルを読み込んで、CommandLineオブジェクトのListを作成します。 167 * 168 * @param isFirst 起動直後の初期処理かどうかの判定フラグ(起動直後は、true) 169 * @return CommandLineオブジェクトのList 170 */ 171 public static List<CommandLine> dbCommand( final boolean isFirst) { 172 final List<CommandLine> cmndList = new ArrayList<>(); 173 174 // 更新用の値 175 final List<String[]> upddbData = new ArrayList<>(); 176 final String NOW = StringUtil.getTimeFormat(); 177 final String PGID = "CMNDLine"; 178 179 final List<String[]> cmdRow = DBUtil.dbQuery( isFirst ? SELECT1 : SELECT2 ); // GE70.SELECT 180 for( final String[] cmdClms : cmdRow ) { 181 cmndList.add( new CommandLine( cmdClms ) ); 182 183 final String fgKan = IN2OUT.get( cmdClms[FGYKAN.NO] ); // 予約フラグ 184 if( fgKan != null ) { // 予約フラグ が、対象の場合。 185 // 予約フラグを、IN2OUT で変換した値に更新します。 186 // M_FileExec テーブルの更新カラム 187 final String[] updVals = new String[] { 188 fgKan // 予約フラグ FGYKAN 189 , NOW // 更新日時 DYUPD 190 , PGID // 更新PG PGUPD 191 , cmdClms[SYSTEM_ID.NO] // システムID SYSTEM_ID 192 , cmdClms[RSRV_NO.NO] // 予約番号 RSRV_NO 193 } ; 194 upddbData.add( updVals ); 195 } 196 } 197 198 if( ! upddbData.isEmpty() ) { 199 DBUtil.execute( UPD_QUER , upddbData ); 200 } 201 202 return cmndList ; 203 } 204 205 /** 206 *コマンドリストクラスの文字列表現を返します。 207 * 208 * @return コマンドリストクラスの文字列表現 209 */ 210 @Override 211 public String toString() { return cmndStr ; } 212}