1
2
3
4
5
6
7 package org.astrogrid.store.delegate.ftp;
8 import org.astrogrid.store.delegate.*;
9
10 import java.io.*;
11
12 import java.net.MalformedURLException;
13 import java.net.URL;
14 import java.util.Enumeration;
15 import org.astrogrid.community.User;
16 import org.astrogrid.io.Piper;
17 import org.astrogrid.store.Agsl;
18 import sun.net.ftp.FtpClient;
19 import sun.net.ftp.FtpProtocolException;
20
21 /***
22 * An implenentation of myspace using an ordinary FTP server.
23 * <P>
24 * Developed using the built-in ftp clients supplied with java - but note
25 * that these are NOT supported directly.
26 * <P>
27 * Adapted from the ACE project
28 * <p>
29 * @deprecated - THIS HAS NOT BEEN PROPERLY MAINTAINED SINCE It04.1
30 */
31
32 public class FtpStore extends StoreDelegate {
33
34 private String server = null;
35 private int port = DEFAULT_PORT;
36 private String rootDir = "";
37 private URL endpoint = null;
38
39 private FullFtpClient ftpConnection = null;
40
41 private final static int DEFAULT_PORT = 21;
42
43 /***
44 * A more complete FTP client based on sun's
45 *
46 * @version 1.0, 01/19/97, 1.1 6/11/02
47 * @author Elliotte Rusty Harold, extended further by M C Hill
48 */
49 public class FullFtpClient extends FtpClient {
50
51 /*** New FullFtpClient connected to host <i>host</i>. */
52 public FullFtpClient(String host) throws IOException {
53 super(host);
54 }
55
56 /*** New FullFtpClient connected to host <i>host</i>, port <i>port</i>. */
57 public FullFtpClient(String host, int port) throws IOException {
58 super(host, port);
59 }
60
61 /*** Move up one directory in the ftp file system *
62 public void cdup() throws IOException {
63 issueCommandCheck("CDUP");
64 }
65
66 /** Create a new directory named s in the ftp file system */
67 public void mkdir(String s) throws IOException
68 {
69
70 issueCommandCheck("mkdir " + s);
71 }
72
73 /*** Ensure directory s exists - Create a new directory named s if it does not already exist */
74 public void endir(String s) throws IOException
75 {
76 try
77 {
78 mkdir(s);
79 }
80 catch (FtpProtocolException fpe)
81 {
82 if (fpe.getMessage().indexOf("521") == -1)
83 {
84 throw fpe;
85 }
86 }
87 }
88
89 /***
90 * Returns the URL of the given file in the given directory
91 */
92 public String getUrl(String directory, String filename) throws IOException
93 {
94 return "ftp://"+server+":"+port+directory+"/"+filename;
95 }
96
97 /***
98 * Returns the URL of the given file in the current directory
99 */
100 public String getUrl(String filename) throws IOException
101 {
102
103 return "ftp://"+server+":"+port+currentDir()+"/"+filename;
104 }
105
106 /*** Delete the specified directory from the ftp file system */
107 public void rmdir(String s) throws IOException {
108 issueCommandCheck("RMD " + s);
109 }
110
111 /*** Delete the file s from the ftp file system */
112 public void delete(String s) throws IOException {
113 issueCommandCheck("DELE " + s);
114 }
115
116 /*** Get the name of the present working directory on the ftp file system */
117 public String currentDir() throws IOException
118 {
119
120 issueCommandCheck("PWD");
121
122
123
124
125
126 String response = getResponseString();
127 return response.substring(response.indexOf('"'), response.lastIndexOf('"'));
128 }
129
130 /*** Move up a directory (there is a command for this is 1.4, but not 1.3 */
131 public void cdup() throws IOException {
132 issueCommandCheck("CD .. ");
133 }
134
135 /*** Move to given path. Path may include filename, so should end up in
136 * that directory */
137 public void cdPath(String targetPath) {
138 throw new UnsupportedOperationException();
139 }
140
141
142 public int issueCommand(String cmd) throws IOException
143 {
144 org.astrogrid.log.Log.trace("FTP>"+cmd);
145 return super.issueCommand(cmd);
146 }
147
148 public int readServerResponse() throws IOException
149 {
150 int result = super.readServerResponse();
151 for (Enumeration e = serverResponse.elements() ; e.hasMoreElements() ;)
152 {
153 org.astrogrid.log.Log.trace("FTP<"+e.nextElement());
154 }
155 return result;
156
157 }
158
159 public String toString()
160 {
161 return "Sun-derived FTP Client to "+server+":"+port;
162 }
163
164 }
165
166 /***
167 * Construct myspace client using given endpoint, which is a complete location, eg
168 * ftp://ftp.roe.ac.uk/pub/astrogrid
169 */
170 public FtpStore(User anOperator, URL ftpEndPoint) throws IOException
171 {
172 super(anOperator);
173 this.endpoint = ftpEndPoint;
174 server = ftpEndPoint.getHost();
175 port = ftpEndPoint.getPort();
176 if (port == -1) { port = DEFAULT_PORT; }
177
178 }
179
180 /***
181 * Construct myspace client using given Agsl
182 */
183 public FtpStore(User anOperator, Agsl agsl) throws IOException
184 {
185 this(anOperator, new URL(agsl.getEndpoint()));
186 }
187
188 /***
189 * Returns the endpoint
190 */
191 public Agsl getEndpoint() {
192 return new Agsl(endpoint);
193 }
194
195 /***
196 * Connect to server, get authorised and move to the directory to be used
197 * for temporary publications
198 */
199 public void connect() throws IOException
200 {
201 org.astrogrid.log.Log.trace("Connecting to "+this+"...");
202
203 try
204 {
205 ftpConnection = new FullFtpClient(server, port);
206 ftpConnection.login(getOperator().getUserId(), getOperator().getAccount());
207 ftpConnection.binary();
208
209 ftpConnection.cd(rootDir);
210 org.astrogrid.log.Log.trace("...logged on to "+ftpConnection
211 }
212 catch (IOException ioe)
213 {
214 IOException nioe = new IOException(ioe+" ("+ftpConnection.getResponseString()+")");
215 nioe.setStackTrace(ioe.getStackTrace());
216 ftpConnection = null;
217 throw nioe;
218 }
219 }
220
221 /***
222 * Disconnects from server, translating all faults into IOExceptions
223 */
224 public void disconnect() throws IOException
225 {
226 ftpConnection.closeServer();
227 ftpConnection = null;
228 }
229
230 /*** For debug, returns server & port */
231 public String toString()
232 {
233 return this.getClass()+" "+server+":"+port;
234 }
235 /***
236 * Copies given stream to server; subdir specifies the subdirectory the
237 * file will be placed in. That subdirectory will be created if it does
238 * not already exist.
239 * Returns the URL of the file on the server
240 */
241 public String pushStream(String targetPath, InputStream source, boolean append) throws IOException
242 {
243 assert ftpConnection != null : "Trying to publish before connecting. Call connect() before publicise(...)";
244
245 org.astrogrid.log.Log.trace("Publicise: Copying '"+source+"' to '"+server+"' as '"+targetPath+"'...");
246
247 ftpConnection.cdPath(targetPath);
248 String filename = new File(targetPath).getName();
249
250 OutputStream remoteOut;
251 if (append) {
252 remoteOut = ftpConnection.append(filename);
253 } else {
254 remoteOut = ftpConnection.put(filename);
255 }
256
257 Piper.bufferedPipe(source, remoteOut);
258 remoteOut.close();
259 source.close();
260
261 return ftpConnection.getUrl(ftpConnection.currentDir(), filename);
262 }
263
264 /***
265 * Publishes the given local file to the server (with the same name)
266 * Returns the URL of the file on the server
267 */
268 public String pushFile(String filename) throws IOException
269 {
270 return pushStream(filename, new FileInputStream(filename), false);
271 }
272
273 /***
274 * Gets the file identified by the remote string (this might be a url)
275 * and copy it to the local filename. If possible, it should only do this
276 * if required - ie if poss it should do some sort of time/date or
277 * checksum comparison. Returns full path to local file
278 */
279 public String updateFromServer(String remoteUrl, String localDir) throws IOException
280 {
281 org.astrogrid.log.Log.affirm(localDir.endsWith("/"), "'"+localDir+"' should terminate with a /");
282
283
284
285
286
287 int fni = remoteUrl.lastIndexOf('/');
288 String filename = remoteUrl.substring(fni+1);
289
290
291 int pdi = remoteUrl.lastIndexOf('/',fni-1);
292 String dir = remoteUrl.substring(pdi+1, fni);
293
294 org.astrogrid.log.Log.trace("Update: Copying '"+remoteUrl+"' to '"+localDir+"'...");
295
296 try
297 {
298 ftpConnection.cd(dir);
299 InputStream remoteIn = new BufferedInputStream(ftpConnection.get(filename));
300 OutputStream localOut = new BufferedOutputStream(new FileOutputStream(localDir+filename));
301
302
303 int i = 0;
304 while ((i = remoteIn.read()) != -1)
305 {
306 localOut.write((byte) i);
307 }
308 remoteIn.close();
309 localOut.close();
310
311 ftpConnection.cdup();
312 return localDir+filename;
313 }
314 catch (Exception e)
315 {
316 IOException ioe = new IOException(e+", getting '"+filename+"' from "+this);
317
318 ioe.fillInStackTrace();
319 throw ioe;
320 }
321 }
322
323
324 /***
325 * Returns a tree representation of the files that match the expression
326 */
327 public StoreFile getFiles(String filter) throws IOException {
328
329 throw new UnsupportedOperationException();
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349 }
350
351 /***
352 * Returns a list of the files that match the expression
353 */
354 public StoreFile[] getChildren(StoreFile folder, String filter) throws IOException {
355
356 throw new UnsupportedOperationException();
357
358 }
359
360 /***
361 * Returns the parent of the given file
362 */
363 public StoreFile getParent(StoreFile child) throws IOException {
364
365 throw new UnsupportedOperationException();
366
367 }
368
369 /***
370 * Returns the file corresponding to the path
371 */
372 public StoreFile getFile(String path) throws IOException {
373
374 throw new UnsupportedOperationException();
375
376 }
377
378
379
380 /***
381 * Streaming output - returns a stream that can be used to output to the given
382 * location
383 */
384 public OutputStream putStream(String targetPath, boolean append) throws IOException {
385 ftpConnection.cdPath(targetPath);
386 if (append) {
387 return ftpConnection.append(new File(targetPath).getName());
388 }
389 else {
390 return ftpConnection.put(new File(targetPath).getName());
391 }
392 }
393
394 /***
395 * Gets a file's contents as a stream
396 */
397 public InputStream getStream(String sourcePath) throws IOException {
398 return getUrl(sourcePath).openStream();
399 }
400
401 /***
402 * Create a container
403 */
404 public void newFolder(String targetPath) throws IOException {
405 ftpConnection.cdPath(new File(targetPath).getParent());
406 ftpConnection.mkdir(new File(targetPath).getName());
407 }
408
409 /***
410 * Delete a file
411 */
412 public void delete(String deletePath) throws IOException {
413 ftpConnection.delete(deletePath);
414 }
415
416 /***
417 * Gets the url to stream
418 */
419 public URL getUrl(String sourcePath) throws IOException {
420 ftpConnection.cdPath(sourcePath);
421 return new URL(ftpConnection.getUrl(new File(sourcePath).getName()));
422 }
423
424
425 }