org.pentaho.di.job.entries.ftpsget.FTPSConnection.java Source code

Java tutorial

Introduction

Here is the source code for org.pentaho.di.job.entries.ftpsget.FTPSConnection.java

Source

/*! ******************************************************************************
 *
 * Pentaho Data Integration
 *
 * Copyright (C) 2002-2013 by Pentaho : http://www.pentaho.com
 *
 *******************************************************************************
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 ******************************************************************************/

package org.pentaho.di.job.entries.ftpsget;

import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;

import org.apache.commons.vfs.FileObject;
import org.ftp4che.FTPConnection;
import org.ftp4che.FTPConnectionFactory;
import org.ftp4che.event.FTPEvent;
import org.ftp4che.event.FTPListener;
import org.ftp4che.util.ftpfile.FTPFile;
import org.pentaho.di.core.Const;
import org.pentaho.di.core.exception.KettleException;
import org.pentaho.di.core.vfs.KettleVFS;
import org.pentaho.di.i18n.BaseMessages;

public class FTPSConnection implements FTPListener {

    private static Class<?> PKG = JobEntryFTPSGet.class; // for i18n purposes, needed by Translator2!!

    public static final String HOME_FOLDER = "/";
    public static final String COMMAND_SUCCESSUL = "COMMAND SUCCESSFUL";

    public static final int CONNECTION_TYPE_FTP = 0;
    public static final int CONNECTION_TYPE_FTP_IMPLICIT_SSL = 1;
    public static final int CONNECTION_TYPE_FTP_AUTH_SSL = 2;
    public static final int CONNECTION_TYPE_FTP_IMPLICIT_SSL_WITH_CRYPTED = 3;
    public static final int CONNECTION_TYPE_FTP_AUTH_TLS = 4;
    public static final int CONNECTION_TYPE_FTP_IMPLICIT_TLS = 5;
    public static final int CONNECTION_TYPE_FTP_IMPLICIT_TLS_WITH_CRYPTED = 6;

    public static final String[] connection_type_Desc = new String[] {
            BaseMessages.getString(PKG, "JobFTPS.ConnectionType.FTP"),
            BaseMessages.getString(PKG, "JobFTPS.ConnectionType.ImplicitSSL"),
            BaseMessages.getString(PKG, "JobFTPS.ConnectionType.AuthSSL"),
            BaseMessages.getString(PKG, "JobFTPS.ConnectionType.ImplicitSSLCrypted"),
            BaseMessages.getString(PKG, "JobFTPS.ConnectionType.AuthTLS"),
            BaseMessages.getString(PKG, "JobFTPS.ConnectionType.ImplicitTLS"),
            BaseMessages.getString(PKG, "JobFTPS.ConnectionType.ImplicitTLSCrypted") };

    public static final String[] connection_type_Code = new String[] { "FTP_CONNECTION",
            "IMPLICIT_SSL_FTP_CONNECTION", "AUTH_SSL_FTP_CONNECTION",
            "IMPLICIT_SSL_WITH_CRYPTED_DATA_FTP_CONNECTION", "AUTH_TLS_FTP_CONNECTION",
            "IMPLICIT_TLS_FTP_CONNECTION", "IMPLICIT_TLS_WITH_CRYPTED_DATA_FTP_CONNECTION" };

    private FTPConnection connection = null;
    private ArrayList<String> replies = new ArrayList<String>();

    private String hostName;
    private int portNumber;
    private String userName;
    private String passWord;
    private int connectionType;
    private int timeOut;
    private boolean passiveMode;

    private String proxyHost;
    private String proxyUser;
    private String proxyPassword;
    private int proxyPort;

    public FTPSConnection(int connectionType, String hostname, int port, String username, String password) {
        this.hostName = hostname;
        this.portNumber = port;
        this.userName = username;
        this.passWord = password;
        this.connectionType = connectionType;
        this.passiveMode = false;
    }

    /**
     *
     * this method is used to set the proxy host
     *
     * @param type
     *          true: proxy host
     */
    public void setProxyHost(String proxyhost) {
        this.proxyHost = proxyhost;
    }

