001/**
002 *
003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved.
004 *
005 * This library is free software; you can redistribute it and/or
006 * modify it under the terms of the GNU Lesser General Public
007 * License as published by the Free Software Foundation; either 
008 * version 2.1 of the License, or (at your option) any later version.
009 * 
010 * This library is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013 * Lesser General Public License for more details.
014 * 
015 * You should have received a copy of the GNU Lesser General Public 
016 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
017 * 
018 **/
019package lucee.runtime.net.ftp;
020
021import lucee.commons.lang.StringUtil;
022import lucee.runtime.exp.ApplicationException;
023
024import java.io.IOException;
025import java.util.HashMap;
026import java.util.Iterator;
027import java.util.Map;
028import java.util.Map.Entry;
029
030/**
031 * Pool of FTP Client
032 */
033public final class FTPPoolImpl {
034
035    Map<String,FTPWrap> wraps=new HashMap<String, FTPWrap>();
036
037    public AFTPClient get(FTPConnectionPro conn) throws IOException, ApplicationException {
038        AFTPClient client = _get(conn).getClient();
039        if(client==null)throw new ApplicationException("can't connect to server ["+conn.getServer()+"]");
040        
041        FTPWrap.setConnectionSettings(client,conn);
042        
043        return client;
044    }
045
046    /**
047     * returns a client from given connection
048     * @param conn
049     * @return 
050     * @return matching wrap
051     * @throws IOException
052     * @throws ApplicationException
053     */
054    protected FTPWrap _get(FTPConnectionPro conn) throws IOException, ApplicationException {
055        FTPWrap wrap=null;
056        
057      
058        
059        if(!conn.hasLoginData()) {
060                if(StringUtil.isEmpty(conn.getName())){
061                        throw new ApplicationException("can't connect ftp server, missing connection defintion");
062                }
063                
064                wrap=wraps.get(conn.getName());
065            if(wrap==null) {
066                throw new ApplicationException("can't connect ftp server, missing connection ["+conn.getName()+"]");
067            }
068            else if(!wrap.getClient().isConnected() || wrap.getConnection().getTransferMode()!=conn.getTransferMode()) {
069                wrap.reConnect(conn.getTransferMode());
070            }
071            return wrap;
072        }
073        String name=conn.hasName()?conn.getName():"__noname__";
074        
075        wrap=wraps.get(name);
076        if(wrap!=null) {
077            if(conn.loginEquals(wrap.getConnection())) {
078                return _get(new FTPConnectionImpl(name,null,null,null,conn.getPort(),conn.getTimeout(),conn.getTransferMode(),conn.isPassive(),
079                                conn.getProxyServer(),conn.getProxyPort(),conn.getProxyUser(),conn.getProxyPassword(),
080                                conn.getFingerprint(),conn.getStopOnError(),conn.secure()));
081            }
082            disconnect(wrap.getClient());
083        }
084                
085        wrap=new FTPWrap(conn);
086        wraps.put(name,wrap);
087        
088        
089      
090                
091                
092                
093                
094        return wrap;
095    }
096
097    /**
098     * disconnect a client
099     * @param client
100     */
101    private void disconnect(AFTPClient client) {
102        try {
103            if(client!=null && client.isConnected()) {
104                        client.quit();
105                client.disconnect();
106            }
107        }
108        catch(IOException ioe) {}
109    }
110
111    public AFTPClient remove(FTPConnection conn) {
112        return remove(conn.getName());
113    }
114
115    public AFTPClient remove(String name) {
116        FTPWrap wrap=wraps.remove(name);
117        if(wrap==null) return null;
118        
119        AFTPClient client = wrap.getClient();
120        disconnect(client);
121        return client;
122    }
123
124    public void clear() {
125        if(!wraps.isEmpty()) {
126            Iterator<Entry<String, FTPWrap>> it = wraps.entrySet().iterator();
127            while(it.hasNext()) {
128                try {
129                    Entry<String, FTPWrap> entry = it.next();
130                    FTPWrap wrap=entry.getValue();
131                    if(wrap!=null && wrap.getClient().isConnected())wrap.getClient().disconnect();
132                } catch (IOException e) {}
133            }
134            wraps.clear();
135        }
136    }
137}