1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 package org.archive.net;
26
27
28 import java.io.IOException;
29 import java.net.Socket;
30
31 import org.apache.commons.net.ftp.FTPClient;
32 import org.apache.commons.net.ftp.FTPReply;
33
34
35 /***
36 * Client for FTP operations. This class is necessary only because the
37 * {@link #_openDataConnection_(int, String)} method is protected in
38 * the superclass, and we need to call it directly to handle directory
39 * listings. (The code that provides directory listings in the
40 * superclass doesn't scale: It reads the entire directory into
41 * an in-memory list).
42 *
43 * <p>Additionally, "strict" methods are provided for the other operations
44 * we use. Maddeningly, the superclass never raises exceptions. If an
45 * FTP operation fails, then the superclass methods generally return false.
46 * A developer then needs to check the {@link FTP#getReplyCode()}
47 * method to see what actually went wrong. The "strict" methods provided
48 * by this class invoke the superclass method, check if the success flag
49 * is false, and then raise an {@link FTPException} with the value of
50 * {@link FTP#getReplyCode()}.
51 *
52 * @author pjack
53 */
54 public class ClientFTP extends FTPClient {
55
56
57 /***
58 * Constructs a new <code>ClientFTP</code>.
59 */
60 public ClientFTP() {
61 }
62
63
64 /***
65 * Connects to the FTP server at the given host and port.
66 *
67 * @param host the host of the FTP server to connect to
68 * @param port the port the FTP server listens on
69 * @throws IOException if the connection cannot be made due to IO error
70 * @throws FTPException if the server refuses the connection
71 */
72 public void connectStrict(String host, int port) throws IOException {
73 this.connect(host, port);
74 int reply = this.getReplyCode();
75 if (!FTPReply.isPositiveCompletion(reply)) {
76 throw new FTPException(reply);
77 }
78 }
79
80
81 /***
82 * Login to the FTP server with the given username and password.
83 *
84 * @param user the username to login under
85 * @param pass the password to use
86 * @throws IOException if a network error occurs
87 * @throws FTPException if the login is rejected by the server
88 * @throws org.apache.commons.net.ftp.FTPConnectionClosedException
89 * if the FTP server prematurely closes the connection (for
90 * instance, if the client was idle for too long)
91 */
92 public void loginStrict(String user, String pass) throws IOException {
93 boolean r = this.login(user, pass);
94 if (!r) {
95 throw new FTPException(this.getReplyCode());
96 }
97 }
98
99
100 /***
101 * Tells the FTP server to send binary files.
102 *
103 * @throws IOException if a network error occurs
104 * @throws FTPException if the server rejects the command
105 * @throws org.apache.commons.net.ftp.FTPConnectionClosedException
106 * if the FTP server prematurely closes the connection (for
107 * instance, if the client was idle for too long)
108 */
109 public void setBinary() throws IOException {
110 boolean r = super.setFileType(BINARY_FILE_TYPE);
111 if (!r) {
112 throw new FTPException(getReplyCode());
113 }
114 }
115
116
117 /***
118 * Opens a data connection.
119 *
120 * @param command the data command (eg, RETR or LIST)
121 * @param path the path of the file to retrieve
122 * @return the socket to read data from
123 * @throws IOException if a network error occurs
124 * @throws FTPException if a protocol error occurs
125 */
126 public Socket openDataConnection(int command, String path)
127 throws IOException {
128 Socket socket = _openDataConnection_(command, path);
129 if (socket == null) {
130 throw new FTPException(this.getReplyCode());
131 }
132 return socket;
133 }
134
135
136 }