View Javadoc

1   // PassivePutter.java
2   // $Id: PassivePutter.java,v 1.7 2007/05/07 18:26:54 sjardine Exp $
3   //
4   // Copyright 2000, Joe Phillips <jaiger@innovationsw.com>
5   // Copyright 2001, 2002 Innovation Software Group, LLC - http://www.innovationsw.com
6   //
7   // This library is free software; you can redistribute it and/or
8   // modify it under the terms of the GNU Library General Public
9   // License as published by the Free Software Foundation; either
10  // version 2 of the License, or (at your option) any later version.
11  //
12  // This library is distributed in the hope that it will be useful,
13  // but WITHOUT ANY WARRANTY; without even the implied warranty of
14  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  // Library General Public License for more details.
16  //
17  // You should have received a copy of the GNU Library General Public
18  // License along with this library; if not, write to the Free
19  // Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20  package gnu.inet.ftp;
21  
22  import java.io.InputStream;
23  import java.io.InterruptedIOException;
24  import java.io.OutputStream;
25  import java.net.Socket;
26  import java.net.SocketException;
27  import java.util.zip.DeflaterOutputStream;
28  
29  import org.apache.commons.logging.Log;
30  import org.apache.commons.logging.LogFactory;
31  
32  /***
33   * This class implements an FTP-style data connection server thread for PUTing
34   * files/data passively to the server.
35   * <P>
36   * This class is used internally to the FtpClient class.
37   */
38  public class PassivePutter extends Putter {
39  
40      private final static Log log = LogFactory.getLog(PassivePutter.class);
41  
42      private PassiveConnection connection;
43  
44      /***
45       * Create a new PassivePutter thread given the input stream data source and
46       * PssiveParameters to use to connect to the server.
47       * 
48       * @param in
49       *                data source
50       * @param connection
51       *                the passive connection to the server
52       */
53      /***
54       * @param in
55       * @param connection
56       */
57      public PassivePutter(InputStream in, PassiveConnection connection) {
58  	super();
59  
60  	this.istream = in;
61  	this.connection = connection;
62      }
63  
64      //
65      // public methods
66      //
67  
68      /***
69       * implements thread behavior. Put data to server using given parameters.
70       */
71      public void run() {
72  	boolean signalClosure = false;
73  	Socket sock = null;
74  	OutputStream ostream = null;
75  	long amount = 0;
76  	int buffer_size = 0;
77  	byte buffer[] = new byte[BUFFER_SIZE];
78  	// this.cancelled= false; // reset cancelled flag
79  	PassiveParameters parameters = connection.getPassiveParameters();
80  
81  	try {
82  	    // make connection
83  	    sock = connection.getSocket();
84  	    if (cancelled)
85  		throw new InterruptedIOException("Transfer cancelled");
86  	    signalConnectionOpened(new ConnectionEvent(parameters
87  		    .getInetAddress(), parameters.getPort()));
88  	    signalClosure = true;
89  	    signalTransferStarted();
90  
91  	    try {
92  
93  		// handle different type settings
94  		switch (type) {
95  		case FtpClientProtocol.TYPE_ASCII:
96  		    ostream = new AsciiOutputStream(sock.getOutputStream());
97  		    break;
98  		default:
99  		    ostream = sock.getOutputStream();
100 		    break;
101 		}
102 
103 		// handle different mode settings
104 		switch (mode) {
105 		case FtpClientProtocol.MODE_ZLIB:
106 		    ostream = new DeflaterOutputStream(ostream);
107 		    break;
108 		case FtpClientProtocol.MODE_STREAM:
109 		default:
110 		    break;
111 		}
112 
113 		int len;
114 		while ((len = istream.read(buffer)) != -1) {
115 		    ostream.write(buffer, 0, len);
116 		    amount += len;
117 		    buffer_size += len;
118 		    if (buffer_size >= BUFFER_SIZE) {
119 			buffer_size = buffer_size % BUFFER_SIZE;
120 			signalTransfered(amount);
121 		    }
122 		    yield();
123 		}
124 	    } catch (InterruptedIOException iioe) {
125 		if (!cancelled) {
126 		    log.error(iioe.getMessage(), iioe);
127 		}
128 	    } catch (Exception e) {
129 		log.error(e.getMessage(), e);
130 	    } finally {
131 		log.debug("Closing inputstream");
132 		if (ostream != null) {
133 		    ostream.close();
134 		}
135 		if (!sock.isClosed()) {
136 		    try {
137 			log.debug("Setting socket to 0 lingering");
138 			sock.setSoLinger(true, 0);
139 			sock.close();
140 		    } catch (SocketException e) {
141 			// Don't care.
142 		    }
143 		}
144 		signalTransferCompleted();
145 	    }
146 	} catch (Exception ee) {
147 	    signalConnectionFailed(ee);
148 	    log.error(ee.getMessage(), ee);
149 	}
150 
151 	if (signalClosure == true) {
152 	    signalConnectionClosed(new ConnectionEvent(parameters
153 		    .getInetAddress(), parameters.getPort()));
154 	}
155     }
156 }
157 
158 // PassivePutter.java