    /**
     *
     * this method is used to set the proxy port
     *
     * @param type
     *          true: proxy port
     */
    public void setProxyPort(int proxyport) {
        this.proxyPort = proxyport;
    }

    /**
     *
     * this method is used to set the proxy username
     *
     * @param type
     *          true: proxy username
     */
    public void setProxyUser(String username) {
        this.proxyUser = username;
    }

    /**
     *
     * this method is used to set the proxy password
     *
     * @param type
     *          true: proxy password
     */
    public void setProxyPassword(String password) {
        this.proxyPassword = password;
    }

    /**
     *
     * this method is used to connect to a remote host
     *
     * @throws KettleException
     */
    public void connect() throws KettleException {
        try {
            connection = FTPConnectionFactory.getInstance(
                    getProperties(hostName, portNumber, userName, passWord, connectionType, timeOut, passiveMode));
            connection.addFTPStatusListener(this);
            connection.connect();
        } catch (Exception e) {
            throw new KettleException(BaseMessages.getString(PKG, "JobFTPS.Error.Connecting", hostName), e);
        }
    }

    private Properties getProperties(String hostname, int port, String username, String password,
            int connectionType, int timeout, boolean passiveMode) {
        Properties pt = new Properties();
        pt.setProperty("connection.host", hostname);
        pt.setProperty("connection.port", String.valueOf(port));
        pt.setProperty("user.login", username);
        pt.setProperty("user.password", password);
        pt.setProperty("connection.type", getConnectionType(connectionType));
        pt.setProperty("connection.timeout", String.valueOf(timeout));
        pt.setProperty("connection.passive", String.valueOf(passiveMode));
        // Set proxy
        if (this.proxyHost != null) {
            pt.setProperty("proxy.host", this.proxyHost);
        }
        if (this.proxyPort != 0) {
            pt.setProperty("proxy.port", String.valueOf(this.proxyPort));
        }
        if (this.proxyUser != null) {
            pt.setProperty("proxy.user", this.proxyUser);
        }
        if (this.proxyPassword != null) {
            pt.setProperty("proxy.pass", this.proxyPassword);
        }

        return pt;
    }

    public static String getConnectionTypeDesc(String tt) {
        if (Const.isEmpty(tt)) {
            return connection_type_Desc[0];
        }
        if (tt.equalsIgnoreCase(connection_type_Code[1])) {
            return connection_type_Desc[1];
        } else {
            return connection_type_Desc[0];
        }
    }

    public static String getConnectionTypeCode(String tt) {
        if (tt == null) {
            return connection_type_Code[0];
        }
        if (tt.equals(connection_type_Desc[1])) {
            return connection_type_Code[1];
        } else {
            return connection_type_Code[0];
        }
    }

    public static String getConnectionTypeDesc(int i) {
        if (i < 0 || i >= connection_type_Desc.length) {
            return connection_type_Desc[0];
        }
        return connection_type_Desc[i];
    }

    public static String getConnectionType(int i) {
        return connection_type_Code[i];
    }

    public static int getConnectionTypeByDesc(String tt) {
        if (tt == null) {
            return 0;
        }

        for (int i = 0; i < connection_type_Desc.length; i++) {
            if (connection_type_Desc[i].equalsIgnoreCase(tt)) {
                return i;
            }
        }
        // If this fails,return the first value
        return 0;
    }

    public static int getConnectionTypeByCode(String tt) {
        if (tt == null) {
            return 0;
        }

        for (int i = 0; i < connection_type_Code.length; i++) {
            if (connection_type_Code[i].equalsIgnoreCase(tt)) {
                return i;
            }
        }
        return 0;
    }

    public static String getConnectionTypeCode(int i) {
        if (i < 0 || i >= connection_type_Code.length) {
            return connection_type_Code[0];
        }
        return connection_type_Code[i];
    }

    /**
     * public void setBinaryMode(boolean type)
     *
     * this method is used to set the transfer type to binary
     *
     * @param type
     *          true: Binary
     * @throws KettleException
     */
    public void setBinaryMode(boolean type) throws KettleException {
        try {
            connection.setTransferType(true);
        } catch (Exception e) {
            throw new KettleException(e);
        }
    }

