View Javadoc

1   /*
2    * <cvs:source>$Source: /devel/astrogrid/community/common/src/java/org/astrogrid/community/common/ivorn/CommunityIvornParser.java,v $</cvs:source>
3    * <cvs:author>$Author: jdt $</cvs:author>
4    * <cvs:date>$Date: 2004/11/22 13:03:04 $</cvs:date>
5    * <cvs:version>$Revision: 1.11 $</cvs:version>
6    *
7    * <cvs:log>
8    *   $Log: CommunityIvornParser.java,v $
9    *   Revision 1.11  2004/11/22 13:03:04  jdt
10   *   Merges from Comm_KMB_585
11   *
12   *   Revision 1.10.22.1  2004/11/02 11:49:39  KevinBenson
13   *   deleted a commented out line
14   *
15   *   Revision 1.10  2004/09/16 23:18:08  dave
16   *   Replaced debug logging in Community.
17   *   Added stream close() to FileStore.
18   *
19   *   Revision 1.9.82.1  2004/09/16 09:58:48  dave
20   *   Replaced debug with commons logging ....
21   *
22   *   Revision 1.9  2004/06/18 13:45:20  dave
23   *   Merged development branch, dave-dev-200406081614, into HEAD
24   *
25   *   Revision 1.8.18.2  2004/06/17 14:50:01  dave
26   *   Removed unused imports (PMD report).
27   *
28   *   Revision 1.8.18.1  2004/06/17 13:38:58  dave
29   *   Tidied up old CVS log entries
30   *
31   * </cvs:log>
32   *
33   */
34  package org.astrogrid.community.common.ivorn ;
35  
36  import org.apache.commons.logging.Log ;
37  import org.apache.commons.logging.LogFactory ;
38  
39  import java.net.URI ;
40  import java.net.URISyntaxException ;
41  
42  import java.util.regex.Matcher ;
43  import java.util.regex.Pattern ;
44  
45  import org.astrogrid.store.Ivorn ;
46  import org.astrogrid.common.ivorn.MockIvorn ;
47  
48  import org.astrogrid.config.Config ;
49  import org.astrogrid.config.SimpleConfig ;
50  import org.astrogrid.config.PropertyNotFoundException ;
51  
52  import org.astrogrid.community.common.exception.CommunityServiceException ;
53  import org.astrogrid.community.common.exception.CommunityIdentifierException ;
54  
55  /***
56   * A parser for handling Ivorn identifiers.
57   *
58   */
59  public class CommunityIvornParser
60      {
61      /***
62       * Our debug logger.
63       *
64       */
65  	private static Log log = LogFactory.getLog(CommunityIvornParser.class);
66  
67      /***
68       * Our AstroGrid configuration.
69       *
70       */
71      protected static Config config = SimpleConfig.getSingleton() ;
72  
73      /***
74       * Public constructor for a specific Ivorn.
75       * @param ivorn A vaild Ivorn identifier.
76       * @throws CommunityIdentifierException If the identifier is not valid.
77       *
78       */
79      public CommunityIvornParser(Ivorn ivorn)
80          throws CommunityIdentifierException
81          {
82          this.setIvorn(ivorn) ;
83          }
84  
85      /***
86       * Public constructor for a specific identifier.
87       * @param ident A vaild identifier.
88       * @throws CommunityIdentifierException If the identifier is not valid.
89       *
90       */
91      public CommunityIvornParser(String ident)
92          throws CommunityIdentifierException
93          {
94          this.setIvorn(
95              parse(ident)
96              ) ;
97          }
98  
99      /***
100      * Our target Ivorn.
101      *
102      */
103     private Ivorn ivorn ;
104 
105     /***
106      * Our corresponding URI.
107      *
108      */
109     private URI uri ;
110 
111     /***
112      * The community ident part.
113      *
114      */
115     private String community ;
116 
117     /***
118      * The account ident part.
119      *
120      */
121     private String account ;
122 
123     /***
124      * The remaining path, after the account ident has been removed.
125      *
126      */
127     private String path ;
128 
129     /***
130      * The URI query string.
131      *
132      */
133     private String query ;
134 
135     /***
136      * The remaining fragment, after the account ident has been removed.
137      *
138      */
139     private String fragment ;
140 
141     /***
142      * Get our target Ivorn.
143      *
144      */
145     public Ivorn getIvorn()
146         {
147         return this.ivorn ;
148         }
149 
150     /***
151      * Set our target Ivorn.
152      * @param A vaild Ivorn identifier.
153      * @throws CommunityIdentifierException If the identifier is not valid.
154      *
155      */
156     protected void setIvorn(Ivorn ivorn)
157         throws CommunityIdentifierException
158         {
159         log.debug("") ;
160         log.debug("----\"----") ;
161         log.debug("CommunityIvornParser.setIvorn()") ;
162         log.debug("  Ivorn : " + ivorn) ;
163         //
164         // Check for null param.
165         if (null == ivorn)
166             {
167             throw new CommunityIdentifierException(
168                 "Null identifier"
169                 ) ;
170             }
171         //
172         // Save the ivorn.
173         this.ivorn     = ivorn ;
174         //
175         // Reset everything else.
176         this.uri       = null  ;
177         this.account   = null ;
178         this.community = null ;
179         this.path      = null ;
180         this.fragment  = null ;
181         //
182         // Try convert it into a URI.
183         try {
184             this.uri = new URI(ivorn.toString()) ;
185             //
186             // Parse the Community ident.
187             this.parseCommunityIdent() ;
188             //
189             // Parse Account ident.
190             this.parseAccountIdent() ;
191             }
192         //
193         // All Ivorn should be valid URI.
194         catch (URISyntaxException ouch)
195             {
196             throw new CommunityIdentifierException(
197                 ouch
198                 ) ;
199             }
200         }
201 
202     /***
203      * Parse the Community ident.
204      *
205      */
206     protected void parseCommunityIdent()
207         {
208         log.debug("") ;
209         log.debug("----\"----") ;
210         log.debug("CommunityIvornParser.parseCommunityIdent()") ;
211         log.debug("  Ivorn     : " + ivorn) ;
212         if (null != uri)
213             {
214             this.community = uri.getHost() ;
215             }
216         log.debug("  Community : " + this.community) ;
217         }
218 
219     /***
220      * Get the Community name as a string.
221      * @return The Community name, or null if no match was found.
222      *
223      */
224     public String getCommunityName()
225         {
226         return this.community ;
227         }
228 
229     /***
230      * Get the Community ident as a string.
231      * @return The Community ident, or null if no match was found.
232      *
233      */
234     public String getCommunityIdent()
235         {
236         return new StringBuffer()
237             .append(Ivorn.SCHEME)
238             .append("://")
239             .append(this.community)
240             .toString() ;
241         }
242 
243     /***
244      * Get the Community ident as a new Ivorn.
245      * @return A new Ivorn, or null if the Community ident is null.
246      *
247      */
248     public Ivorn getCommunityIvorn()
249         {
250         //
251         // If we have a community ident.
252         if (null != this.getCommunityIdent())
253             {
254             //
255             // Create a new Ivorn.
256             return new Ivorn(
257                 this.getCommunityName(),
258                 null
259                 ) ;
260             }
261         //
262         // If we don't have a community ident.
263         else {
264             return null ;
265             }
266         }
267 
268     /***
269      * Our regex pattern.
270      *
271      */
272     private static Pattern pattern ;
273     static {
274         try {
275             pattern = Pattern.compile("^/?([^/]+)/?(.*)") ;
276             }
277         catch (Exception ouch)
278             {
279             //
280             // Log this as a fatal error.
281             log.debug("ERROR ----") ;
282             log.debug("CommunityIvornParser RegExp pattern is not valid.") ;
283             log.debug(ouch) ;
284             log.debug("----------") ;
285             }
286         }
287 
288     /***
289      * Parse the Account ident.
290      *
291      */
292     protected void parseAccountIdent()
293         {
294         log.debug("") ;
295         log.debug("----\"----") ;
296         log.debug("CommunityIvornParser.parseAccountIdent()") ;
297         log.debug("  Ivorn : " + ivorn) ;
298         //
299         // Set all of the parts to null.
300         this.account   = null ;
301         this.path      = null ;
302         this.query     = null ;
303         this.fragment  = null ;
304         //
305         // If we have a valid URI.
306         if (null != uri)
307             {
308             //
309             // Try the user part.
310             this.account  = uri.getUserInfo() ;
311             //
312             // If we got the account from the URI user.
313             if (null != this.account)
314                 {
315                 //
316                 // The path and fragment are left unchanged.
317                 if (null != uri.getPath())
318                     {
319                     //
320                     // If there is anything in the path.
321                     if (uri.getPath().length() > 0)
322                         {
323                         //
324                         // Check for a leading '/'
325                         if (uri.getPath().startsWith("/"))
326                             {
327                             //
328                             // If there is anything else.
329                             if (uri.getPath().length() > 1)
330                                 {
331                                 //
332                                 // Use anything after the '/'
333                                 this.path = uri.getPath().substring(1) ;
334                                 }
335                             }
336                         else {
337                             //
338                             // Use the path as-is.
339                             this.path = uri.getPath() ;
340                             }
341                         }
342                     }
343                 //
344                 // If there is anything in the fragment.
345                 if (null != uri.getFragment())
346                     {
347                     if (uri.getFragment().length() > 0)
348                         {
349                         //
350                         // Use the fragment as-is.
351                         this.fragment = uri.getFragment() ;
352                         }
353                     }
354                 }
355             //
356             // If we didn't get the account from the URI user.
357             else {
358                 //
359                 // If we have a path.
360                 if (null != uri.getPath())
361                     {
362                     //
363                     // Try parse the path.
364                     this.parseAccountPath() ;
365                     }
366                 //
367                 // If we don't have a path.
368                 else {
369                     //
370                     // Try parse the fragment.
371                     this.parseAccountFragment() ;
372                     }
373                 }
374             //
375             // The query string is untouched.
376             if (null != uri.getQuery())
377                 {
378                 if (uri.getQuery().length() > 0)
379                     {
380                     this.query = uri.getQuery() ;
381                     }
382                 }
383             }
384         log.debug(" Account   : " + this.account) ;
385         log.debug(" Path      : " + this.path) ;
386         log.debug(" Query     : " + this.query) ;
387         log.debug(" Fragment  : " + this.fragment) ;
388         }
389 
390     /***
391      * Parse the URI path for the Account ident.
392      *
393      */
394     protected void parseAccountPath()
395         {
396         log.debug("") ;
397         log.debug("----\"----") ;
398         log.debug("CommunityIvornParser.parseAccountPath()") ;
399         log.debug("  Ivorn : " + ivorn) ;
400         log.debug("  Path  : " + uri.getPath()) ;
401         //
402         // If we have a path.
403         if (null != uri.getPath())
404             {
405             //
406             // Try match the path.
407             Matcher matcher = pattern.matcher(uri.getPath()) ;
408             //
409             // If we got a match.
410             if (matcher.matches())
411                 {
412                 //
413                 // If we found an account.
414                 if (matcher.groupCount() > 0)
415                     {
416                     //
417                     // Use the first match as our account.
418                     this.account = matcher.group(1) ;
419                     }
420                 //
421                 // If we found anything else.
422                 if (matcher.groupCount() > 1)
423                     {
424                     //
425                     // Strip spaces from the remainder.
426                     String temp = matcher.group(2).trim() ;
427                     if (temp.length() > 0)
428                         {
429                         //
430                         // Save anything left over as the path.
431                         this.path = temp ;
432                         }
433                     }
434                 //
435                 // The fragment remains unchanged.
436                 this.fragment = uri.getFragment() ;
437                 }
438             //
439             // If we didn't get a match.
440             else {
441                 //
442                 // Try parse the fragment.
443                 this.parseAccountFragment() ;
444                 }
445             }
446         }
447 
448     /***
449      * Parse the URI fragment for the Account ident.
450      *
451      */
452     protected void parseAccountFragment()
453         {
454         log.debug("") ;
455         log.debug("----\"----") ;
456         log.debug("CommunityIvornParser.parseAccountFragment()") ;
457         log.debug("  Ivorn    : " + ivorn) ;
458         log.debug("  Fragment : " + uri.getFragment()) ;
459         //
460         // If we have a fragment.
461         if (null != uri.getFragment())
462             {
463             //
464             // Try match the fragment.
465             Matcher matcher = pattern.matcher(uri.getFragment()) ;
466             //
467             // If we got a match.
468             if (matcher.matches())
469                 {
470                 //
471                 // If we found an account.
472                 if (matcher.groupCount() > 0)
473                     {
474                     //
475                     // Use the first match as our account.
476                     this.account = matcher.group(1) ;
477                     }
478                 //
479                 // If we found anything else.
480                 if (matcher.groupCount() > 1)
481                     {
482                     //
483                     // Save the rest as the fragment.
484                     //
485                     // Strip spaces from the remainder.
486                     String temp = matcher.group(2).trim() ;
487                     if (temp.length() > 0)
488                         {
489                         //
490                         // Save anything left over as the fragment.
491                         this.fragment = temp ;
492                         }
493                     }
494                 }
495             }
496         }
497 
498     /***
499      * Get the Account name as a string.
500      * This will contain just the account name, without the community identifier.
501      * @return The Account name, or null if no match was found.
502      *
503      */
504     public String getAccountName()
505         {
506         return this.account ;
507         }
508 
509     /***
510      * Get the Account ident as a string.
511      * This will contain both the community ident and account name, 'community/account' 
512      * @return The Account ident, or null if no match was found.
513      * @todo Should this add 'ivo://' to the ident ?
514      *
515      */
516     public String getAccountIdent()
517         {
518         if ((null != this.getCommunityIdent()) && (null != this.getAccountName()))
519             {
520             return new StringBuffer()
521                 .append(this.getCommunityIdent())
522                 .append("/")
523                 .append(this.getAccountName())
524                 .toString() ;
525             }
526         else {
527             return null ;
528             }
529         }
530 
531     /***
532      * Get the Account Ivorn.
533      * This will contain both the community ident and account name, 'ivo://community/account' 
534      * @return A new Ivorn, or null if the Community or Account ident are null.
535      *
536      */
537     public Ivorn getAccountIvorn()
538         throws CommunityIdentifierException
539         {
540         if ((null != this.getCommunityIdent()) && (null != this.getAccountName()))
541             {
542             return CommunityAccountIvornFactory.createIvorn(
543                 this.getCommunityName(),
544                 this.getAccountName()
545                 ) ;
546             }
547         else {
548             return null ;
549             }
550         }
551 
552     /***
553      * Get the rest of the path, after the Account ident has been removed.
554      * @return The remaining URI path, or null if there is nothing left. 
555      *
556      */
557     protected String getPath()
558         {
559         return path ;
560         }
561 
562     /***
563      * Get the query, after the Account ident has been removed.
564      * @return The remaining URI query, or null if there is nothing left. 
565      *
566      */
567     protected String getQuery()
568         {
569         return query ;
570         }
571 
572     /***
573      * Get the rest of fragment, after the Account ident has been removed.
574      * @return The remaining URI fragment, or null if there is nothing left. 
575      *
576      */
577     protected String getFragment()
578         {
579         return fragment ;
580         }
581 
582     /***
583      * Get the remaining URI string, including the path, query and fragment,
584      * after the account has been removed
585      * @return The remaining URI string, or null if there is nothing left. 
586      *
587      */
588     public String getRemainder()
589         {
590         StringBuffer buffer = new StringBuffer() ;
591         //
592         // If we have a path.
593         if (null != this.path)
594             {
595             buffer.append("/") ;
596             buffer.append(this.path) ;
597             }
598         //
599         // If we have a query.
600         if (null != this.query)
601             {
602             buffer.append("?") ;
603             buffer.append(this.query) ;
604             }
605         //
606         // If we have a fragment.
607         if (null != this.fragment)
608             {
609             buffer.append("#") ;
610             buffer.append(this.fragment) ;
611             }
612         //
613         // Return the string, or null if it is empty.
614         return (buffer.length() > 0) ? buffer.toString() : "" ;
615         }
616 
617     /***
618      * Checks if the Ivorn is a mock identifier.
619      * @return true if the Ivorn is a mock identifier.
620      *
621      */
622     public boolean isMock()
623         {
624         return (
625             MockIvorn.isMock(this.ivorn)
626             ) ;
627         }
628 
629     /***
630      * Convert a string identifier into an Ivorn.
631      * @param ident The identifier.
632      * @return a new Ivorn containing the identifier.
633      * @throws CommunityIdentifierException If the identifier is invalid.
634      *
635      */
636     protected static Ivorn parse(String ident)
637         throws CommunityIdentifierException
638         {
639         if (null == ident)
640             {
641             throw new CommunityIdentifierException(
642                 "Null identifier"
643                 ) ;
644             }
645         try {
646             return new Ivorn(ident) ;
647             }
648         catch (URISyntaxException ouch)
649             {
650             throw new CommunityIdentifierException(
651                 ouch
652                 ) ;
653             }
654         }
655 
656     /***
657      * The property name for our local Community identifier.
658      *
659      */
660     public static final String LOCAL_COMMUNITY_PROPERTY = "org.astrogrid.community.ident" ;
661 
662     /***
663      * Access to the local Community identifier.
664      * @throws CommunityServiceException If the local Community identifier is not set.
665      *
666      */
667     public static String getLocalIdent()
668         throws CommunityServiceException
669         {
670         log.debug("") ;
671         log.debug("----\"----") ;
672         log.debug("CommunityIvornParser.getLocalIdent()") ;
673         try {
674             //
675             // Get the local identifier from our configuration.
676             String local = (String) config.getProperty(LOCAL_COMMUNITY_PROPERTY) ;
677             log.debug("  Local : " + local) ;
678             //
679             // If we found the local ident.
680             if (null != local)
681                 {
682                 return local ;
683                 }
684             //
685             // If we didn't find the local ident.
686             else {
687                 throw new CommunityServiceException(
688                     "Local Community identifier not configured"
689                     ) ;
690                 }
691             }
692         catch (PropertyNotFoundException ouch)
693             {
694             throw new CommunityServiceException(
695                 "Local Community identifier not configured"
696                 ) ;
697             }
698         }
699 
700     /***
701      * Check if the Community ident is local.
702      * @return true If the Ivorn Community matches the local Community identifier.
703      * @throws CommunityServiceException If the local Community identifier is not set.
704      *
705      */
706     public boolean isLocal()
707         throws CommunityServiceException
708         {
709         log.debug("") ;
710         log.debug("----\"----") ;
711         log.debug("CommunityIvornParser.isLocal()") ;
712         log.debug("  Ivorn : " + ivorn) ;
713         //
714         // Compare the ident.
715         return getLocalIdent().equals(
716             this.getCommunityName()
717             ) ;
718         }
719 
720     /***
721      * Convert the parser to a String.
722      *
723      */
724     public String toString()
725         {
726         return "CommunityIvornParser : " + ((null != ivorn) ? ivorn.toString() : null) ;
727         }
728 
729     }