org.waarp.ftp.client.WaarpFtpClient.java Source code

Java tutorial

Introduction

Here is the source code for org.waarp.ftp.client.WaarpFtpClient.java

Source

/**
 * This file is part of Waarp Project.
 * 
 * Copyright 2009, Frederic Bregier, and individual contributors by the @author tags. See the
 * COPYRIGHT.txt in the distribution for a full listing of individual contributors.
 * 
 * All Waarp Project is free software: you can redistribute it and/or modify it under the terms of
 * the GNU General Public License as published by the Free Software Foundation, either version 3 of
 * the License, or (at your option) any later version.
 * 
 * Waarp is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
 * Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along with Waarp . If not, see
 * <http://www.gnu.org/licenses/>.
 */
package org.waarp.ftp.client;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.SocketException;

import org.apache.commons.net.PrintCommandListener;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.commons.net.ftp.FTPSClient;
import org.apache.commons.net.util.TrustManagerUtils;
import org.waarp.common.logging.WaarpLogger;
import org.waarp.common.logging.WaarpLoggerFactory;

/**
 * FTP Client using Apache Commons net FTP client (not working using FTPS or FTPSE)
 * 
 * @author "Frederic Bregier"
 * 
 */
public class WaarpFtpClient {
    /**
     * Internal Logger
     */
    private static final WaarpLogger logger = WaarpLoggerFactory.getLogger(WaarpFtpClient.class);

    String server = null;
    int port = 21;
    String user = null;
    String pwd = null;
    String acct = null;
    int timeout;
    boolean isPassive = false;
    int ssl = 0; // -1 native, 1 auth
    protected FTPClient ftpClient = null;
    protected String result = null;
    private boolean binaryTransfer = true;

