1
2
3
4
5
6
7
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
109 if (rl.toLowerCase().startsWith("mailto:")) {
110 rl = "astrogrid:store:"+rl;
111 }
112
113
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
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
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:");
215 }
216
217 /*** Returns the myspace reference */
218
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) {
245 if (path.endsWith("/")) {
246 path = path.substring(0,path.length()-1);
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
289
290
291
292
293
294
295
296
297
298
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
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455