1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.vfs.provider.ftp;
18
19 import org.apache.commons.net.ftp.FTPClient;
20 import org.apache.commons.net.ftp.FTPFile;
21 import org.apache.commons.vfs.FileSystemException;
22 import org.apache.commons.vfs.FileSystemOptions;
23 import org.apache.commons.vfs.UserAuthenticationData;
24 import org.apache.commons.vfs.util.UserAuthenticatorUtils;
25 import org.apache.commons.vfs.provider.GenericFileName;
26
27 import java.io.IOException;
28 import java.io.InputStream;
29 import java.io.OutputStream;
30
31 /***
32 * A wrapper to the FTPClient to allow automatic reconnect on connection loss.<br />
33 * I decided to not to use eg. noop() to determine the state of the connection to avoid unnecesary server round-trips.
34 */
35 class FTPClientWrapper implements FtpClient
36 {
37 private final GenericFileName root;
38 private final FileSystemOptions fileSystemOptions;
39
40 private FTPClient ftpClient = null;
41
42 FTPClientWrapper(final GenericFileName root, final FileSystemOptions fileSystemOptions) throws FileSystemException
43 {
44 this.root = root;
45 this.fileSystemOptions = fileSystemOptions;
46 getFtpClient();
47 }
48
49 public GenericFileName getRoot()
50 {
51 return root;
52 }
53
54 public FileSystemOptions getFileSystemOptions()
55 {
56 return fileSystemOptions;
57 }
58
59 private FTPClient createClient() throws FileSystemException
60 {
61 final GenericFileName rootName = getRoot();
62
63 UserAuthenticationData authData = null;
64 try
65 {
66 authData = UserAuthenticatorUtils.authenticate(fileSystemOptions, FtpFileProvider.AUTHENTICATOR_TYPES);
67
68 return FtpClientFactory.createConnection(rootName.getHostName(),
69 rootName.getPort(),
70 UserAuthenticatorUtils.getData(authData, UserAuthenticationData.USERNAME, UserAuthenticatorUtils.toChar(rootName.getUserName())),
71 UserAuthenticatorUtils.getData(authData, UserAuthenticationData.PASSWORD, UserAuthenticatorUtils.toChar(rootName.getPassword())),
72 rootName.getPath(),
73 getFileSystemOptions());
74 }
75 finally
76 {
77 UserAuthenticatorUtils.cleanup(authData);
78 }
79 }
80
81 private FTPClient getFtpClient() throws FileSystemException
82 {
83 if (ftpClient == null)
84 {
85 ftpClient = createClient();
86 }
87
88 return ftpClient;
89 }
90
91 public boolean isConnected() throws FileSystemException
92 {
93 return getFtpClient().isConnected();
94 }
95
96 public void disconnect() throws IOException
97 {
98 try
99 {
100 getFtpClient().disconnect();
101 }
102 finally
103 {
104 ftpClient = null;
105 }
106 }
107
108 public FTPFile[] listFiles(String relPath) throws IOException
109 {
110 try
111 {
112 return getFtpClient().listFiles(relPath);
113 }
114 catch (IOException e)
115 {
116 disconnect();
117 return getFtpClient().listFiles(relPath);
118 }
119 }
120
121 public boolean removeDirectory(String relPath) throws IOException
122 {
123 try
124 {
125 return getFtpClient().removeDirectory(relPath);
126 }
127 catch (IOException e)
128 {
129 disconnect();
130 return getFtpClient().removeDirectory(relPath);
131 }
132 }
133
134 public boolean deleteFile(String relPath) throws IOException
135 {
136 try
137 {
138 return getFtpClient().deleteFile(relPath);
139 }
140 catch (IOException e)
141 {
142 disconnect();
143 return getFtpClient().deleteFile(relPath);
144 }
145 }
146
147 public boolean rename(String oldName, String newName) throws IOException
148 {
149 try
150 {
151 return getFtpClient().rename(oldName, newName);
152 }
153 catch (IOException e)
154 {
155 disconnect();
156 return getFtpClient().rename(oldName, newName);
157 }
158 }
159
160 public boolean makeDirectory(String relPath) throws IOException
161 {
162 try
163 {
164 return getFtpClient().makeDirectory(relPath);
165 }
166 catch (IOException e)
167 {
168 disconnect();
169 return getFtpClient().makeDirectory(relPath);
170 }
171 }
172
173 public boolean completePendingCommand() throws IOException
174 {
175 if (ftpClient != null)
176 {
177 return getFtpClient().completePendingCommand();
178 }
179
180 return true;
181 }
182
183 public InputStream retrieveFileStream(String relPath) throws IOException
184 {
185 try
186 {
187 return getFtpClient().retrieveFileStream(relPath);
188 }
189 catch (IOException e)
190 {
191 disconnect();
192 return getFtpClient().retrieveFileStream(relPath);
193 }
194 }
195
196 public InputStream retrieveFileStream(String relPath, long restartOffset) throws IOException
197 {
198 try
199 {
200 FTPClient client = getFtpClient();
201 client.setRestartOffset(restartOffset);
202 return client.retrieveFileStream(relPath);
203 }
204 catch (IOException e)
205 {
206 disconnect();
207
208 FTPClient client = getFtpClient();
209 client.setRestartOffset(restartOffset);
210 return client.retrieveFileStream(relPath);
211 }
212 }
213
214 public OutputStream appendFileStream(String relPath) throws IOException
215 {
216 try
217 {
218 return getFtpClient().appendFileStream(relPath);
219 }
220 catch (IOException e)
221 {
222 disconnect();
223 return getFtpClient().appendFileStream(relPath);
224 }
225 }
226
227 public OutputStream storeFileStream(String relPath) throws IOException
228 {
229 try
230 {
231 return getFtpClient().storeFileStream(relPath);
232 }
233 catch (IOException e)
234 {
235 disconnect();
236 return getFtpClient().storeFileStream(relPath);
237 }
238 }
239
240 public boolean abort() throws IOException
241 {
242 try
243 {
244
245
246
247
248
249 disconnect();
250 return true;
251 }
252 catch (IOException e)
253 {
254 disconnect();
255 }
256 return true;
257 }
258
259 public String getReplyString() throws IOException
260 {
261 return getFtpClient().getReplyString();
262 }
263 }