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.util;
017    
018    import java.io.FileInputStream;
019    import java.io.FileOutputStream;
020    import java.io.InputStream;
021    import java.io.OutputStream;
022    import java.io.PrintWriter;
023    import java.io.IOException;
024    import java.util.Map;
025    import java.util.LinkedHashMap ;
026    
027    import org.apache.commons.net.ftp.FTP;
028    import org.apache.commons.net.ftp.FTPClient;
029    import org.apache.commons.net.ftp.FTPFile;
030    import org.apache.commons.net.PrintCommandListener;
031    import 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     */
099    public 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             * ケースã§ã¯ã€æœ€åˆã«?‘度ã?‘呼ã³å‡ºã™ã ã‘ã§ã™ã?
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 [ç§’])ã€?TPClient ã®ãƒ¡ã‚½ãƒ?ƒ‰ã«ã¯ã€ãƒŸãƒªç§’ã§ã‚»ãƒ?ƒˆã—ã¾ã™ã?
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;     // 区åˆ?‚Šæ–?­—ã‚’?‹ï¼‘ã™ã‚‹ã?
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    }