View Javadoc

1   /*
2    * $Id: Agsl.java,v 1.5 2004/10/06 17:37:58 mch Exp $
3    *
4    * Copyright 2003 AstroGrid. All rights reserved.
5    *
6    * This software is published under the terms of the AstroGrid Software License,
7    * a copy of which has been included with this distribution in the LICENSE.txt file.
8    */
9   
10  package org.astrogrid.store;
11  
12  import java.io.IOException;
13  import java.io.InputStream;
14  import java.io.OutputStream;
15  import java.net.MalformedURLException;
16  import java.net.URI;
17  import java.net.URL;
18  import org.astrogrid.community.User;
19  import org.astrogrid.store.Ivorn;
20  import org.astrogrid.store.Msrl;
21  import org.astrogrid.store.delegate.StoreClient;
22  import org.astrogrid.store.delegate.StoreDelegateFactory;
23  import java.net.URISyntaxException;
24  
25  /***
26   * AstroGrid Storepoint Locator.  An astrogrid-specific way of <b>locating</b> a
27   * file (or the location to create a file) completely.
28   * <p>
29   * This contains all the information you
30   * need to identify a file in 'VoSpace' that can be reached through one of
31   * the StoreClient delegates
32   * <p>
33   * It is of the form:
34   * <pre>
35   *    astrogrid:store:{url}
36   * </pre>
37   *or
38   * <pre>
39   *    astrogrid:store:myspace:[{serverId}]{delegateendpoint}#{myspacepath}
40   * </pre>
41   *or (experimental)
42   * <pre>
43   *    astrogrid:store:mailto:{email address}
44   * </pre>
45   * <p>
46   * The path can be null, ie referring just to a store <i>service</i> rather than
47   * a file/folder on that service.
48   */
49  
50  public class Agsl
51  {
52     /*** Note that this is not a url to the file - as an ftp reference is split by fragment ftp://server/path#fileonserver
53      */
54     private URL url = null;
55     private Msrl msrl = null;
56     
57     public static final String SCHEME = "astrogrid:store";
58     
59     public static final String FORM = SCHEME+":[<Msrl>|<URL>][#path]";
60     
61     /*** Create an AGSL for a URL-based store point */
62     public Agsl(URL aUrl)
63     {
64        this.url = aUrl;
65     }
66  
67     /*** Create an AGSL for a myspace-based store point (might include file path) */
68     public Agsl(Msrl aMyspaceResourceLocation)
69     {
70        this.msrl = aMyspaceResourceLocation;
71     }
72  
73  
74  
75     /*** Makes a reference from the given endpoint (eg myspace:http://asdfasdf" target="alexandria_uri">http://asdfasdf or ftp://)
76      * and filepath
77      */
78     public Agsl(Msrl myspaceEndpoint, String path) throws MalformedURLException
79     {
80        init(myspaceEndpoint, path);
81     }
82  
83     /*** Makes a reference from the given endpoint (eg myspace:http://asdfasdf" target="alexandria_uri">http://asdfasdf or ftp://)
84      * and filepath
85      */
86     public Agsl(URL storepoint, String path) throws MalformedURLException
87     {
88        init(storepoint, path);
89     }
90  
91     /*** Makes a reference from the given storepoint location (eg astrogrid:store:myspace:http://asdfasdf" target="alexandria_uri">http://asdfasdf or astrogrid:store:ftp://)
92      * and filepath
93      */
94     public Agsl(Agsl storepoint, String path) throws MalformedURLException
95     {
96        init(storepoint, path);
97     }
98  
99     /*** Make a reference from the given string representation. Takes agsl forms,
100     * but also URLs and MSRLs. Also, for the moment, takes the deprecated VospaceRL
101     * from It4.1
102     * @deprecated - use typed ones
103     */
104    public Agsl(String rl) throws MalformedURLException
105    {
106       rl = rl.trim();
107       
108       //allow for mailto
109       if (rl.toLowerCase().startsWith("mailto:")) {
110          rl = "astrogrid:store:"+rl;
111       }
112       
113       //check it's valid
114       if (!rl.toLowerCase().startsWith(SCHEME+":")) {
115          throw new MalformedURLException("AGSL '"+rl+"' is not of the right form: "+FORM);
116       }
117 
118       rl = rl.substring(SCHEME.length()+1);
119       
120       if (Msrl.isMsrl(rl)) {
121          this.msrl = new Msrl(rl);
122       }
123       else {
124          this.url = new URL(rl);
125          
126          //for some reason if there is no slash in the authority, it picks up the first bit of the reference - up to the first #
127          if ((url.getAuthority() != null) && (url.getAuthority().indexOf("#")>-1)) {
128             url = new URL(url.getProtocol(),
129                           url.getHost().substring(0, url.getHost().indexOf('#')),
130                           url.getPort(),
131                           "#"+url.getRef());
132          }
133       }
134    }
135    
136    /***
137     * Initialises an AGSL out of the given myspace & path
138     */
139    private void init(Msrl myspacestore, String path)   {
140       if (myspacestore == null) throw new IllegalArgumentException("endpoint must not be null");
141       
142       if (myspacestore.getPath() != null) throw new IllegalArgumentException("endpoint '"+myspacestore+"' includes a file path");
143 
144       if (path == null) {
145          this.msrl = myspacestore;
146       }
147       else {
148          this.msrl = new Msrl(myspacestore.getDelegateEndpoint(), path);
149       }
150    }
151 
152    /***
153     * Initialises an AGSL from the given URL & path
154     */
155    private void init(URL storepoint, String path) throws MalformedURLException {
156       if (storepoint == null) throw new IllegalArgumentException("endpoint must not be null");
157       
158       if (storepoint.getRef() != null) throw new IllegalArgumentException("endpoint '"+storepoint+"' includes a fragment/reference");
159 
160       if (path==null) {
161          this.url = storepoint;
162       }
163       else {
164          this.url = new URL(storepoint+"#"+path);
165       }
166    }
167 
168    /***
169     * Initialises an AGSL from the given AGSL storepoint & path
170     */
171    private void init(Agsl storepoint, String path) throws MalformedURLException {
172       if (storepoint == null) throw new IllegalArgumentException("endpoint must not be null");
173       
174       if (storepoint.getPath() != null) throw new IllegalArgumentException("endpoint '"+storepoint+"' includes a path");
175 
176       if (Msrl.isMsrl(storepoint.getEndpoint())) {
177          init(new Msrl(storepoint.getEndpoint()), path);
178       }
179       else {
180          init(new URL(storepoint.getEndpoint()), path);
181       }
182    }
183 
184    /***
185     * This string must be reversable through the above constructor, ie for agsl string s:
186     *   new Vorl(s).toString().equals(s);
187     * must be true.  However, we can pass in ftp:// and myspace:// etc to the constructor
188     * so it won't always work...
189     */
190    public String toString() {
191       if (msrl != null) {
192          return SCHEME+":"+msrl.toString();
193       }
194       else {
195          return SCHEME+":"+url.toString();
196       }
197    }
198  
199    /*** Returns the AGSL in URI form */
200    public URI toUri() {
201       try {
202          return new URI(toString());
203       }
204       catch (URISyntaxException e) {
205          //this should never happen as it shouldn't be possible to create an agsl that isn't
206          throw new RuntimeException("Application error: "+e+" for AGSL "+toString());
207       }
208    }
209    
210    /*** Returns true if the given string is an attempt to be an agsl */
211    public static boolean isAgsl(String agsl)
212    {
213       return agsl.toLowerCase().startsWith(SCHEME+":") ||
214          agsl.toLowerCase().startsWith("vospace:"); //it04.1 scheme
215    }
216    
217    /*** Returns the myspace reference */
218 //   public Msrl getMsrl() { return msrl; }
219 
220    /*** Returns the delegate endpoint */
221    public String getEndpoint() {
222       if (url != null) {
223          return url.getProtocol()+"://"+url.getAuthority()+url.getPath();
224       }
225       else {
226          return Msrl.SCHEME+":"+msrl.getDelegateEndpoint().toString();
227       }
228    }
229    
230    /*** Returns the path (including filename) to the file on the server */
231    public String getPath() {
232       if (url != null) {
233          return url.getRef();
234       }
235       else {
236          return msrl.getPath();
237       }
238    }
239    
240    /*** Returns the filename */
241    public String getFilename() {
242       if (url != null) {
243          String path = url.getRef();
244          if (path != null) { //might refer to a server, ie no path
245             if (path.endsWith("/")) {
246                path = path.substring(0,path.length()-1); //chop off last slash
247             }
248             int slash = path.lastIndexOf("/");
249             return path.substring(slash+1);
250          }
251          else {
252             return null;
253          }
254       }
255       else {
256          return msrl.getFilename();
257       }
258    }
259    
260    /*** Opens an inputstream to the file.  Just like url.openStream().... but
261     * need to give User to authorise/etc
262     */
263    public InputStream openInputStream(User user) throws IOException {
264       StoreClient client = StoreDelegateFactory.createDelegate(user, this);
265       return client.getStream(getPath());
266       /***
267       if (url != null) {
268       not right
269          if (url.getProtocol().equals("file")) {
270             return new
271          }
272          else {
273             return url.openStream();
274          }
275       }
276       else {
277          return msrl.openInputStream();
278       }
279        */
280    }
281 
282    /*** Opens an outputstream to the file.
283     */
284    public OutputStream openOutputStream(User user) throws IOException {
285       StoreClient client = StoreDelegateFactory.createDelegate(user, this);
286       return client.putStream(getPath(), false);
287       /*
288       if (url != null) {
289          if (url.getProtocol().equals("file")) {
290             File f = new File(url.getFile());
291             return new FileOutputStream(f);
292          }
293          else {
294             throw new UnsupportedOperationException("Cannot (currently) open outputs to URLs");
295          }
296       }
297       else {
298          return msrl.openOutputStream();
299       }
300        */
301    }
302    
303    /***
304     * Returns a standard URL to the file.
305     */
306    public URL resolveURL() throws IOException {
307       
308       if (url != null) {
309          return url;
310       }
311       else {
312          return msrl.resolveURL();
313       }
314    }
315 
316    
317    /***
318     * Returns the full scheme, eg astrogrid:store:myspace, or astrogrid:store:ftp
319     */
320    public String getScheme() {
321       if (url != null) {
322          return SCHEME+":"+url.getProtocol();
323       }
324       else {
325          return SCHEME+":"+Msrl.SCHEME;
326       }
327    }
328    
329 
330    /*** Constructs an IVORN out of a user and this AGSL; ie assumes that
331     * the user has an account on a community server that is resolvable through
332     * a registry, and that the path on this agsl is the path to the storepoint
333     * resolved to by that community server
334     */
335    public Ivorn toIvorn(User user) {
336       return new Ivorn(user.getCommunity(), user.getUserId(), getPath());
337    }
338    
339    
340    /*** Tests that an AGSL is the same as another AGSL */
341    public boolean equals(Object anAgsl) {
342       return toString().equals(anAgsl.toString());
343    }
344    
345 }
346 
347 /*
348 $Log: Agsl.java,v $
349 Revision 1.5  2004/10/06 17:37:58  mch
350 Added toURI
351 
352 Revision 1.4  2004/07/06 19:37:19  mch
353 Removed Vorl
354 
355 Revision 1.3  2004/06/16 21:17:02  jdt
356 Merged from branch MySpace_JDT_BZ340
357 
358 Revision 1.2.2.1  2004/06/16 20:36:47  jdt
359 deleted a commented out method
360 
361 Revision 1.2  2004/06/14 23:08:53  jdt
362 Merge from branches
363 ClientServerSplit_JDT
364 and
365 MySpaceClientServerSplit_JDT
366 
367 MySpace now split into a client/delegate jar
368 astrogrid-myspace-<version>.jar
369 and a server/manager war
370 astrogrid-myspace-server-<version>.war
371 
372 Revision 1.1.2.1  2004/06/14 22:33:21  jdt
373 Split into delegate jar and server war.
374 Delegate: astrogrid-myspace-SNAPSHOT.jar
375 Server/Manager: astrogrid-myspace-server-SNAPSHOT.war
376 
377 Package names unchanged.
378 If you regenerate the axis java/wsdd/wsdl files etc you'll need
379 to move some files around to ensure they end up in the client
380 or the server as appropriate.
381 As of this check-in the tests/errors/failures is 162/1/22 which
382 matches that before the split.
383 
384 Revision 1.18  2004/05/19 16:24:33  mch
385 Properly typed Agsl creation, some fixes to tests
386 
387 Revision 1.17  2004/04/21 10:35:50  mch
388 Fixes to ivorn/fragment resolving
389 
390 Revision 1.16  2004/04/06 15:39:53  mch
391 Fixes for creating with nul path
392 
393 Revision 1.15  2004/04/01 15:16:36  mch
394 Added toIvorn() method
395 
396 Revision 1.14  2004/04/01 14:49:23  mch
397 change to javadoc
398 
399 Revision 1.13  2004/03/25 12:27:19  mch
400 Tidied doc
401 
402 Revision 1.12  2004/03/25 12:21:59  mch
403 Tidied doc
404 
405 Revision 1.11  2004/03/18 20:00:47  mch
406 Added trims
407 
408 Revision 1.10  2004/03/15 18:18:31  mch
409 Added file output
410 
411 Revision 1.9  2004/03/14 03:31:01  mch
412 Added openOutputStream
413 
414 Revision 1.8  2004/03/14 03:09:16  mch
415 Fixed nulpointer exception for mailto:
416 
417 Revision 1.7  2004/03/14 01:24:54  mch
418 Added experimental email target
419 
420 Revision 1.6  2004/03/09 23:18:58  mch
421 Added Vorl for 4.1 access
422 
423 Revision 1.5  2004/03/02 01:27:00  mch
424 Minor fixes
425 
426 Revision 1.4  2004/03/01 23:35:40  mch
427 Added getFilename
428 
429 Revision 1.3  2004/03/01 22:38:46  mch
430 Part II of copy from It4.1 datacenter + updates from myspace meetings + test fixes
431 
432 Revision 1.2  2004/03/01 16:38:58  mch
433 Merged in from datacenter 4.1 and odd cvs/case problems
434 
435 Revision 1.1  2004/03/01 16:24:05  mch
436 Merged in from datacenter 4.1
437 
438 Revision 1.3  2004/03/01 14:40:54  mch
439 Added backwards VospaceRL compatibility
440 
441 Revision 1.1  2004/02/24 15:59:56  mch
442 Moved It04.1 Datacenter VoSpaceClient stuff to myspace as StoreClient stuff
443 
444 Revision 1.1  2004/02/17 03:37:27  mch
445 Various fixes for demo
446 
447 Revision 1.1  2004/02/16 23:31:21  mch
448 Temporary Vospace Resource Location representation
449 
450 Revision 1.1  2004/02/15 23:16:06  mch
451 New-style VoSpace delegates.  Not agreed so private to datacenter for the moment
452 
453  */
454 
455