Package org.jboss.internal.soa.esb.util

Source Code of org.jboss.internal.soa.esb.util.FtpImpl

/*
* JBoss, Home of Professional Open Source
* Copyright 2006, JBoss Inc., and individual contributors as indicated
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.internal.soa.esb.util;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.net.URISyntaxException;

import org.apache.log4j.Logger;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.jboss.soa.esb.ConfigurationException;
import org.jboss.soa.esb.addressing.eprs.FTPEpr;
import org.jboss.soa.esb.addressing.eprs.FileEpr;
import org.jboss.soa.esb.common.Environment;
import org.jboss.soa.esb.common.ModulePropertyManager;
import org.jboss.soa.esb.helpers.ConfigTree;
import org.jboss.soa.esb.util.FileUtil;
import org.jboss.soa.esb.util.FtpClientUtil;
import org.jboss.soa.esb.util.RemoteFileSystem;
import org.jboss.soa.esb.util.RemoteFileSystemException;
import org.picketlink.identity.federation.api.openid.OpenIDManager.CONST;

/**
* Simplified FTP transfers
* <p>
* Description: Implements a simple set of FTP functionality Parameters to
* establish the FTP connection are provided at construction time and cannot
* change during the lifetime of the object <br/>Hides low level details.
* </p>
*/
public class FtpImpl implements RemoteFileSystem
{
    private static Logger logger = Logger.getLogger(FtpImpl.class);
        private static final String TMP_SUFFIX = ".rosettaPart";

        private boolean m_bPassive;

        private int m_iPort;
       
        private int m_iTimeoutDefault, m_iTimeoutData, m_iTimeoutSo;

        protected FTPClient m_oConn ;

        private FTPEpr m_oEpr;

        protected ConfigTree m_oParms;

        private String m_sFtpServer, m_sUser, m_sPasswd;

        private String m_sRemoteDir, m_sLocalDir;
       
        private int m_iRenameRetry;
       
        private String m_ControlChannelEncoding;
       
        // package-protected since the only use is from FtpImplUnitTest
        FtpImpl (ConfigTree p_oP, boolean p_bConnect)
                        throws ConfigurationException, RemoteFileSystemException
        {
                m_oParms = p_oP;
                initialize(p_bConnect);
        }

        public FtpImpl (FTPEpr p_oP, boolean p_bConnect)
                        throws ConfigurationException, RemoteFileSystemException
        {
                this(p_oP) ;
               
                configTreeFromEpr() ;
               
                initialize(p_bConnect) ;
        }

        // protected since the only use is from "this" and FtpsImpl
        protected FtpImpl (FTPEpr p_oP)
                        throws ConfigurationException
        {
                m_oEpr = p_oP;

                final URI uri;
                try
                {
                        uri = m_oEpr.getURI();
                }
                catch (URISyntaxException e)
                {
                        throw new ConfigurationException(e);
                }

                m_sFtpServer = uri.getHost();

                String[] sa = null;

                if (uri.getUserInfo() != null)
                        sa = uri.getUserInfo().split(":");

                final int saLen = (sa == null ? 0 : sa.length) ;
                switch(saLen)
                {
                case 1:
                    m_sUser = sa[0] ;
                    break;
                case 2:
                    m_sUser = sa[0] ;
                  m_sPasswd = sa[1] ;
                }

                m_sRemoteDir = uri.getPath();

                if ((m_sRemoteDir == null) || (m_sRemoteDir.equals("")))
                        m_sRemoteDir = FtpUtils.getRemoteDir();

                m_iPort = uri.getPort();

                m_sLocalDir = FtpUtils.getLocalDir();

            File oLocalDir = new File(m_sLocalDir);
            if(!oLocalDir.exists()) {
                throw new ConfigurationException("Local FTP directory '" + oLocalDir.getAbsolutePath()
                        + "' doesn't exist.  Check your JBossESB config '"
                        + ModulePropertyManager.TRANSPORTS_MODULE + ":" + Environment.FTP_LOCALDIR + "'");
            }
   
            m_bPassive = m_oEpr.getPassive();
           
                m_iRenameRetry = FtpUtils.getRenameRetry();

                m_iTimeoutDefault = FtpUtils.getTimeoutDefault();
                m_iTimeoutData = FtpUtils.getTimeoutData();
                m_iTimeoutSo = FtpUtils.getTimeoutSo();   
                m_ControlChannelEncoding = m_oEpr.getControlChannelEncoding();
        }

