001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.servicemix.ftp;
018    
019    import java.io.IOException;
020    
021    import org.apache.commons.net.SocketClient;
022    import org.apache.commons.net.ftp.FTP;
023    import org.apache.commons.net.ftp.FTPClient;
024    import org.apache.commons.net.ftp.FTPClientConfig;
025    import org.apache.commons.net.ftp.FTPReply;
026    
027    /**
028     * A pool of FTP clients for
029     * the <a href="http://jakarta.apache.org/commons/net.html">Jakarta Commons Net</a> library
030     *
031     * @version $Revision: 426415 $
032     * @org.apache.xbean.XBean element="pool"
033     */
034    public class FTPClientPool extends SocketClientPoolSupport {
035    
036        public static final int DEFAULT_DATA_TIMEOUT = 120000; // two minutes
037        public static final String DEFAULT_CONTROL_ENCODING = FTP.DEFAULT_CONTROL_ENCODING;
038    
039        private String username;
040        private String password;
041        private boolean binaryMode = true;
042        private boolean passiveMode;
043        private FTPClientConfig config;
044        private String controlEncoding = DEFAULT_CONTROL_ENCODING;
045        private int dataTimeout = DEFAULT_DATA_TIMEOUT;
046    
047        public boolean validateObject(Object object) {
048            FTPClient client = (FTPClient) object;
049            try {
050                return client.sendNoOp();
051            } catch (IOException e) {
052                throw new RuntimeException("Failed to validate client: " + e, e);
053            }
054        }
055    
056        public void activateObject(Object object) throws Exception {
057            FTPClient client = (FTPClient) object;
058            client.setReaderThread(true);
059        }
060    
061        public void passivateObject(Object object) throws Exception {
062            FTPClient client = (FTPClient) object;
063            client.setReaderThread(false);
064        }
065    
066        // Properties
067        //-------------------------------------------------------------------------
068        public String getUsername() {
069            return username;
070        }
071    
072        public void setUsername(String username) {
073            this.username = username;
074        }
075    
076        public String getPassword() {
077            return password;
078        }
079    
080        public void setPassword(String password) {
081            this.password = password;
082        }
083    
084        public boolean isBinaryMode() {
085            return binaryMode;
086        }
087    
088        public void setBinaryMode(boolean binaryMode) {
089            this.binaryMode = binaryMode;
090        }
091    
092        /**
093         * @return the passiveMode
094         */
095        public boolean isPassiveMode() {
096            return passiveMode;
097        }
098    
099        /**
100         * @param passiveMode the passiveMode to set
101         */
102        public void setPassiveMode(boolean passiveMode) {
103            this.passiveMode = passiveMode;
104        }
105    
106        public FTPClientConfig getConfig() {
107            return config;
108        }
109    
110        public void setConfig(FTPClientConfig config) {
111            this.config = config;
112        }
113    
114        /**
115         * @return the controlEncoding
116         */
117        public String getControlEncoding() {
118            return controlEncoding;
119        }
120    
121        /**
122         * @param controlEncoding the controlEncoding to set
123         */
124        public void setControlEncoding(String controlEncoding) {
125            this.controlEncoding = controlEncoding;
126        }
127    
128        /**
129         * @return the dataTimeout
130         */
131        public int getDataTimeout() {
132            return dataTimeout;
133        }
134    
135        /**
136         * @param dataTimeout the dataTimeout to set
137         */
138        public void setDataTimeout(int dataTimeout) {
139            this.dataTimeout = dataTimeout;
140        }
141    
142        // Implementation methods
143        //-------------------------------------------------------------------------
144        protected void connect(SocketClient client) throws Exception {
145            FTPClient ftp = (FTPClient) client;
146    
147            if (config != null) {
148                ftp.configure(config);
149            }
150            ftp.setControlEncoding(getControlEncoding());
151    
152            super.connect(ftp);
153            ftp.setDataTimeout(getDataTimeout());
154    
155            int code = ftp.getReplyCode();
156            if (!FTPReply.isPositiveCompletion(code)) {
157                ftp.disconnect();
158                throw new ConnectionRefusedException(code);
159            }
160            if (!ftp.login(getUsername(), getPassword())) {
161                ftp.disconnect();
162                throw new ConnectionRefusedException(ftp.getReplyCode());
163            }
164            if (isBinaryMode()) {
165                ftp.setFileType(FTP.BINARY_FILE_TYPE);
166            }
167            if (isPassiveMode()) {
168                ftp.enterLocalPassiveMode();
169            }
170        }
171    
172        protected void disconnect(SocketClient client) throws Exception {
173            FTPClient ftp = (FTPClient) client;
174            if (ftp.isConnected()) {
175                ftp.logout();
176            }
177            super.disconnect(client);
178        }
179    
180        protected SocketClient createSocketClient() {
181            return new FTPClient();
182        }
183    }