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