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     */
016    package org.opengion.fukurou.process;
017    
018    import org.opengion.fukurou.util.Argument;
019    import org.opengion.fukurou.util.FTPConnect;
020    import org.opengion.fukurou.util.LogWriter;
021    
022    import java.util.Map ;
023    import java.util.LinkedHashMap ;
024    
025    import java.io.File;
026    
027    /**
028     * Process_FileFtp は、上流から受け取っã�?FileLineModel をå?ç�?�™るã?
029     * ChainProcess インターフェースの実è£?‚¯ラスですã?
030     *
031     * 上流から受け取っã�?FileLineModel の ファイルから、localPath のローカル共通パスã‚?
032     * remotePath のFTP共通パスに、PFT伝é?しますã?(-command=PUT 処ç�??み)
033     * ファイルそã?もã?の階層構é?は、維持されるため、ローカルからFTPサーバã?
034     * へのフォルãƒ?‚³ピã?に近いイメージになりますã?
035     *
036     * Process_FileCopy との違いは、ファイルのエンコード変換は行いません。たã�?�—ã€?
037     * FTP伝é?での改行コードã?変換はã€?mode=ASCII でæŒ?®šできますã?
038     * もうひとつ、Process_FileCopy では、inPath と outPath でのCOPY処ç�?�§したがã?
039     * こã?クラスでは、localPath と、remotePath でそれぞれの共通パスを指定しますã?
040     *
041     * 上流ã?ロセスでは、Name 属æ?として、ã?File』を持ち、å?は、Fileオブジェクãƒ?
042     * である、Process_FileSearch を使用するのがã?便利ですã?それ以外ã?クラスã‚?
043     * 使用する場合でもã?Name属æ?と、File オブジェクトを持つ LineModel を受け渡ã�?
044     * できれば、使用可能ですã?
045     *
046     * 引数æ–?­—å?中に空白を含ã‚??合ã?、ダブルコーãƒ??ション("") で括って下さã�??
047     * 引数æ–?­—å?の ã€?』ã?前後には、空白は挟めません。å¿?�šã€?key=value の様に
048     * 繋げてくださいã€?
049     *
050     * @og.formSample
051     *  Process_FileFtp -host=FTPサーバã? -user=ユーザー -pass=パスワーãƒ?-localPath=ローカル共通パス -remotePath=FTP共通パス
052     *                   [-mode=[ASCII/BINARY]  ] [-passive=[true/false] ]
053     *
054     *    -host=FTPサーバã?             ?šFTPサーバã?
055     *    -user=ユーザー                ?šユーザー
056     *    -pass=パスワーãƒ?             ?šパスワーãƒ?
057     *    -localPath=ローカル共通パス   ?š上流で検索されたファイルパスのローカル側共通部åˆ?
058     *    -remotePath=FTP共通パス       ?š上流で検索されたファイルパスのFTP側共通部åˆ?
059     *   [-mode=[ASCII/BINARY]  ]       ?š扱ã�?ƒ•ァイルの種類をæŒ?®šしまã�?初期値:ASCII)
060     *   [-passive=[true/false] ]       ?šパãƒ?‚·ブモーãƒ?ローカルからサーバã?へ接続を張ã‚?を利用するかどã�?�‹(初期値:true)
061     *                                      (false:アクãƒ?‚£ブモーãƒ?通常のFTPの初期値)で通信しますã?)
062     *   [-mkdirs=[true/false]  ]       ?š受けå?ファイル(GETæ™?LOCAL、PUTæ™?FTPサーバã?)にãƒ?‚£レクトリを作æ?するかどã�?�‹(初期値:true)
063     *                                      (false:ãƒ?‚£レクトリが無ければ、エラーにしますã?)
064     *   [-encode=エンコード名 ]        ?š日本語ファイル名などのエンコード名を指定しまã�?初期値:UTF-8)
065     *   [-timeout=タイãƒ?‚¢ウãƒ?秒] ]   ?šDataタイãƒ?‚¢ウãƒ?初期値:600 [秒])
066     *   [-display=[false/true] ]       ?štrueは、検索状況を表示しまã�?初期値:false)
067     *   [-debug=[false/true]   ]       ?šデバッグæƒ??を標準å?力に表示する(true)かしなã�?false)ã�?初期値:false[表示しない])
068     *
069     * @og.rev 5.1.5.0 (2010/04/01) 新規追åŠ?
070     *
071     * ※ 注æ„?
072     *    Windwosにおいて、大量ファイルのFTP伝é?を行う場合ã?、注意がå¿?¦�ですã?
073     *    Windowsにおけるソケãƒ?ƒˆのæœ?¤§値はã€?000がデフォルトå?ですã?
074     *    またã?TIME_WAITのãƒ?ƒ•ォルトå?はã€?åˆ?=240ç§?ですã?
075     *    FTPの様にãƒ??タ伝é?時に毎回、ソケãƒ?ƒˆを作æ?すると、ã?ートが枯æ¸?�—ますã?
076     *
077     *    こã?値を変更するには、レジストリに以下ã?キーを設定するå¿?¦�がありますã?
078     *
079     *    â–?‚½ケãƒ?ƒˆのæœ?¤§数(5,000??5,534の間で設å®???
080     *    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\MaxUserPort (DWORD)
081     *
082     *    â–?IME_WAITの時間(30??00秒ã?間で設å®???
083     *    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\TcpTimedWaitDelay (DWORD)
084     *
085     *    ※ 設定後ã?再起動しなã�?�¨設定が反映されませんã€?
086     *
087     * @version  4.0
088     * @author   Kazuhiko Hasegawa
089     * @since    JDK5.0,
090     */
091    public class Process_FileFtp extends AbstractProcess implements ChainProcess {
092            private static final int     TIMEOUT = 600 ;    // Dataタイãƒ?‚¢ウãƒ?初期値:600 [秒])
093    
094            private FTPConnect      ftp                     = null;
095    //      private File            tempFile        = null;
096    
097            private String  host            = null;                 // FTPサーバã?
098            private String  user            = null;                 // ユーザー
099    //      private String  pass            = null;                 // パスワーãƒ?
100            private String  command         = "PUT";                // FTPサーバã?側での処ç�??方æ³?GET/PUT/DEL)を指定しますã?(PUTのみ固å®?
101            private String  localPath       = null;                 // 上流で検索されたファイルパスのローカル側共通部åˆ?
102            private String  remotePath      = null;                 // 上流で検索されたファイルパスのFTP側共通部åˆ?
103    
104            private boolean display         = false;                // trueは、検索状況を表示しまã�?初期値:false)
105            private boolean debug           = false;                // ãƒ?ƒ�ãƒ?‚°æƒ??を標準å?力に表示する(true)かしなã�?false)ã�?
106    
107            private int     localPathLen    = 0;
108            private int     inCount                 = 0;
109    
110            private static final Map<String,String> mustProparty   ;          // ?»プロパティ?½å¿??チェãƒ?‚¯用 Map
111            private static final Map<String,String> usableProparty ;          // ?»プロパティ?½整合æ?チェãƒ?‚¯ Map
112    
113            private static final String[] MODE_LST = new String[] { "ASCII","BINARY" };
114    //      private static final String[] CMD_LST  = new String[] { "GET","PUT","DEL" };
115    
116            static {
117                    mustProparty = new LinkedHashMap<String,String>();
118                    mustProparty.put( "host",               "接続å?のFTPサーバã?のアドレスまたã?、サーバã?å�?å¿??)" );
119                    mustProparty.put( "user",               "接続するユーザーå�?å¿??)" );
120                    mustProparty.put( "pass",               "接続するユーザーのパスワーãƒ?å¿??)" );
121                    mustProparty.put( "localPath",  "上流で検索されたファイルパスのローカル側共通部åˆ?å¿??)" );
122                    mustProparty.put( "remotePath", "上流で検索されたファイルパスのFTP側共通部åˆ?å¿??)" );
123    
124                    usableProparty = new LinkedHashMap<String,String>();
125                    usableProparty.put( "mode",                     "扱ã�?ƒ•ァイルの種é¡?ASCII/BINARY)を指定しまã�?初期値:ASCII)" );
126            //      usableProparty.put( "command",          "FTPサーバã?側での処ç�??方æ³?GET/PUT/DEL)を指定しまã�?初期値:PUT)" );
127                    usableProparty.put( "passive",          "パッシブモーãƒ?ローカルからサーバã?へ接続を張ã‚?を利用するかどã�?�‹(初期値:true)" );
128                    usableProparty.put( "mkdirs",           "受け側ファイル(GETæ™?LOCAL、PUTæ™?FTPサーバã?)にãƒ?‚£レクトリを作æ?するかどã�?�‹(初期値:true)" );
129                    usableProparty.put( "encode",           "日本語ファイル名などのエンコード名を指定しまã�?初期値:UTF-8)" );
130                    usableProparty.put( "timeout",          "Dataタイãƒ?‚¢ウãƒ?初期値:600 [秒])" );
131                    usableProparty.put( "display",          "[false/true]:trueは、検索状況を表示しまã�?初期値:false)" );
132                    usableProparty.put( "debug",            "ãƒ?ƒ�ãƒ?‚°æƒ??を標準å?力に表示する(true)かしなã�?false)ã�? +
133                                                                                            CR + "(初期値:false:表示しなã�?" );
134            }
135    
136            /**
137             * ãƒ?ƒ•ォルトコンストラクターã€?
138             * こã?クラスは、動çš?½œæ?されますã?ãƒ?ƒ•ォルトコンストラクターでã€?
139             * super クラスに対して、å¿?¦�な初期化を行っておきますã?
140             *
141             */
142            public Process_FileFtp() {
143                    super( "org.opengion.fukurou.process.Process_FileFtp",mustProparty,usableProparty );
144            }
145    
146            /**
147             * プロセスの初期化を行いますã?初めにä¸?º¦ã�?�‘、呼び出されますã?
148             * 初期処ç�?ファイルオープンã€?¼¤?¢オープンç­?に使用しますã?
149             *
150             * @param   paramProcess ãƒ??タベã?スの接続å?æƒ??などを持ってã�?‚‹オブジェクãƒ?
151             */
152            public void init( final ParamProcess paramProcess ) {
153                    Argument arg = getArgument();
154    
155    //              String host = arg.getProparty( "host");                         // FTPサーバã?
156    //              String user = arg.getProparty( "user" );                        // ユーザー
157                    String pass = arg.getProparty( "pass" );                        // パスワーãƒ?
158                    host = arg.getProparty( "host");                        // FTPサーバã?
159                    user = arg.getProparty( "user" );                       // ユーザー
160    //              pass = arg.getProparty( "pass" );                       // パスワーãƒ?
161    
162                    ftp = new FTPConnect();
163    
164                    ftp.setHostUserPass( host , user , pass );
165    
166                    // localPath と、remotePath をセãƒ?ƒˆしますã?
167                    localPath       = arg.getProparty("localPath" );
168                    remotePath      = arg.getProparty("remotePath" );
169    
170                    localPathLen  = localPath.length();
171    
172                    // FTP処ç�?�«å¿?¦�なå�?¨®パラメータをセãƒ?ƒˆしますã?
173                    ftp.setMode(    arg.getProparty( "mode"         ,"ASCII",MODE_LST       ));             // 扱ã�?ƒ•ァイルの種類をæŒ?®šしますã?
174    //              ftp.setCommand( "PUT"                                                                                    );             // FTP処ç�??方法をæŒ?®šしますã?
175                    ftp.setPassive( arg.getProparty( "passive"      ,true                           ));             // パッシブモードを利用するかどã�?�‹
176                    ftp.setMkdirs(  arg.getProparty( "mkdirs"       ,true                           ));             // 受け側ファイルにãƒ?‚£レクトリを作æ?するかどã�?�‹
177                    ftp.setEncode(  arg.getProparty( "encode"       ,"UTF-8"                        ));             // 日本語ファイル名などのエンコード名を指定しまã�?初期値:UTF-8)
178                    ftp.setTimeout( arg.getProparty( "timeout"      ,TIMEOUT                        ));             // Dataタイãƒ?‚¢ウãƒ?初期値:600 [秒])
179    
180                    display = arg.getProparty("display",display);
181                    debug   = arg.getProparty("display",debug);
182    //              if( debug ) { println( arg.toString() ); }                      // 5.7.3.0 (2014/02/07) ãƒ?ƒ�ãƒ?‚°æƒ??
183    
184                    ftp.setDisplay( display );              // trueは、検索状況を表示しますã?(初期値:false)
185                    ftp.setDebug(   debug   );              // ãƒ?ƒ�ãƒ?‚°æƒ??を標準å?力に表示する(true)かしなã�?false)ã�?
186    
187                    // FTPConnect をå?期化しますã?
188                    ftp.connect();
189            }
190    
191            /**
192             * プロセスの終äº?‚’行いますã?æœ?¾Œにä¸?º¦ã�?�‘、呼び出されますã?
193             * 終äº??ç�?ファイルクローズã€?¼¤?¢クローズç­?に使用しますã?
194             *
195             * @param   isOK トã?タルで、OKã�?�£たかどã�?�‹[true:成功/false:失敗]
196             */
197            public void end( final boolean isOK ) {
198                    if( ftp != null ) {
199                            ftp.disconnect();
200                    }
201            }
202    
203            /**
204             * 引数の LineModel をå?ç�?�™るメソãƒ?ƒ‰ですã?
205             * 変換処ç�?¾Œã? LineModel を返しますã?
206             * 後続å?ç�?‚’行わなã�??å�?ãƒ??タのフィルタリングを行う場å�?はã€?
207             * null ãƒ??タを返しますã?つまりã?null ãƒ??タは、後続å?ç�?‚’行わなã�?
208             * フラグの代わりにも使用してã�?�¾すã?
209             * なおã?変換処ç�?¾Œã? LineModel と、オリジナルの LineModel がã?
210             * 同ä¸?�‹、コピã?(クローン)かã?、各処ç�?ƒ¡ソãƒ?ƒ‰å†?�§決めてã�?�¾すã?
211             * ドキュメントに明記されてã�?�ªã�??合ã?、副作用が問題になるå?合ã?ã€?
212             * å�??ç�?�”とに自åˆ?�§コピã?(クローン)して下さã�??
213             *
214             * @param       data    オリジナルのLineModel
215             *
216             * @return      処ç�?¤‰換後ã?LineModel
217             */
218            public LineModel action( final LineModel data ) {
219                    inCount++ ;
220                    final FileLineModel fileData ;
221                    if( data instanceof FileLineModel ) {
222                            fileData = (FileLineModel)data ;
223                    }
224                    else {
225                            // LineModel ã�?FileLineModel でなã�??合ã?オブジェクトを作æ?しますã?
226                            fileData = new FileLineModel( data );
227                    }
228    
229                    File localFile = fileData.getFile() ;   // LineModel から取得したファイルã€?
230                    if( ! localFile.isFile() ) {
231                            if( display ) { println( data.dataLine() ); }
232                            return data;
233                    }
234    
235                    String lclFileName = localFile.getAbsolutePath();
236    
237                    // ファイル名ã?、引数ファイルå�?からã€?localPathを引き、remotePath を加えますã?
238                    String rmtFileName = remotePath + lclFileName.substring( localPathLen );
239    
240    //              ftp.setLocalFile(       lclFileName );                                  // ローカルのファイルå�?
241    //              ftp.setRemoteFile(      rmtFileName );                                  // FTP先ã?ファイルå�?
242    
243                    ftp.action( command,lclFileName,rmtFileName );
244    
245                    if( display ) { println( data.dataLine() ); }
246                    return data ;
247            }
248    
249            /**
250             * プロセスの処ç�?µ�果のレポã?ト表現を返しますã?
251             * 処ç�??ログラãƒ?��、å?力件数、å?力件数などのæƒ??ですã?
252             * こã?æ–?­—å?をそのまま、標準å?力に出すことで、結果レポã?トと出来るよã�?�ª
253             * 形式で出してくださいã€?
254             *
255             * @return   処ç�?µ�果のレポã?ãƒ?
256             */
257            public String report() {
258                    String report = "[" + getClass().getName() + "]" + CR
259                                    + TAB + "Copy Count : " + inCount   + CR
260                                    + TAB + "host       : " + host      + CR
261                                    + TAB + "user       : " + user      + CR
262                                    + TAB + "localPath  : " + localPath + CR
263                                    + TAB + "remotePath : " + remotePath ;
264    
265                    return report ;
266            }
267    
268            /**
269             * こã?クラスの使用方法を返しますã?
270             *
271             * @return      こã?クラスの使用方æ³?
272             */
273            public String usage() {
274                    StringBuilder buf = new StringBuilder();
275    
276                    buf.append( "Process_FileFtp は、上流から受け取っã�?FileLineModel をå?ç�?�™ã‚?                                  ).append( CR );
277                    buf.append( "ChainProcess インターフェースの実è£?‚¯ラスですã?"                                                                      ).append( CR );
278                    buf.append( CR );
279                    buf.append( "上流から受け取っã�?FileLineModel の ファイルから、localPath のローカル共通パスã‚?   ).append( CR );
280                    buf.append( "remotePath のFTP共通パスに、PFT伝é?しますã?(-command=PUT 処ç�??み) "                             ).append( CR );
281                    buf.append( "ファイルそã?もã?の階層構é?は、維持されるため、ローカルからFTPサーバã?"                               ).append( CR );
282                    buf.append( "へのフォルãƒ?‚³ピã?に近いイメージになりますã?"                                                                            ).append( CR );
283                    buf.append( CR );
284                    buf.append( "Process_FileCopy との違いは、ファイルのエンコード変換は行いません。たã�?�—ã€?               ).append( CR );
285                    buf.append( "FTP伝é?での改行コードã?変換はã€?mode=ASCII でæŒ?®šできますã?"                                               ).append( CR );
286                    buf.append( "もうひとつ、Process_FileCopy では、inPath と outPath でのCOPY処ç�?�§したがã?"             ).append( CR );
287                    buf.append( "こã?クラスでは、localPath と、remotePath でそれぞれの共通パスを指定しますã?"                ).append( CR );
288                    buf.append( CR );
289                    buf.append( "上流ã?ロセスでは、Name 属æ?として、ã?File』を持ち、å?は、Fileオブジェクãƒ?                    ).append( CR );
290                    buf.append( "である、Process_FileSearch を使用するのがã?便利ですã?それ以外ã?クラスã‚?                   ).append( CR );
291                    buf.append( "使用する場合でもã?Name属æ?と、File オブジェクトを持つ LineModel を受け渡ã�?          ).append( CR );
292                    buf.append( "できれば、使用可能ですã?"                                                                                                                    ).append( CR );
293                    buf.append( CR ).append( CR );
294    
295                    buf.append( getArgument().usage() ).append( CR );
296    
297                    return buf.toString();
298            }
299    
300            /**
301             * こã?クラスは、main メソãƒ?ƒ‰から実行できませんã€?
302             *
303             * @param       args    コマンド引数配å?
304             */
305            public static void main( final String[] args ) {
306                    LogWriter.log( new Process_FileFtp().usage() );
307            }
308    }