    /**
     *
     * this method is used to set the mode to passive
     *
     * @param type
     *          true: passive mode
     */
    public void setPassiveMode(boolean passivemode) {
        this.passiveMode = passivemode;
    }

    /**
     *
     * this method is used to return the passive mode
     *
     * @return TRUE if we use passive mode
     *
     */
    public boolean isPassiveMode() {
        return this.passiveMode;
    }

    /**
     *
     * this method is used to set the timeout
     *
     * @param timeout
     *
     */
    public void setTimeOut(int timeout) {
        this.timeOut = timeout;
    }

    /**
     *
     * this method is used to return the timeout
     *
     * @return timeout
     *
     */
    public int getTimeOut() {
        return this.timeOut;
    }

    public String getUserName() {
        return userName;
    }

    public String getHostName() {
        return hostName;
    }

    public ArrayList<String> getReplies() {
        return replies;
    }

    /**
     *
     * this method is used to set the connection type
     *
     * @param type
     *          true: connection type
     */
    public void setConnectionType(int connectiontype) {
        this.connectionType = connectiontype;
    }

    public int getConnectionType() {
        return this.connectionType;
    }

    public void connectionStatusChanged(FTPEvent arg0) {
    }

    public void replyMessageArrived(FTPEvent event) {
        this.replies = new ArrayList<String>();
        for (String e : event.getReply().getLines()) {
            if (!e.trim().equals("")) {
                e = e.substring(3).trim().replace("\n", "");
                if (!e.toUpperCase().contains(COMMAND_SUCCESSUL)) {
                    e = e.substring(1).trim();
                    replies.add(e);
                }
            }
        }
    }

    /**
     *
     * this method change FTP working directory
     *
     * @param directory
     *          change the working directory
     * @throws KettleException
     */
    public void changeDirectory(String directory) throws KettleException {
        try {
            this.connection.changeDirectory(directory);
        } catch (Exception f) {
            throw new KettleException(BaseMessages.getString(PKG, "JobFTPS.Error.ChangingFolder", directory), f);
        }
    }

    /**
     *
     * this method is used to create a directory in remote host
     *
     * @param directory
     *          directory name on remote host
     * @throws KettleException
     */
    public void createDirectory(String directory) throws KettleException {
        try {
            this.connection.makeDirectory(directory);
        } catch (Exception f) {
            throw new KettleException(BaseMessages.getString(PKG, "JobFTPS.Error.CreationFolder", directory), f);
        }
    }

    public List<FTPFile> getFileList(String folder) throws KettleException {
        try {
            if (connection != null) {
                List<FTPFile> response = connection.getDirectoryListing(folder);
                return response;
            } else {
                return null;
            }
        } catch (Exception e) {
            throw new KettleException(e);
        }
    }

    /**
     *
     * this method is used to download a file from a remote host
     *
     * @param file
     *          remote file to download
     * @param localFilename
     *          target filename in local host
     * @throws KettleException
     */
    public void downloadFile(FTPFile file, String localFilename) throws KettleException {
        try {
            File localFile = new File(localFilename);
            writeToFile(connection.downloadStream(file), localFile);
        } catch (Exception e) {
            throw new KettleException(e);
        }
    }

