org.exoplatform.services.ftp.FtpServerImpl.java Source code

Java tutorial

Introduction

Here is the source code for org.exoplatform.services.ftp.FtpServerImpl.java

Source

/*
 * Copyright (C) 2009 eXo Platform SAS.
 *
 * 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.exoplatform.services.ftp;

import org.apache.commons.chain.Catalog;
import org.exoplatform.commons.utils.PrivilegedFileHelper;
import org.exoplatform.commons.utils.SecurityHelper;
import org.exoplatform.services.command.impl.CommandService;
import org.exoplatform.services.ftp.client.FtpClientSession;
import org.exoplatform.services.ftp.client.FtpClientSessionImpl;
import org.exoplatform.services.ftp.command.FtpCommand;
import org.exoplatform.services.ftp.config.FtpConfig;
import org.exoplatform.services.ftp.data.FtpDataChannelManager;
import org.exoplatform.services.ftp.data.FtpDataChannelManagerImpl;
import org.exoplatform.services.jcr.RepositoryService;
import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
import org.exoplatform.services.jcr.core.ManageableRepository;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;

import java.io.File;
import java.io.InputStream;
import java.net.BindException;
import java.net.ServerSocket;
import java.net.Socket;
import java.security.PrivilegedAction;
import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;

import javax.jcr.RepositoryException;

/**
 * Created by The eXo Platform SAS Author : Vitaly Guly <gavrik-vetal@ukr.net/mail.ru>
 * 
 * @version $Id: $
 */

public class FtpServerImpl implements FtpServer {

    private static final Log LOG = ExoLogger.getLogger(FtpConst.FTP_PREFIX + "FtpServerImpl");

    public static final String COMMAND_PATH = "/conf/ftp-commands.xml";

    private Catalog commandCatalog;

    private RepositoryService repositoryService;

    private FtpConfig configuration;

    private FtpAcceptThread acceptThread;

    private FtpDataChannelManager dataChannelManager;

    private ArrayList<FtpClientSession> clients = new ArrayList<FtpClientSession>();

    public FtpServerImpl(FtpConfig configuration, CommandService commandService,
            RepositoryService repositoryService) throws Exception {
        this.configuration = configuration;
        this.repositoryService = repositoryService;

        InputStream commandStream = SecurityHelper.doPrivilegedAction(new PrivilegedAction<InputStream>() {
            public InputStream run() {
                return getClass().getResourceAsStream(COMMAND_PATH);
            }
        });

        commandService.putCatalog(commandStream);
        commandCatalog = commandService.getCatalog(FtpConst.FTP_COMMAND_CATALOG);
    }

    protected void prepareCache() {
        String cacheFolderName = configuration.getCacheFolderName();

        File cacheFolder = new File(cacheFolderName);

        if (!PrivilegedFileHelper.exists(cacheFolder)) {
            LOG.info("Cache folder not exist. Try to create it...");
            PrivilegedFileHelper.mkdirs(cacheFolder);
        }

        String[] cacheFiles = PrivilegedFileHelper.list(cacheFolder);
        if (cacheFiles == null) {
            LOG.info("No cache file in cache folder!");
            return;
        }

        for (String cacheFile : cacheFiles) {
            if (cacheFile.endsWith(FtpConst.FTP_CACHEFILEEXTENTION)) {
                File file = new File(cacheFolderName + "/" + cacheFile);
                PrivilegedFileHelper.delete(file);
            }
        }

    }

    public boolean start() {
        try {
            prepareCache();

            ServerSocket serverSocket = null;
            int port = configuration.getCommandPort();
            // Trying to find a port available
            while (serverSocket == null) {
                try {
                    serverSocket = new ServerSocket(port);
                    LOG.info("FTPServer started on port '" + port + "'");
                } catch (BindException e) {
                    LOG.warn("Cannot launch the FTPServer on '" + (port++) + "', we try the next port number");
                }
            }

            dataChannelManager = new FtpDataChannelManagerImpl(configuration);

            acceptThread = new FtpAcceptThread(this, serverSocket);
            acceptThread.start();

            return true;
        } catch (Exception exc) {
            LOG.info("Unhandled exception. " + exc.getMessage(), exc);
        }

        return false;
    }

    public boolean stop() {
        return false;
    }

    public FtpConfig getConfiguration() {
        return configuration;
    }

    public ManageableRepository getRepository() {

        try {
            return repositoryService.getDefaultRepository();
        } catch (RepositoryException e) {
            LOG.info("Repository exception. " + e.getMessage(), e);
        } catch (RepositoryConfigurationException e) {
            LOG.info("Repository configuration exception. " + e.getMessage(), e);
        }

        return null;
    }

    public FtpCommand getCommand(String commandName) {
        return (FtpCommand) commandCatalog.getCommand(commandName);
    }

    public FtpDataChannelManager getDataChannelManager() {
        return dataChannelManager;
    }

    public boolean unRegisterClient(FtpClientSession clientSession) {
        boolean result = clients.remove(clientSession);
        LOG.info(">>> Client disconnected. Clients: " + clients.size());
        return result;
    }

    public int getClientsCount() {
        return clients.size();
    }

    protected class FtpAcceptThread extends Thread {

        protected FtpServer ftpServer;

        protected ServerSocket serverSocket;

        protected boolean enable = true;

        public FtpAcceptThread(FtpServer ftpServer, ServerSocket serverSocket) {
            this.ftpServer = ftpServer;
            this.serverSocket = serverSocket;
            setName("Ftp Server" + (configuration.getPortalContainer() == null ? ""
                    : " " + configuration.getPortalContainer().getName()));
            setDaemon(true);
        }

        public void disable() {
            enable = false;
        }

        @Override
        public void run() {
            while (enable) {
                Socket incoming = null;
                try {
                    incoming = SecurityHelper.doPrivilegedExceptionAction(new PrivilegedExceptionAction<Socket>() {
                        public Socket run() throws Exception {
                            return serverSocket.accept();
                        }
                    });

                    FtpClientSession clientSession = new FtpClientSessionImpl(ftpServer, incoming);
                    clients.add(clientSession);

                    LOG.info(">>> New client connected. Clients: " + clients.size());
                } catch (Exception exc) {
                    LOG.info("Unhandled exception. " + exc.getMessage(), exc);
                }
            }
        }

    }

}