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.camel.component.file.remote;
018    
019    import java.io.IOException;
020    
021    import org.apache.commons.logging.Log;
022    import org.apache.commons.logging.LogFactory;
023    import org.apache.commons.net.ftp.FTPClient;
024    
025    /**
026     * Utility methods for FTP.
027     */
028    public final class FtpUtils {
029        private static final transient Log LOG = LogFactory.getLog(FtpUtils.class);
030    
031        private FtpUtils() {
032        }
033    
034        public static boolean connect(FTPClient client, RemoteFileConfiguration config) throws IOException {
035            String host = config.getHost();
036            int port = config.getPort();
037            String username = config.getUsername();
038    
039            if (config.getFtpClientConfig() != null) {
040                LOG.trace("Configuring FTPClient with config: " + config.getFtpClientConfig());
041                client.configure(config.getFtpClientConfig());
042            }
043    
044            LOG.trace("Connecting to " + config);
045            client.connect(host, port);
046    
047            // must enter passive mode directly after connect
048            if (config.isPassiveMode()) {
049                LOG.trace("Using passive mode connections");
050                client.enterLocalPassiveMode();
051            }
052    
053            boolean login;
054            if (username != null) {
055                LOG.trace("Attempting to login user: " + username);
056                login = client.login(username, config.getPassword());
057            } else {
058                LOG.trace("Attempting to login anonymous");
059                login = client.login("anonymous", null);
060            }
061            if (LOG.isTraceEnabled()) {
062                LOG.trace("User " + (username != null ? username : "anonymous") + " logged in: " + login);
063            }
064            if (!login) {
065                return false;
066            }
067    
068            client.setFileType(config.isBinary() ? FTPClient.BINARY_FILE_TYPE : FTPClient.ASCII_FILE_TYPE);
069            return true;
070        }
071    
072        public static void disconnect(FTPClient client) throws IOException {
073            if (client.isConnected()) {
074                client.disconnect();
075            }
076        }
077    
078        public static FTPClient createNewFtpClient() {
079            return new FTPClient();
080        }
081    
082        public static boolean buildDirectory(FTPClient ftpClient, String dirName) throws IOException {
083            String originalDirectory = ftpClient.printWorkingDirectory();
084    
085            boolean success = false;
086            try {
087                // maybe the full directory already exsits
088                success = ftpClient.changeWorkingDirectory(dirName);
089                if (!success) {
090                    if (LOG.isTraceEnabled()) {
091                        LOG.trace("Trying to build remote directory: " + dirName);
092                    }
093                    success = ftpClient.makeDirectory(dirName);
094                    if (!success) {
095                        // we are here if the server side doesn't create intermediate folders
096                        // so create the folder one by one
097                        buildDirectoryChunks(ftpClient, dirName);
098                    }
099                }
100            } finally {
101                // change back to original directory
102                ftpClient.changeWorkingDirectory(originalDirectory);
103            }
104    
105            return success;
106        }
107    
108        public static boolean buildDirectoryChunks(FTPClient ftpClient, String dirName) throws IOException {
109            final StringBuilder sb = new StringBuilder(dirName.length());
110            final String[] dirs = dirName.split("\\/");
111    
112            boolean success = false;
113            for (String dir : dirs) {
114                sb.append(dir).append('/');
115                String directory = sb.toString();
116                if (LOG.isTraceEnabled()) {
117                    LOG.trace("Trying to build remote directory: " + directory);
118                }
119    
120                success = ftpClient.makeDirectory(directory);
121            }
122    
123            return success;
124        }
125    
126    }