View Javadoc

1   /*
2    * Copyright (c) 2003 Peter Antman, Teknik i Media  <peter.antman@tim.se>
3    *
4    * $Id: NetFTPConnection.java,v 1.1.1.1 2004/05/19 12:26:42 pra Exp $
5    *
6    * This library is free software; you can redistribute it and/or
7    * modify it under the terms of the GNU Lesser General Public
8    * License as published by the Free Software Foundation; either
9    * version 2 of the License, or (at your option) any later version
10   * 
11   * This library is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14   * Lesser General Public License for more details.
15   * 
16   * You should have received a copy of the GNU Lesser General Public
17   * License along with this library; if not, write to the Free Software
18   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19   */
20  package org.backsource.adaptor.ftp;
21  import java.io.InputStream;
22  import java.io.ByteArrayOutputStream;
23  import java.io.BufferedOutputStream;
24  import java.io.ByteArrayInputStream;
25  import java.io.BufferedInputStream;
26  import java.io.IOException;
27  import java.util.List;
28  import java.util.ArrayList;
29  
30  import org.apache.log4j.Logger;
31  
32  import org.apache.commons.net.ftp.FTP;
33  import org.apache.commons.net.ftp.FTPClient;
34  import org.apache.commons.net.ftp.FTPReply;
35  import org.apache.commons.net.ftp.FTPFile;
36  import org.apache.commons.net.ftp.FTPConnectionClosedException;
37  
38  import org.backsource.utils.io.CachedOutputStream;
39  /***
40   * An FTP Connection based on the jakarta commont-net-ftp lib.
41   *
42   * <p>It is important to know that a close() on the connections just returns
43   * the connection to the factory; and do not close the real connection.
44   *
45   * @author <a href="mailto:pra@tim.se">Peter Antman</a>
46   * @version $Revision: 1.1.1.1 $
47   */
48  
49  public class NetFTPConnection implements FTPConnection{
50     private static final Logger log = Logger.getLogger(NetFTPConnection.class);
51     private FTPClient ftp;
52     
53     private FTPConnectionFactory factory;
54     
55     protected NetFTPConnection(FTPConnectionFactory factory) {
56        this.factory = factory;
57     }
58     
59     protected void connect() throws FTPException {
60        try {
61           ftp = new FTPClient();
62           ftp.setDefaultTimeout( factory.getTimeout() );
63           
64           // Connect
65           ftp.connect( factory.getHostName() );
66           int reply = ftp.getReplyCode();
67           if(!FTPReply.isPositiveCompletion(reply)) {
68              throwException("FTP server refused connection", null);
69           }
70           
71           // Login
72           if ( !ftp.login(factory.getUser(),factory.getPassword() ) ) {
73              throwException("FTP server refused login for user " +factory.getUser(),null);
74           }
75           ftp.enterLocalPassiveMode();
76        } catch (IOException e) {
77           throwException("Exception when connecting to server "+factory.getHostName(),e);
78        } // end of try-catch
79     }
80     
81     protected void internalClose() {
82        if(ftp != null && ftp.isConnected()) {
83           try {
84              ftp.disconnect();
85           } catch(IOException f) {
86              ;// do nothing
87           }
88        }
89        ftp = null;
90     }
91     
92     public void close() {
93        factory.releaseConnection(this);
94     }
95     
96     public void setBinaryMode(boolean binaryMode) throws FTPException{
97        checkState();
98        try {
99           if ( binaryMode ) {
100             if ( !ftp.setFileType(FTP.BINARY_FILE_TYPE)) {
101                throwException("Could not set binary file type",null);
102             } // end of if ()
103             
104          } else {
105             if ( !ftp.setFileType(FTP.ASCII_FILE_TYPE)) {
106                throwException("Could not set ascii file type",null);
107             } // end of if ()
108             
109          } // end of else
110       } catch (IOException e) {
111          throwException("Could not set file type",e);
112       } // end of try-catch
113       
114    }
115    
116    public void setPassiveMode(boolean passiveMode) throws FTPException{
117       checkState();
118       if ( passiveMode ) {
119          ftp.enterLocalPassiveMode();
120       } else {
121          ftp.enterLocalActiveMode();
122       } // end of else
123       
124    }
125    
126    public boolean isAlive() {
127       try {
128          checkState();
129          ftp.sendNoOp();
130          return true;
131       } catch (Exception e) {
132          return false;
133       } // end of try-catch
134       
135    }
136 
137    public List list(String url) throws FTPException {
138       checkState();
139       org.apache.commons.net.ftp.FTPFile[] files = null;
140       try {
141          files =  ftp.listFiles(url);
142       } catch (IOException e) {
143          throwException("Could not list files in " + url,e);
144       } // end of try-catch
145 
146       ArrayList list = new ArrayList();
147       if ( files != null) {
148          for ( int i = 0;i < files.length;i++) {
149             list.add( new NetFTPFile( files[i],url));
150          } // end of for ()
151          
152       } // end of if ()
153       return list;
154       
155    }
156    
157    public InputStream get(String url) throws FTPException {
158       checkState();
159       InputStream is = null;
160       try {
161          
162          CachedOutputStream cos = factory.getCachedStream().getOutputStream();
163          if (!ftp.retrieveFile( url, cos )) {
164             cos.close();
165             throwException("Could not get file "+ url,null);
166          }
167          // Have to do this mumbo jumbo here, beacuse if we chose
168          // the imputStream method we must close it and manually check the
169          // connection wich does not play well with Amsterdam
170          //InputStream is = ftp.retrieveFileStream( file );
171          is = factory.getCachedStream().getInputStream(cos);
172          cos.close();	
173       } catch (IOException e) {
174          throwException("Could not get file "+ url,e);
175       } // end of try-catch
176       return is;
177    }
178    public void put(String url, InputStream localStream) throws FTPException{
179       checkState();
180       try {
181          if ( !ftp.storeUniqueFile(url,localStream)) {
182             throwException("Could not put file "+ url,null);
183          } // end of if ()
184       } catch (IOException e) {
185          throwException("Could not put file "+ url,e);
186       } // end of try-catch
187    }
188 
189    public void deleteFile(String url) throws FTPException{
190       checkState();
191       try {
192          if ( !ftp.deleteFile(url)) {
193             throwException("Could not delete file "+ url,null);
194          } // end of if ()
195       } catch (IOException e) {
196          throwException("Could not delete file "+ url,e);
197       } // end of try-catch
198    }
199    
200    public void mkdir(String url) throws FTPException{
201       checkState();
202       try {
203          if ( !ftp.makeDirectory(url)) {
204             throwException("Could not create dir "+ url,null);
205          } // end of if ()
206       } catch (IOException e) {
207          throwException("Could not create dir "+ url,e);
208       } // end of try-catch
209    }
210 
211    public String getWorkingDirectory() throws FTPException{
212       checkState();
213       String cwd = null;
214       try {
215          cwd = ftp.printWorkingDirectory();
216       } catch (IOException e) {
217          throwException("Could not get working dir",e);
218       } // end of try-catch
219       return cwd;
220    }
221 
222    public void cd(String dir) throws FTPException {
223       checkState();
224       try {
225          if ( !ftp.changeWorkingDirectory(dir)) {
226             throwException("Could not change to dir "+ dir,null);
227          } // end of if ()
228       } catch (IOException e) {
229          throwException("Could not change to dir "+ dir,e);
230       } // end of try-catch
231       
232    }
233    
234    /***
235     * Throw an FTPException.
236     *
237     * <p>If the source exception is a FTPConnectionClosedException, then an FTPTimeoutException is thrown.
238     */
239    private void throwException(String msg, Exception e) throws FTPException{
240       FTPException ftpEx = null;
241       if ( e != null) {
242          if ( e instanceof FTPConnectionClosedException) {
243             ftpEx = new  FTPTimeoutException(msg,e);
244          } else {        
245             ftpEx = new  FTPException(msg,e);
246          } // end of else
247       } else {
248          ftpEx = new  FTPException(msg);
249       } // end of else
250             
251       if ( ftp != null) {
252          ftpEx.setReasonCode( ftp.getReplyCode() );
253          ftpEx.setReason( ftp.getReplyString() );
254       } // end of if ()
255       throw ftpEx;
256       
257    }
258    
259    private void checkState() throws FTPException{
260       if ( ftp == null) {
261          throw new FTPException("No connection open; connection in invalid state"); 
262       } // end of if ()
263       
264    }
265 
266 }// NetFTPConnection