    /**
     * WARNING: SSL mode (FTPS and FTPSE) are not working due to a bug in Apache Commons-Net
     * 
     * @param server
     * @param port
     * @param user
     * @param pwd
     * @param acct
     * @param isPassive
     * @param ssl
     * @param timeout
     */
    public WaarpFtpClient(String server, int port, String user, String pwd, String acct, boolean isPassive, int ssl,
            int controlTimeout, int timeout) {
        this.server = server;
        this.port = port;
        this.user = user;
        this.pwd = pwd;
        this.acct = acct;
        this.isPassive = isPassive;
        this.ssl = ssl;
        if (this.ssl != 0) {
            // implicit or explicit
            this.ftpClient = new FTPSClient(this.ssl == -1);
            ((FTPSClient) this.ftpClient).setTrustManager(TrustManagerUtils.getAcceptAllTrustManager());
        } else {
            this.ftpClient = new FTPClient();
        }
        if (controlTimeout > 0) {
            this.ftpClient.setControlKeepAliveTimeout(controlTimeout / 1000);
            this.ftpClient.setControlKeepAliveReplyTimeout(controlTimeout);
        }
        if (timeout > 0) {
            this.ftpClient.setDataTimeout(timeout);
        }
        this.ftpClient.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out), true));
    }

    /**
     * Try to connect to the server and goes with the authentication
     * 
     * @return True if connected and authenticated, else False
     */
    public boolean connect() {
        result = null;
        boolean isActive = false;
        try {
            try {
                this.ftpClient.connect(this.server, this.port);
            } catch (SocketException e) {
                result = "Connection in error";
                logger.error(result, e);
                return false;
            } catch (IOException e) {
                result = "Connection in error";
                logger.error(result, e);
                return false;
            }
            int reply = this.ftpClient.getReplyCode();
            if (!FTPReply.isPositiveCompletion(reply)) {
                this.disconnect();
                result = "Connection in error: " + reply;
                logger.error(result);
                return false;
            }
            try {
                if (this.acct == null) {
                    // no account
                    if (!this.ftpClient.login(this.user, this.pwd)) {
                        this.logout();
                        result = "Login in error";
                        logger.error(result);
                        return false;
                    }
                } else if (!this.ftpClient.login(this.user, this.pwd, this.acct)) {
                    this.logout();
                    result = "Login in error";
                    logger.error(result);
                    return false;
                }
            } catch (IOException e) {
                result = "Login in error";
                logger.error(result, e);
                return false;
            }
            try {
                this.ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
            } catch (IOException e1) {
                result = "Set BINARY in error";
                logger.error(result, e1);
                return false;
            }
            changeMode(isPassive);
            this.ftpClient.setUseEPSVwithIPv4(false);
            if (ssl == 1) {
                // now send request for PROT (AUTH already sent)
                try {
                    ((FTPSClient) this.ftpClient).execPBSZ(0);
                    logger.debug("PBSZ 0");
                    ((FTPSClient) this.ftpClient).execPROT("P");
                    logger.debug("Info: " + ((FTPSClient) this.ftpClient).getEnableSessionCreation());
                } catch (IOException e) {
                    this.logout();
                    result = "Explicit SSL in error";
                    logger.error(result, e);
                    return false;
                }
            }
            isActive = true;
            return true;
        } finally {
            if ((!isActive)
                    && this.ftpClient.getDataConnectionMode() == FTPClient.ACTIVE_LOCAL_DATA_CONNECTION_MODE) {
                this.disconnect();
            }
        }
    }

    /**
     * Logout from the Control connection
     */
    public void logout() {
        try {
            this.ftpClient.logout();
        } catch (IOException e) {
            if (this.ftpClient.getDataConnectionMode() == FTPClient.ACTIVE_LOCAL_DATA_CONNECTION_MODE) {
                try {
                    this.ftpClient.disconnect();
                } catch (IOException f) {
                    // do nothing
                }
            }
        }
    }

    /**
     * Disconnect the Ftp Client
     */
    public void disconnect() {
        try {
            this.ftpClient.disconnect();
        } catch (IOException e) {
            logger.debug("Disconnection in error", e);
        }
    }

    /**
     * Create a new directory
     * 
     * @param newDir
     * @return True if created
     */
    public boolean makeDir(String newDir) {
        result = null;
        try {
            return this.ftpClient.makeDirectory(newDir);
        } catch (IOException e) {
            result = "MKDIR in error";
            logger.info(result, e);
            return false;
        }
    }

    /**
     * Change remote directory
     * 
     * @param newDir
     * @return True if the change is OK
     */
    public boolean changeDir(String newDir) {
        result = null;
        try {
            return this.ftpClient.changeWorkingDirectory(newDir);
        } catch (IOException e) {
            result = "CHDIR in error";
            logger.info(result, e);
            return false;
        }
    }

    /**
     * Change the FileType of Transfer (Binary true, ASCII false)
     * 
     * @param binaryTransfer1
     * @return True if the change is OK
     */
    public boolean changeFileType(boolean binaryTransfer1) {
        result = null;
        this.binaryTransfer = binaryTransfer1;
        try {
            if (this.binaryTransfer) {
                return this.ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
            } else {
                return this.ftpClient.setFileType(FTP.ASCII_FILE_TYPE);
            }
        } catch (IOException e) {
            result = "FileType in error";
            logger.warn(result, e);
            return false;
        }
    }

    /**
     * Change to passive (true) or active (false) mode
     * 
     * @param passive
     */
    public void changeMode(boolean passive) {
        this.isPassive = passive;
        if (this.isPassive) {
            this.ftpClient.enterLocalPassiveMode();
        } else {
            this.ftpClient.enterLocalActiveMode();
        }
    }

    /**
     * Ask to transfer a file
     * 
     * @param local
     *            local filepath (limited to path if get, else full path)
     * @param remote
     *            filename
     * @param getStoreOrAppend
     *            -1 = get, 1 = store, 2 = append
     * @return True if the file is correctly transfered
     */
    public boolean transferFile(String local, String remote, int getStoreOrAppend) {
        result = null;
        boolean status = false;
        FileOutputStream output = null;
        FileInputStream fileInputStream = null;
        try {
            if (getStoreOrAppend > 0) {
                fileInputStream = new FileInputStream(local);
                if (getStoreOrAppend == 1) {
                    status = this.ftpClient.storeFile(remote, fileInputStream);
                } else {
                    // append
                    status = this.ftpClient.appendFile(remote, fileInputStream);
                }
                fileInputStream.close();
                fileInputStream = null;
                if (!status) {
                    result = "Cannot finalize store like operation";
                    logger.error(result);
                    return false;
                }
                if (!this.ftpClient.completePendingCommand()) {
                    result = "Cannot finalize store like operation";
                    logger.error(result);
                    return false;
                }
                return true;
            } else {
                output = new FileOutputStream(new File(local, remote));
                status = this.ftpClient.retrieveFile(remote, output);
                output.flush();
                output.close();
                output = null;
                if (!status) {
                    result = "Cannot finalize retrieve like operation";
                    logger.error(result);
                    return false;
                }
                if (!this.ftpClient.completePendingCommand()) {
                    result = "Cannot finalize retrieve like operation";
                    logger.error(result);
                    return false;
                }
                return true;
            }
        } catch (IOException e) {
            if (output != null)
                try {
                    output.close();
                } catch (IOException e1) {
                }
            if (fileInputStream != null)
                try {
                    fileInputStream.close();
                } catch (IOException e1) {
                }
            result = "Cannot finalize operation";
            logger.error(result, e);
            return false;
        }
    }

    /**
     * 
     * @return the list of files as returned by the FTP command
     */
    public String[] listFiles() {
        try {
            FTPFile[] list = this.ftpClient.listFiles();
            String[] results = new String[list.length];
            int i = 0;
            for (FTPFile file : list) {
                results[i] = file.toFormattedString();
                i++;
            }
            return results;
        } catch (IOException e) {
            result = "Cannot finalize transfer operation";
            logger.error(result, e);
            return null;
        }
    }

    /**
     * 
     * @param feature
     * @return True if the feature is listed
     */
    public boolean featureEnabled(String feature) {
        try {
            System.err.println(this.ftpClient.features());
            if (this.ftpClient.featureValue(feature) == null) {
                String result = this.ftpClient.getReplyString();
                return (result.contains(feature.toUpperCase()));
            }
            return true;
        } catch (IOException e) {
            result = "Cannot execute operation Feature";
            logger.error(result, e);
            return false;
        }
    }

    /**
     * 
     * @param params
     * @return the string lines returned by the command params
     */
    public String[] executeCommand(String params) {
        result = null;
        try {
            System.err.println(params);
            int pos = params.indexOf(' ');
            String command = params;
            String args = null;
            if (pos > 0) {
                command = params.substring(0, pos);
                args = params.substring(pos + 1);
            }
            String[] results = this.ftpClient.doCommandAsStrings(command, args);
            if (results == null) {
                results = new String[1];
                results[0] = this.ftpClient.getReplyString();
            }
            return results;
        } catch (IOException e) {
            result = "Cannot execute operation Site";
            logger.error(result, e);
            return null;
        }
    }

    /**
     * 
     * @param params
     * @return the string lines returned by the SITE command params
     */
    public String[] executeSiteCommand(String params) {
        result = null;
        try {
            System.err.println("SITE " + params);
            String[] results = this.ftpClient.doCommandAsStrings("SITE", params);
            if (results == null) {
                results = new String[1];
                results[0] = this.ftpClient.getReplyString();
            }
            return results;
        } catch (IOException e) {
            result = "Cannot execute operation Site";
            logger.error(result, e);
            return null;
        }
    }

}