    private void writeToFile(InputStream is, File file) throws KettleException {
        try {
            DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file)));
            int c;
            while ((c = is.read()) != -1) {
                out.writeByte(c);
            }
            is.close();
            out.close();
        } catch (IOException e) {
            throw new KettleException(BaseMessages.getString(PKG, "JobFTPS.Error.WritingToFile", file.getName()),
                    e);
        }
    }

    /**
     *
     * this method is used to upload a file to a remote host
     *
     * @param localFileName
     *          Local full filename
     * @param shortFileName
     *          Filename in remote host
     * @throws KettleException
     */
    public void uploadFile(String localFileName, String shortFileName) throws KettleException {
        FileObject file = null;

        try {
            file = KettleVFS.getFileObject(localFileName);
            this.connection.uploadStream(file.getContent().getInputStream(), new FTPFile(new File(shortFileName)));
        } catch (Exception e) {
            throw new KettleException(BaseMessages.getString(PKG, "JobFTPS.Error.UuploadingFile", localFileName),
                    e);
        } finally {
            if (file != null) {
                try {
                    file.close();
                } catch (Exception e) {
                    // Ignore close errors
                }
            }
        }
    }

    /**
     *
     * this method is used to return filenames in working directory
     *
     * @return filenames
     * @throws KettleException
     */
    public String[] getFileNames() throws KettleException {
        ArrayList<String> list = null;
        try {
            List<FTPFile> fileList = getFileList(getWorkingDirectory());
            list = new ArrayList<String>();
            Iterator<FTPFile> it = fileList.iterator();
            while (it.hasNext()) {
                FTPFile file = it.next();
                if (!file.isDirectory()) {
                    list.add(file.getName());
                }
            }
        } catch (Exception e) {
            throw new KettleException(BaseMessages.getString(PKG, "JobFTPS.Error.RetrievingFilenames"), e);
        }
        return list == null ? null : list.toArray(new String[list.size()]);
    }

    /**
     *
     * this method is used to delete a file in remote host
     *
     * @param file
     *          File on remote host to delete
     * @throws KettleException
     */
    public void deleteFile(FTPFile file) throws KettleException {
        try {
            this.connection.deleteFile(file);
        } catch (Exception e) {
            throw new KettleException(BaseMessages.getString(PKG, "JobFTPS.Error.DeletingFile", file.getName()), e);
        }
    }

    /**
     *
     * this method is used to delete a file in remote host
     *
     * @param filename
     *          Name of file on remote host to delete
     * @throws KettleException
     */
    public void deleteFile(String filename) throws KettleException {
        try {
            this.connection.deleteFile(new FTPFile(getWorkingDirectory(), filename));
        } catch (Exception e) {
            throw new KettleException(BaseMessages.getString(PKG, "JobFTPS.Error.DeletingFile", filename), e);
        }
    }

    /**
     *
     * this method is used to move a file to remote directory
     *
     * @param fromFile
     *          File on remote host to move
     * @param targetFoldername
     *          Target remote folder
     * @throws KettleException
     */
    public void moveToFolder(FTPFile fromFile, String targetFoldername) throws KettleException {
        try {
            this.connection.renameFile(fromFile, new FTPFile(targetFoldername, fromFile.getName()));
        } catch (Exception e) {
            throw new KettleException(BaseMessages.getString(PKG, "JobFTPS.Error.MovingFileToFolder",
                    fromFile.getName(), targetFoldername), e);
        }
    }

    /**
     *
     * Checks if a directory exists
     *
     * @return true if the directory exists
     *
     */
    public boolean isDirectoryExists(String directory) {
        String currectDirectory = null;
        boolean retval = false;
        try {
            // Before save current directory
            currectDirectory = this.connection.getWorkDirectory();
            // Change directory
            this.connection.changeDirectory(directory);
            retval = true;
        } catch (Exception e) {
            // Ignore directory change errors
        } finally {
            // switch back to the current directory
            if (currectDirectory != null) {
                try {
                    this.connection.changeDirectory(currectDirectory);
                } catch (Exception e) {
                    // Ignore directory change errors
                }
            }
        }
        return retval;
    }

    /**
     *
     * Checks if a file exists on remote host
     *
     * @param filename
     *          the name of the file to check
     * @return true if the file exists
     *
     */
    public boolean isFileExists(String filename) {
        boolean retval = false;
        try {
            FTPFile file = new FTPFile(new File(filename));
            // Get modification time just to check if file exists
            connection.getModificationTime(file);
            retval = true;
        } catch (Exception e) {
            // Ignore errors
        }
        return retval;
    }

    /**
     *
     * Returns the working directory
     *
     * @return working directory
     * @throws Exception
     */
    public String getWorkingDirectory() throws Exception {
        return this.connection.getWorkDirectory();
    }

    /**
     *
     * this method is used to disconnect the connection
     *
     */
    public void disconnect() {
        if (this.connection != null) {
            this.connection.disconnect();
        }
        if (this.replies != null) {
            this.replies.clear();
        }
    }

}