        /**
         * Checks validity and completeness of parameters, and keeps the info
         * internally for subsequent FTP requests
         *
         * @throws ConfigurationException :
         *             if parameters are invalid or incomplete
         *             <li>Parameters: (XML attributes at the root level) </li>
         *             <li> ftpServer = name or IP of FTP server </li>
         *             <li> ftpUser = login ID for server </li>
         *             <li> ftpPassword </li>
         *             <li> localDirURI = absolute path in the local filesystem
         *             </li>
         *             <li> remoteDirURI = remote path is relative to ftp user home
         *             in remote computer </li>
         */
        protected void checkParms () throws ConfigurationException
        {
                String att = m_oParms.getAttribute(FileEpr.URL_TAG);
                URI uri = null;
               
                try
                {
                        if (att != null)
                                uri = new URI(att);
                }
                catch (URISyntaxException ex)
                {
                        throw new ConfigurationException(ex);
                }
               
                m_sFtpServer = (null != uri) ? uri.getHost() : m_oParms.getAttribute(PARMS_FTP_SERVER);
                if (null == m_sFtpServer) {
                  throw new ConfigurationException("No FTP server specified");
                }
               
                String[] sa = (null == uri) ? null : uri.getUserInfo().split(":");
                m_sUser = (null != sa) ? sa[0] : m_oParms.getAttribute(PARMS_USER);
                if (null == m_sUser) {
                  throw new ConfigurationException("No username specified for FTP");
                }

                m_sPasswd = ((null != sa) && (sa.length > 1)) ? sa[1] : m_oParms.getAttribute(PARMS_PASSWD);

                m_sRemoteDir = (null != uri) ? uri.getPath() : m_oParms.getAttribute(PARMS_REMOTE_DIR);
                if (null == m_sRemoteDir) m_sRemoteDir = "";

                m_sLocalDir = m_oParms.getAttribute(PARMS_LOCAL_DIR);
                if (null == m_sLocalDir) m_sLocalDir = ".";

                String sAux = m_oParms.getAttribute(PARMS_PORT);
                m_iPort = (null != uri) ? uri.getPort() : (null == sAux) ? 21 : Integer.parseInt(sAux);
               
                m_bPassive = false;
                sAux = m_oParms.getAttribute(PARMS_PASSIVE);
                m_bPassive = (null != sAux) && Boolean.parseBoolean(sAux);

                m_ControlChannelEncoding = null;
                String ccEncoding = m_oParms.getAttribute(RemoteFileSystem.PARMS_CONTROL_CHANNEL_ENCODING);
                m_ControlChannelEncoding = (null != ccEncoding) ? ccEncoding : m_ControlChannelEncoding;
               
                String sRenameRetry = m_oParms.getAttribute(PARMS_RENAME_RETRY);
                m_iRenameRetry = (null != sRenameRetry) ? Integer.parseInt(sRenameRetry) : FtpUtils.getRenameRetry();
               
                String sTimeoutDefault = m_oParms.getAttribute(PARMS_TIMEOUT_DEFAULT);
                m_iTimeoutDefault = (null != sTimeoutDefault) ? Integer.parseInt(sTimeoutDefault) : FtpUtils.getTimeoutDefault();
                String sTimeoutData = m_oParms.getAttribute(PARMS_TIMEOUT_DATA);
                m_iTimeoutData = (null != sTimeoutData) ? Integer.parseInt(sTimeoutData) : FtpUtils.getTimeoutData();
                String sTimeoutSo = m_oParms.getAttribute(PARMS_TIMEOUT_SO);
                m_iTimeoutSo = (null != sTimeoutSo) ? Integer.parseInt(sTimeoutSo) : FtpUtils.getTimeoutSo();
        }

