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.fukurou.util;
017
018import java.io.FileInputStream;
019import java.io.FileOutputStream;
020import java.io.InputStream;
021import java.io.OutputStream;
022import java.io.PrintWriter;
023import java.io.IOException;
024import java.util.Map;
025import java.util.LinkedHashMap ;
026
027import org.apache.commons.net.ftp.FTP;
028import org.apache.commons.net.ftp.FTPClient;
029import org.apache.commons.net.ftp.FTPFile;
030import org.apache.commons.net.PrintCommandListener;
031import org.apache.commons.net.ftp.FTPReply;
032
033/**
034 * FTPConnect.java は、共通的に使用される FTP関連の基本機能を実装した、クラスです。
035 *
036 * これは、org.apache.commons.net.ftp.FTPClient をベースに開発されています。
037 * このクラスの実行には、commons-net-ftp-2.0.jar が必要です。
038 *
039 * -host=FTPサーバー -user=ユーザー -passwd=パスワード -remoteFile=FTP先のファイル名 を必須設定します。
040 * -localFile=ローカルのファイル名は、必須ではありませんが、-command=DEL の場合にのみ不要であり、
041 * それ以外の command の場合は、必要です。
042 *
043 * -mode=[ASCII/BINARY] は、ファイル転送時に、ファイルの種類によって指定します。
044 * ASCIIモードは、OS毎に異なる改行コードを変換して転送します。BINARYモードは、そのままの姿でやり取りします。
045 *
046 * -command=[GET/PUT/DEL] は、FTPサーバーに対しての処理の方法を指定します。
047 *   GET:FTPサーバーからローカルにファイル転送します(初期値)。
048 *   PUT:ローカルファイルをFTPサーバーに PUT(STORE、SAVE、UPLOAD、などと同意語)します。
049 *   DEL:FTPサーバーの指定のファイルを削除します。この場合のみ、-localFile 属性の指定は不要です。
050 *
051 * -passive=[true/false] は、パッシブモード(ローカルからサーバーへ接続を張る)を利用する場合に宣言します。
052 * 初期値は、true:使用する です。
053 * 通常のFTPでは、アクティブモードでファイルをやり取りします。これは、クライアント側が、サーバーソケットを
054 * オープンし、指定のポートで待ちうけ状態を作り、FTPサーバー側から接続してもらいます。
055 * 一般的な企業内では、ファイアウォールの設定等で、外部からの接続を制限しているケースが多く、アクティブモード
056 * では、繋がらない場合が、ほとんどです。
057 * このクラスでは、初期値をパッシブモードにすることで、企業内のファイアウォールのある環境でも
058 * 接続できるようにしています。
059 *
060 * -mkdirs=[true/false] は、受け側のファイル(GET時:LOCAL、PUT時:FTPサーバー)に取り込むファイルのディレクトリが
061 * 存在しない場合に、作成するかどうかを指定します(初期値:true)。
062 * 通常、FTPサーバーに、フォルダ階層を作成してPUTする場合、動的にフォルダ階層を作成したいケースで便利です。
063 * 逆に、フォルダは確定しており、指定フォルダ以外に PUT するのはバグっていると事が分かっている場合には
064 * false に設定して、存在しないフォルダにPUT しようとすると、エラーになるようにします。
065 *
066 * 引数文字列中に空白を含む場合は、ダブルコーテーション("") で括って下さい。
067 * 引数文字列の 『=』の前後には、空白は挟めません。必ず、-key=value の様に
068 * 繋げてください。
069 *
070 * @og.formSample
071 *  FTPConnect -host=FTPサーバー -user=ユーザー -passwd=パスワード -remoteFile=FTP先のファイル名 [-localFile=ローカルのファイル名]
072 *                   [-mode=[ASCII/BINARY]  ] [-command=[GET/PUT/DEL] ] [-passive=[true/false] ]
073 *
074 *    -host=FTPサーバー                 :接続先のFTPサーバーのアドレスまたは、サーバー名
075 *    -user=ユーザー                    :接続するユーザー名
076 *    -passwd=パスワード                :接続するユーザーのパスワード
077 *    -remoteFile=FTP先のファイル名     :接続先のFTPサーバー側のファイル名。PUT,GET 関係なくFTP側として指定します。
078 *   [-localFile=ローカルのファイル名]  :ローカルのファイル名。PUT,GET 関係なくローカルファイルを指定します。
079 *   [-port=ポート ]                    :接続するサーバーのポートを指定します。
080 *   [-mode=[ASCII/BINARY]  ]           :扱うファイルの種類を指定します(初期値:ASCII)
081 *   [-command=[GET/PUT/DEL] ]          :FTPサーバー側での処理の方法を指定します。
082 *                                              GET:FTP⇒LOCAL、PUT:LOCAL⇒FTP への転送です(初期値:GET)
083 *                                              DEL:FTPファイルを削除します。
084 *   [-passive=[true/false] ]           :パッシブモード(ローカルからサーバーへ接続を張る)を利用するかどうか(初期値:true)
085 *                                              (false:アクティブモード(通常のFTPの初期値)で通信します。)
086 *   [-mkdirs=[true/false]  ]           :受け側ファイル(GET時:LOCAL、PUT時:FTPサーバー)にディレクトリを作成するかどうか(初期値:true)
087 *                                              (false:ディレクトリが無ければ、エラーにします。)
088 *   [-encode=エンコード名 ]            :日本語ファイル名などのエンコード名を指定します(初期値:UTF-8)
089 *   [-timeout=タイムアウト[秒] ]       :Dataタイムアウト(初期値:600 [秒])
090 *   [-display=[false/true] ]           :trueは、検索状況を表示します(初期値:false)
091 *   [-debug=[false|true]   ]           :デバッグ情報を標準出力に表示する(true)かしない(false)か(初期値:false[表示しない])
092 *
093 * @og.rev 5.1.6.0 (2010/05/01) 新規追加
094 *
095 * @version  5.0
096 * @author       Kazuhiko Hasegawa
097 * @since    JDK5.0,
098 */
099public final class FTPConnect extends AbstractConnect {
100        private final FTPClient ftp;
101
102        private static final int DEF_PORT       = 21;                   // ポート
103
104        private boolean isAsciiMode = true;                     // 扱うファイルの種類を指定します。             (true:ASCII / false:BINARY)
105        private boolean isPassive       = true;                 // パッシブモードを利用するかどうか。    (true:パッシブ / false:アクティブ)
106        private String  encode          = "UTF-8";              // 日本語ファイル名などのエンコード名(初期値:UTF-8)
107
108        private boolean isConnect       = false;                // コネクト済みかどうか。
109
110        private String  lastRemoteDir   = "/";          // FTP先の最後に登録したフォルダ名(mkdir の高速化のため)
111
112        /**
113         * デフォルトコンストラクター
114         */
115        public FTPConnect() {
116                ftp = new FTPClient();
117        }
118
119        /**
120         * FTPサーバーへの接続、ログインを行います。
121         *
122         * このメソッドは、初期化メソッドです。
123         * FTPサーバーへの接続、ログインを行いますので、複数ファイルを転送する
124         * ケースでは、最初に1度だけ呼び出すだけです。
125         * 接続先を変更する場合は、もう一度このメソッドをコールする必要があります。
126         * (そのような場合は、通常、オブジェクトを構築しなおす方がよいと思います。)
127         */
128        @Override
129        public void connect() {
130                if( isDisplay ) { System.out.println( "CONNECT: HOST=" + host + ",USER=" + user + ",PORT=" + port ); }
131
132                // もし、すでに接続されていた場合は、クロース処理を行います。
133                if( isConnect ) { disconnect(); }
134
135                try {
136                        // connectメソッドの前に呼び出さなければならないらしい。
137                        // 日本語ファイル名対応(初期値:UTF-8)
138                        if( encode != null ) {
139                                ftp.setControlEncoding( encode );
140                        }
141
142                        // サーバーに対して接続を行います。
143                        ftp.connect( host, getPort( DEF_PORT ) );
144
145                        int reply = ftp.getReplyCode();
146
147                        if( !FTPReply.isPositiveCompletion( reply ) ) {
148                                errAppend( "FTP server refused connection. [PositiveCompletion]" );
149                                errAppend( "   host    = [" , host      , "]" );
150                                errAppend( "   user    = [" , user      , "]" );
151                                errAppend( "   port    = [" , port      , "]" );
152                                errAppend( ftp.getReplyString() );
153                                disconnect();
154                                throw new RuntimeException( getErrMsg() );
155                        }
156
157                        // サーバーに対してログインを行います。
158                        if( !ftp.login( user, passwd ) ) {
159                                errAppend( "ログインに失敗しました。" );
160                                errAppend( "   host    = [" , host      , "]" );
161                                errAppend( "   user    = [" , user      , "]" );
162                                errAppend( "   port    = [" , port      , "]" );
163                                errAppend( ftp.getReplyString() );
164                                disconnect();
165                                throw new RuntimeException( getErrMsg() );
166                        }
167
168                        // 各種パラメータを設定します。
169                        paramInit();
170                }
171                catch ( IOException ex ) {
172                        errAppend( "FTP server refused connection." );
173                        errAppend( ftp.getReplyString() );
174                        errAppend( ex );
175                        if( isDebug ) { ex.printStackTrace(); }
176                        disconnect();
177                        throw new RuntimeException( getErrMsg(),ex );
178                }
179
180                isConnect = true;
181        }
182
183        /**
184         * 設定されたパラメータの初期化処理を行います。
185         *
186         * このメソッドは、ftp.connectt( host )メソッドの実行後に
187         * 呼び出す必要があります。
188         * パラメータを再セット後に、このメソッドを呼び出すことになります。
189         * timeout , encode , CommandListener(display や debug属性) , isPassive ,
190         * isAsciiMode など、ファイル名以外の属性情報の設定を反映させます。
191         * 複数ファイルの転送時には、localFile , remoteFile 属性を設定の上、action() メソッドを
192         * 呼び出すことで、対応できます。
193         *
194         * @throws IOException 入出力エラーが発生したとき
195         */
196        private void paramInit() throws IOException {
197
198                // Dataタイムアウト(初期値:600 [秒])。FTPClient のメソッドには、ミリ秒でセットします。
199                ftp.setDataTimeout( timeout*1000 );
200
201                // コマンドリスナーのセット(設定済みのListenerをremoveする実装は、入れてません。)
202                if( isDisplay && isDebug ) {
203                        ftp.addProtocolCommandListener( new PrintCommandListener( new PrintWriter(System.out) ) );
204                }
205
206                // パッシブモードを利用するかどうか。 (true:パッシブ / false:アクティブ)
207                if( isPassive ) { ftp.enterLocalPassiveMode();  }
208                else                    { ftp.enterLocalActiveMode();   }
209
210                // 扱うファイルの種類を指定(true:ASCII / false:BINARY)
211                boolean isOK = FLAG_OK ;
212                if( isAsciiMode ) { isOK = ftp.setFileType( FTP.ASCII_FILE_TYPE ); }
213                else                      { isOK = ftp.setFileType( FTP.BINARY_FILE_TYPE );}
214
215                if( !isOK ) {
216                        errAppend( "paramInit Error." );
217                        errAppend( ftp.getReplyString() );
218                        throw new RuntimeException( getErrMsg() );
219                }
220        }
221
222        /**
223         * FTPサーバーとの接続をクローズします。
224         *
225         * ログインされている場合は、ログアウトも行います。
226         * コネクトされている場合は、ディスコネクトします。
227         *
228         */
229        @Override
230        public void disconnect() {
231                if( isDisplay ) { System.out.println( "DISCONNECT:" ); }
232
233                if( isConnect ) {
234                        isConnect = false;
235                        try {
236                                ftp.logout();
237                                if( ftp.isConnected() ) {
238                                        ftp.disconnect();
239                                }
240                        }
241                        catch( Throwable th ) {
242                                errAppend( "disconnect Error." );
243                                errAppend( ftp.getReplyString() );
244                                errAppend( th );
245                                if( isDebug ) { th.printStackTrace(); }
246                                throw new RuntimeException( getErrMsg(),th );
247                        }
248                }
249        }
250
251        /**
252         * command="GET" が指定されたときの処理を行います。
253         *
254         * 接続先のFTPサーバー側のファイル名をローカルにダウンロードします。
255         *
256         * @param       localFile       ローカルのファイル名
257         * @param       remoteFile      FTP先のファイル名
258         * @throws IOException 入出力エラーが発生したとき
259         */
260        @Override
261        protected void actionGET( final String localFile, final String remoteFile ) throws IOException {
262                if( isDebug ) { System.out.println( "GET: " + remoteFile + " => " + localFile ); }
263
264                // GET(DOWNLOAD)取得時は、ローカルファイルのディレクトリを作成する必要がある。
265                if( isMkdirs ) {
266                        makeLocalDir( localFile );
267                }
268
269        //      InputStream  input  = null;
270                OutputStream output = null;
271                try {
272        //              input  = ftp.retrieveFileStream( remoteFile );  // 連続読み込みを行うと、null になった。
273                        output = new FileOutputStream( localFile );
274        //              isOK = FileUtil.copy( input,output );
275                        if( !ftp.retrieveFile( remoteFile, output ) ) {
276                                errAppend( "ファイルの取得(GET)に失敗しました。" );
277                                errAppend( "   localFile  = [" , localFile      , "]" );
278                                errAppend( "   remoteFile = [" , remoteFile , "]" );
279                                errAppend( ftp.getReplyString() );
280                                throw new RuntimeException( getErrMsg() );
281                        }
282                }
283                finally {
284        //              Closer.ioClose( input );
285                        Closer.ioClose( output );
286                }
287        }
288
289        /**
290         * command="GETDIR" が指定されたときの処理を行います。
291         *
292         * 接続先のFTPサーバー側のディレクトリ以下をローカルディレクトリに階層構造のままダウンロードします。
293         *
294         * @param       localDir        ローカルのディレクトリ名
295         * @param       remoteDir       FTP先のディレクトリ名
296         * @throws IOException 入出力エラーが発生したとき
297         */
298        @Override
299        protected void actionGETdir( final String localDir, final String remoteDir ) throws IOException {
300                FTPFile[] rmtFiles = ftp.listFiles( remoteDir );
301                for( int i=0; i<rmtFiles.length; i++ ) {
302                        String rmt = rmtFiles[i].getName();
303                        if( rmtFiles[i].isDirectory() ) {
304                                actionGETdir( addFile( localDir,rmt ),addFile( remoteDir,rmt ) );
305                        }
306                        else {
307                                actionGET( addFile( localDir,rmt ),addFile( remoteDir,rmt ) );
308                        }
309                }
310        }
311
312        /**
313         * command="PUT" が指定されたときの処理を行います。
314         *
315         * ローカルファイルを、接続先のFTPサーバー側にアップロードします。
316         *
317         * @param       localFile       ローカルのファイル名
318         * @param       remoteFile      FTP先のファイル名
319         * @throws IOException 入出力エラーが発生したとき
320         */
321        @Override
322        protected void actionPUT( final String localFile, final String remoteFile ) throws IOException {
323                if( isDebug ) { System.out.println( "PUT: " + localFile + " => " + remoteFile ); }
324
325                boolean isOK = FLAG_OK;
326
327                // PUT(UPLOAD)登録時は、リモートファイルのディレクトリを作成する必要がある。
328                if( isMkdirs ) {
329                        // 前回のDIRとの比較で、すでに存在していれば、makeDirectory 処理をパスする。
330                        int ad = remoteFile.lastIndexOf( '/' ) + 1;     // 区切り文字を+1する。
331                        String tmp = remoteFile.substring( 0,ad );
332                        if( ad > 0 && !lastRemoteDir.startsWith( tmp ) ) {
333                                lastRemoteDir = tmp;
334                                if( tmp.startsWith( "/" ) ) {
335                                        String[] fls = tmp.split( "/" );
336                                        ftp.changeWorkingDirectory( "/" );
337                                        for( int i=1; i<fls.length; i++ ) {
338                                                isOK = ftp.changeWorkingDirectory( fls[i] );    // まず、チェンジしてみる。
339                                                if( ! isOK ) {
340                                                        isOK = ftp.makeDirectory( fls[i] );                     // チェンジできなければ、作る。
341                                                        if( isOK ) {
342                                                                isOK = ftp.changeWorkingDirectory( fls[i] );    // 作れれば、チェンジする。
343                                                        }
344                                                }
345                                                // チェンジできなければ、エラー
346                                                if( ! isOK ) {
347                                                        errAppend( "チェンジディレクトリに失敗しました。" );
348                                                        errAppend( "   remoteDir  = [" , lastRemoteDir  , "]" );
349                                                        errAppend( ftp.getReplyString() );
350                                                        throw new RuntimeException( getErrMsg() );
351                                                }
352                                        }
353                                }
354                                if( ! isOK ) {
355                                        errAppend( "ディレクトリの作成に失敗しました。" );
356                                        errAppend( "   remoteDir  = [" , lastRemoteDir  , "]" );
357                                        errAppend( ftp.getReplyString() );
358                                        throw new RuntimeException( getErrMsg() );
359                                }
360                        }
361                }
362
363                InputStream  input  = null;
364        //      OutputStream output = null;
365                try {
366                        input  = new FileInputStream( localFile );
367        //              output = ftp.storeFileStream( remoteFile );
368        //              isOK = FileUtil.copy( input,output );
369                        if( !ftp.storeFile( remoteFile, input ) ) {
370                                errAppend( "ファイルのストア(PUT)に失敗しました。" );
371                                errAppend( "   localFile  = [" , localFile      , "]" );
372                                errAppend( "   remoteFile = [" , remoteFile , "]" );
373                                errAppend( ftp.getReplyString() );
374                                throw new RuntimeException( getErrMsg() );
375                        }
376                }
377                finally {
378                        Closer.ioClose( input );
379        //              Closer.ioClose( output );
380                }
381        }
382
383        /**
384         * command="DEL" が指定されたときの処理を行います。
385         *
386         * 接続先のFTPサーバー側のファイル名を削除します。
387         *
388         * @param       remoteFile      FTP先のファイル名
389         * @throws IOException 入出力エラーが発生したとき
390         */
391        @Override
392        protected void actionDEL( final String remoteFile ) throws IOException {
393                if( isDebug ) { System.out.println( "DEL: " + remoteFile ); }
394
395                if( !ftp.deleteFile( remoteFile ) ) {
396                        errAppend( "ファイルの削除(DEL)に失敗しました。" );
397                        errAppend( "   remoteFile = [" , remoteFile , "]" );
398                        errAppend( ftp.getReplyString() );
399                        throw new RuntimeException( getErrMsg() );
400                }
401        }
402
403        /**
404         * command="DELDIR" が指定されたときの処理を行います。
405         *
406         * 接続先のFTPサーバー側のディレクトリ名を削除します。
407         *
408         * @param       remoteDir       FTP先のディレクトリ名
409         * @throws IOException 入出力エラーが発生したとき
410         */
411        @Override
412        protected void actionDELdir( final String remoteDir ) throws IOException {
413
414                FTPFile[] rmtFiles = ftp.listFiles( remoteDir );
415                for( int i=0; i<rmtFiles.length; i++ ) {
416                        String rmt = addFile( remoteDir,rmtFiles[i].getName() );
417                        if( rmtFiles[i].isDirectory() ) {
418                                actionDELdir( rmt );
419                        }
420                        else {
421                                actionDEL( rmt );
422//                              isOK =  ftp.deleteFile( rmt );
423                        }
424                }
425
426                if( !ftp.removeDirectory( remoteDir ) ) {
427                        errAppend( "Directoryの削除(DEL)に失敗しました。" );
428                        errAppend( "   remoteDir = [" , remoteDir , "]" );
429                        errAppend( ftp.getReplyString() );
430                        throw new RuntimeException( getErrMsg() );
431                }
432        }
433
434        /**
435         * 扱うファイルの種類を指定します (初期値:ASCII)。
436         *
437         * ファイルを FTP でやり取りする場合、ASCII 指定すると、OSの改行コードの違いを
438         * 吸収して、ファイルのやり取りが行われます。(つまり、改行コード変換が行われます。)
439         * BINARY 指定すると、現状のファイルのまま、やり取りされます。
440         * これは、たとえ、アスキーファイルであっても、そのままの姿でやり取りされるということです。
441         * 内部的には、isAsciiMode 属性に、true:ASCII / false:BINARY で管理されます。
442         *
443         * @param       mode    扱うファイルの種類を指定します [ASCII/BINARY]
444         */
445        public void setMode( final String mode ) {
446                if( mode != null ) {
447                        if( ! "ASCII".equals( mode ) && ! "BINARY".equals( mode ) ) {
448                                errAppend( "モード指定は、ASCII または、BINARY と指定ください。" );
449                                errAppend( "   mode  = [" , mode        , "]" );
450                                throw new RuntimeException( getErrMsg() );
451                        }
452
453                        isAsciiMode = "ASCII".equals( mode ) ;          // "ASCII" 以外は、すべて "BINARY" になる。
454                }
455        }
456
457        /**
458         * パッシブモードを利用するかどうか(true:パッシブ)を設定します(初期値:true)。
459         *
460         * パッシブモード(ローカルからサーバーへ接続を張る)を利用する場合に宣言します。
461         * 通常のFTPでは、アクティブモードでファイルをやり取りします。これは、クライアント側が、サーバーソケットを
462         * オープンし、指定のポートで待ちうけ状態を作り、FTPサーバー側から接続してもらいます。
463         * 一般的な企業内では、ファイアウォールの設定等で、外部からの接続を制限しているケースが多く、アクティブモード
464         * では、繋がらない場合が、ほとんどです。
465         * このクラスでは、初期値をパッシブモードにすることで、企業内のファイアウォールのある環境でも
466         * 接続できるようにしています。
467         *
468         * @param       isPassive       パッシブモードを利用するかどうか。(true:パッシブ)
469         */
470        public void setPassive( final boolean isPassive ) {
471                this.isPassive = isPassive ;
472        }
473
474        /**
475         * 日本語ファイル名などのエンコード名を指定します(初期値:UTF-8)。
476         *
477         * @param       encode  エンコード名
478         */
479        public void setEncode( final String encode ) {
480                if( encode != null ) {
481                        this.encode = encode ;
482                }
483        }
484
485// ******************************************************************************************************* //
486//       以下、単独で使用する場合の main処理
487// ******************************************************************************************************* //
488
489        private static final Map<String,String> mustProparty   ;          // [プロパティ]必須チェック用 Map
490        private static final Map<String,String> usableProparty ;          // [プロパティ]整合性チェック Map
491
492        static {
493                mustProparty = new LinkedHashMap<String,String>();
494                mustProparty.put( "host",               "接続先のFTPサーバーのアドレスまたは、サーバー名(必須)" );
495                mustProparty.put( "user",               "接続するユーザー名(必須)" );
496                mustProparty.put( "passwd",             "接続するユーザーのパスワード(必須)" );
497                mustProparty.put( "remoteFile", "接続先のFTPサーバー側のファイル名(必須)" );
498
499                usableProparty = new LinkedHashMap<String,String>();
500                usableProparty.put( "localFile",        "ローカルのファイル名" );
501                usableProparty.put( "port",                     "接続に利用するポート番号を設定します。" );
502                usableProparty.put( "mode",                     "扱うファイルの種類(ASCII/BINARY)を指定します(初期値:ASCII)" );
503                usableProparty.put( "command",          "FTPサーバー側での処理の方法(GET/PUT/DEL)を指定します(初期値:GET)" );
504                usableProparty.put( "passive",          "パッシブモード(ローカルからサーバーへ接続を張る)を利用するかどうか(初期値:true)" );
505                usableProparty.put( "mkdirs",           "受け側ファイル(GET時:LOCAL、PUT時:FTPサーバー)にディレクトリを作成するかどうか(初期値:true)" );
506                usableProparty.put( "encode",           "日本語ファイル名などのエンコード名を指定します(初期値:UTF-8)" );
507                usableProparty.put( "timeout",          "Dataタイムアウト(初期値:600 [秒])" );
508                usableProparty.put( "display",          "[false/true]:trueは、検索状況を表示します(初期値:false)" );
509                usableProparty.put( "debug",            "デバッグ情報を標準出力に表示する(true)かしない(false)か" +
510                                                                                        CR + "(初期値:false:表示しない)" );
511        }
512
513        private static final String[] MODE_LST = new String[] { "ASCII","BINARY" };
514        private static final String[] CMD_LST  = new String[] { "GET","PUT","DEL","GETDIR","PUTDIR","DELDIR" };
515
516        /**
517         * このクラスの動作確認用の、main メソッドです。
518         *
519         * @param       args    コマンド引数配列
520         */
521        public static void main( final String[] args ) {
522                Argument arg = new Argument( "org.opengion.fukurou.util.FTPConnect" );
523                arg.setMustProparty( mustProparty );
524                arg.setUsableProparty( usableProparty );
525                arg.setArgument( args );
526
527                FTPConnect ftp = new FTPConnect();
528
529                String host   = arg.getProparty( "host");                       // FTPサーバー
530                String user   = arg.getProparty( "user" );                      // ユーザー
531                String passwd = arg.getProparty( "passwd" );            // パスワード
532
533                ftp.setHostUserPass( host , user , passwd );
534
535                ftp.setPort(    arg.getProparty( "port"                                 ) );            // 接続に利用するポート番号を設定します。
536                ftp.setMode(    arg.getProparty( "mode"         ,"ASCII",MODE_LST ) );  // 扱うファイルの種類を指定します。
537                ftp.setPassive( arg.getProparty( "passive"      ,true           ) );            // パッシブモードを利用するかどうか
538                ftp.setMkdirs(  arg.getProparty( "mkdirs"       ,true           ) );            // 受け側ファイルにディレクトリを作成するかどうか
539                ftp.setEncode(  arg.getProparty( "encode"       ,"UTF-8"    ) );                // 日本語ファイル名などのエンコード名を指定します(初期値:UTF-8)
540                ftp.setTimeout( arg.getProparty( "timeout"      ,TIMEOUT    ) );                // Dataタイムアウト(初期値:600 [秒])
541                ftp.setDisplay( arg.getProparty( "display"      ,false          ) );            // trueは、検索状況を表示します(初期値:false)
542                ftp.setDebug(   arg.getProparty( "debug"        ,false          ) );            // デバッグ情報を標準出力に表示する(true)かしない(false)か
543
544                try {
545                        // コネクトします。
546                        ftp.connect();
547
548                        String command          = arg.getProparty( "command" ,"GET" ,CMD_LST  );        // FTP処理の方法を指定します。
549                        String localFile        = arg.getProparty( "localFile"  );                                      // ローカルのファイル名
550                        String remoteFile       = arg.getProparty( "remoteFile" );                                      // FTP先のファイル名
551
552                        // command , localFile , remoteFile を元に、SFTP処理を行います。
553                        ftp.action( command,localFile,remoteFile );
554                }
555                catch( RuntimeException ex ) {
556                        System.err.println( ftp.getErrMsg() );
557                }
558                finally {
559                        // ホストとの接続を終了します。
560                        ftp.disconnect();
561                }
562        }
563}