        protected void configTreeFromEpr () throws RemoteFileSystemException
        {
                m_oParms = new ConfigTree("fromEpr");
                try
                {
                        m_oParms.setAttribute(PARMS_FTP_SERVER, m_sFtpServer);
                        m_oParms.setAttribute(PARMS_USER, m_sUser);
                        if (m_sPasswd != null)
                        {
                            m_oParms.setAttribute(PARMS_PASSWD, m_sPasswd);
                        }
                        m_oParms.setAttribute(PARMS_REMOTE_DIR, m_sRemoteDir);
                        if (m_iPort > 0)
                        {
                            m_oParms.setAttribute(PARMS_PORT, Integer.toString(m_iPort));
                        }
                        m_oParms.setAttribute(RemoteFileSystem.PARMS_CONTROL_CHANNEL_ENCODING, this.m_ControlChannelEncoding);
                        m_oParms.setAttribute(PARMS_LOCAL_DIR, m_sLocalDir);
                        m_oParms.setAttribute(PARMS_ASCII, Boolean.toString(false));
                        m_oParms.setAttribute(PARMS_PASSIVE, Boolean.toString(m_bPassive));
                        m_oParms.setAttribute(PARMS_RENAME_RETRY, Integer.toString(m_iRenameRetry));
                        m_oParms.setAttribute(PARMS_TIMEOUT_DEFAULT, Integer.toString(m_iTimeoutDefault));
                        m_oParms.setAttribute(PARMS_TIMEOUT_DATA, Integer.toString(m_iTimeoutData));
                        m_oParms.setAttribute(PARMS_TIMEOUT_SO, Integer.toString(m_iTimeoutSo));
                }
                catch (Exception e)
                {
                        throw new RemoteFileSystemException(e);
                }
        }

        /*
         * (non-Javadoc)
         *
         * @see org.jboss.soa.esb.util.RemoteFileSystem#deleteRemoteFile(java.lang.String)
         */
        public void deleteRemoteFile (String p_sFile) throws RemoteFileSystemException
        {
            try
            {
                changeRemoteDirectory() ;
                if (!m_oConn.deleteFile(p_sFile))
                {
                    throw new RemoteFileSystemException("Failed to delete remote file: " + m_oConn.getReplyString());
                }
            }
            catch (final IOException ioe)
            {
                throw new RemoteFileSystemException(ioe);
            }
        }

        /*
         * (non-Javadoc)
         *
         * @see org.jboss.soa.esb.util.RemoteFileSystem#downloadFile(java.lang.String,
         *      java.lang.String)
         */
        public void downloadFile (String p_sFile, String p_sFinalName)
                        throws IOException, RemoteFileSystemException
        {
                try
                {
                    final File to = new File(p_sFinalName) ;
                    final File oLocalDir = new File(m_sLocalDir);
                    final File oNew = (to.isAbsolute() ? to : new File(oLocalDir, p_sFinalName)) ;
                    if (oNew.exists()) {
                      boolean result = oNew.delete();
                      if (!result) {
                        logger.error("Could not delete file " + oNew.getAbsolutePath());
                      }
                    }
                   
                    final File toTmp = new File(p_sFinalName + TMP_SUFFIX) ;
                    final File oNewTmp = (toTmp.isAbsolute() ? toTmp : new File(oLocalDir, p_sFinalName + TMP_SUFFIX)) ;
                    if (oNewTmp.exists()) {
                      boolean result = oNewTmp.delete();
                      if (!result) {
                        logger.error("Could not delete file " + oNewTmp.getAbsolutePath());
                      }
                    }
                       
                    changeRemoteDirectory() ;
                    final InputStream is = m_oConn.retrieveFileStream(p_sFile) ;
                    if (is == null)
                    {
                        throw new RemoteFileSystemException("Could not download file: " + m_oConn.getReplyString());
                    }
                   
                    try
                    {
                        final FileOutputStream fos = new FileOutputStream(oNewTmp) ;
                        try
                        {
                            copyStream(is, fos) ;
                        }
                        finally
                        {
                            fos.close() ;
                        }
                    }
                    finally
                    {
                        is.close() ;
                    }
                    if (!m_oConn.completePendingCommand())
                    {
                        boolean result = oNewTmp.delete();
                        if (!result) {
                          logger.error("Could not delete file " + oNewTmp.getAbsolutePath());
                        }
                        throw new RemoteFileSystemException("Failed to download contents: " + m_oConn.getReplyString()) ;
                    }
                    FileUtil.renameTo(oNewTmp, oNew) ;
                }
                catch (final IOException ioe)
                {
                    throw new RemoteFileSystemException(ioe) ;
                }
        }

        /*
         * (non-Javadoc)
         *
         * @see org.jboss.soa.esb.util.RemoteFileSystem#getFileListFromRemoteDir(java.lang.String)
         */
        public String[] getFileListFromRemoteDir (String p_sSuffix)
                        throws RemoteFileSystemException, IOException
        {
            if ((p_sSuffix == null) || ("".equals(p_sSuffix))) {
                    try
                    {
                        changeRemoteDirectory() ;
                        return m_oConn.listNames() ;
                    }
                    catch (final IOException ioe)
                    {
                        throw new RemoteFileSystemException(ioe) ;
                    }             
            } else {
              String sSuffix = "*" + p_sSuffix;

              try
              {
                changeRemoteDirectory() ;
                return m_oConn.listNames(sSuffix) ;
              }
              catch (final IOException ioe)
              {
                throw new RemoteFileSystemException(ioe) ;
              }
            }
        }

        /*
         * (non-Javadoc)
         *
         * @see org.jboss.soa.esb.util.RemoteFileSystem#getRemoteDir()
         */
        public String getRemoteDir ()
        {
                return m_sRemoteDir;
        }

        protected void initialize (boolean bConnect)
            throws ConfigurationException, RemoteFileSystemException
        {
            checkParms();
            m_oConn = instantiateClient() ;
           
            if( m_ControlChannelEncoding != null ) {
              m_oConn.setControlEncoding(this.m_ControlChannelEncoding);
            }
           
            if (bConnect)
            {
                try
                {
                    if (m_iTimeoutDefault > 0)
                    {
                        m_oConn.setDefaultTimeout(m_iTimeoutDefault);
                    }
                   
                    connect() ;
                   
                    if (!m_oConn.isConnected())
                        throw new RemoteFileSystemException(
                                        "Can't connect to FTP server");
                   
                    if (!m_oConn.login(m_sUser, m_sPasswd))
                    {
                        m_oConn.logout() ;
                        throw new RemoteFileSystemException("Remote login failed: " + m_oConn.getReplyString());
                    }
                    m_oConn.setFileType(FTP.BINARY_FILE_TYPE) ;
                    if (m_bPassive)
                    {
                        m_oConn.enterLocalPassiveMode() ;
                    }
                    if (m_iTimeoutData > 0)
                    {
                        m_oConn.setDataTimeout(m_iTimeoutData);
                    }
                    if (m_iTimeoutSo > 0)
                    {
                        m_oConn.setSoTimeout(m_iTimeoutSo);
                    }
                }
                catch (final IOException ioe)
                {
                    if (m_oConn.isConnected())
                    {
                        try
                        {
                            m_oConn.disconnect() ;
                        }
                        catch (final IOException ioe2) {} // ignore
                    }
                    throw new RemoteFileSystemException(ioe);
                }
            }
        }

        protected FTPClient instantiateClient()
            throws RemoteFileSystemException
        {
                return new FTPClient() ;
        }
       
        protected void connect()
                throws IOException
        {
            if (m_iPort > 0)
            {
                m_oConn.connect(m_sFtpServer, m_iPort) ;
            }
            else
            {
                m_oConn.connect(m_sFtpServer) ;
            }
        }

        /*
         * (non-Javadoc)
         *
         * @see org.jboss.soa.esb.util.RemoteFileSystem#quit()
         */
        public void quit ()
        {
                if (null != m_oConn)
                {
                        try
                        {
                                m_oConn.quit();
                                m_oConn.disconnect() ;
                        }
                        catch (Exception e)
                        {
                        }
                }
        }

        /*
         * (non-Javadoc)
         *
         * @see org.jboss.soa.esb.util.RemoteFileSystem#remoteDelete(java.io.File)
         */
        public void remoteDelete (File p_oFile) throws RemoteFileSystemException
        {
                try
                {
                    changeRemoteDirectory() ;
                    if (!m_oConn.deleteFile(p_oFile.getName()))
                    {
                        throw new RemoteFileSystemException("Failed to delete remote file: " + m_oConn.getReplyString());
                    }
                }
                catch (final IOException ioe)
                {
                    throw new RemoteFileSystemException(ioe);
                }
        }

        /*
         * (non-Javadoc)
         *
         * @see org.jboss.soa.esb.util.RemoteFileSystem#remoteRename(java.io.File,
         *      java.io.File)
         */
        public void remoteRename (File p_oFrom, File p_oTo) throws RemoteFileSystemException
        {
                try
                {
                        changeRemoteDirectory();
                        if (!m_oConn.rename(FtpClientUtil.fileToFtpString(p_oFrom),
                                FtpUtils.fileToFtpString(p_oTo)))
                        {
                            throw new RemoteFileSystemException("Failed to rename file: " + m_oConn.getReplyString());
                        }
                }
                catch (final IOException ioe)
                {
                    throw new RemoteFileSystemException(ioe);
                }
        }

        /*
         * (non-Javadoc)
         *
         * @see org.jboss.soa.esb.util.RemoteFileSystem#renameInRemoteDir(java.lang.String,
         *      java.lang.String)
         */
        public void renameInRemoteDir (String p_sFrom, String p_sTo)
                        throws RemoteFileSystemException
        {
            try
            {
                changeRemoteDirectory() ;
                if (!m_oConn.rename(p_sFrom, p_sTo))
                {
                    throw new RemoteFileSystemException("Failed to rename file: " + m_oConn.getReplyString());
                }
            }
            catch (final IOException ioe)
            {
                throw new RemoteFileSystemException(ioe);
            }
        }

        /*
         * (non-Javadoc)
         *
         * @see org.jboss.soa.esb.util.RemoteFileSystem#setRemoteDir(java.lang.String)
         */
        public void setRemoteDir (String p_sDir) throws RemoteFileSystemException
        {
                if (p_sDir == null)
                        throw new IllegalArgumentException();
               
                m_sRemoteDir = p_sDir;
        }

        /*
         * (non-Javadoc)
         *
         * @see org.jboss.soa.esb.util.RemoteFileSystem#uploadFile(java.io.File,
         *      java.lang.String)
         */
        public void uploadFile (File p_oFile, String p_sRemoteName)
                        throws RemoteFileSystemException
        {
            try
            {
                changeRemoteDirectory() ;
               
                final String sRemoteTmp = p_sRemoteName + TMP_SUFFIX;
               
                final OutputStream os = m_oConn.storeFileStream(sRemoteTmp) ;
                if (os == null)
                {
                    throw new RemoteFileSystemException("Failed to obtain output stream: " + m_oConn.getReplyString()) ;
                }
               
                try
                {
                    final FileInputStream fis = new FileInputStream(p_oFile) ;
                    try
                    {
                        copyStream(fis, os) ;
                    }
                    finally
                    {
                        fis.close() ;
                    }
                }
                finally
                {
                    os.flush() ;
                    os.close() ;
                }
                if (!m_oConn.completePendingCommand())
                {
                    throw new RemoteFileSystemException("Failed to upload contents: " + m_oConn.getReplyString()) ;
                }
               
                boolean retryProblem = true// https://jira.jboss.org/jira/browse/JBESB-1995

                for (int i = 0; i < m_iRenameRetry; i++)
                {
                    if (m_oConn.rename(sRemoteTmp, p_sRemoteName))
                    {
                        retryProblem = false;
                       
                        break;
                    }
                    else
                    {
                        if (i+1 < m_iRenameRetry)
                        {
                            try
                            {
                                Thread.sleep(1000L); // 1 second
                            }
                            catch (final Exception ex)
                            {
                            }
                        }
                    }
                }
               
                if (retryProblem)
                    throw new RemoteFileSystemException("Failed to rename file: " + m_oConn.getReplyString());
            }
            catch (final IOException ioe)
            {
                throw new RemoteFileSystemException(ioe);
            }
        }
       
        private void changeRemoteDirectory()
            throws IOException, RemoteFileSystemException
        {
            final String remoteDir = getRemoteDir() ;
            if ((remoteDir != null) && (remoteDir.length() > 0))
            {
                if (!m_oConn.changeWorkingDirectory(remoteDir))
                {
                    throw new RemoteFileSystemException("Failed to change to remote directory: " + m_oConn.getReplyString());
                }
            }
        }
       
        private void copyStream(final InputStream is, final OutputStream os)
            throws IOException
        {
            final BufferedInputStream bis = new BufferedInputStream(is) ;
            final BufferedOutputStream bos = new BufferedOutputStream(os) ;
           
            final byte[] buffer = new byte[256] ;
            while(true)
            {
                final int count = bis.read(buffer) ;
                if (count <= 0)
                {
                    break ;
                }
                bos.write(buffer, 0, count) ;
            }
            bos.flush() ;
        }
}
TOP

Related Classes of org.jboss.internal.soa.esb.util.FtpImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.