View Javadoc

1   package com.atlassian.marketplace.client.model;
2   
3   import java.net.URI;
4   
5   import com.atlassian.fugue.Either;
6   import com.atlassian.fugue.Option;
7   import com.atlassian.marketplace.client.api.UriTemplate;
8   
9   import com.google.common.base.Function;
10  import com.google.common.base.Functions;
11  import com.google.common.collect.ImmutableMap;
12  
13  import org.apache.commons.lang.ObjectUtils;
14  
15  import static com.atlassian.marketplace.client.model.Links.REST_TYPE;
16  
17  /**
18   * A resource/web hyperlink in the HAL-JSON format used by the Marketplace version 2 API.
19   * A HAL link can be either a URI or a a {@link UriTemplate}.
20   */
21  public final class Link
22  {
23      private final Option<String> type;
24      final Either<UriTemplate, URI> templateOrUri;
25  
26      public Link(Either<UriTemplate, URI> templateOrUri, Option<String> type)
27      {
28          this.templateOrUri = templateOrUri;
29          this.type = type;
30      }
31  
32      public static Link fromUri(URI uri, Option<String> type)
33      {
34          return new Link(Either.<UriTemplate, URI>right(uri), type);
35      }
36      
37      public static Link fromUriTemplate(UriTemplate ut, Option<String> type)
38      {
39          return new Link(Either.<UriTemplate, URI>left(ut), type);
40      }
41      
42      /**
43       * Returns the link URI (the "href" attribute) if it is a URI; if it is a template,
44       * converts it to a URI by removing all variable parameters.
45       */
46      public URI getUri()
47      {
48          return templateOrUri.fold(
49              new Function<UriTemplate, URI>()
50              {
51                  public URI apply(UriTemplate t)
52                  {
53                      return t.resolve(ImmutableMap.<String, String>of());
54                  }
55              },
56              Functions.<URI>identity()
57          );
58      }
59      
60      /**
61       * Returns the link URI template if it is a template, or {@link Option#none()} if it is a
62       * normal URI.
63       */
64      public Option<UriTemplate> getUriTemplate()
65      {
66          return templateOrUri.left().toOption();
67      }
68      
69      public Either<UriTemplate, URI> getTemplateOrUri()
70      {
71          return templateOrUri;
72      }
73      
74      /**
75       * Returns the optional "type" attribute, indicating the media type of the linked resource.
76       * If this is {@link Option#none()}, assume that the resource contains JSON.
77       */
78      public Option<String> getType()
79      {
80          return type;
81      }
82      
83      public boolean matchType(Option<String> desiredType)
84      {
85          for (String dt: desiredType)
86          {
87              return type == null ? dt.equals(REST_TYPE) : dt.equals(type); 
88          }
89          return true;
90      }
91      
92      /**
93       * Returns the link URI or link template as a string.
94       */
95      public String stringValue()
96      {
97          for (UriTemplate ut: getUriTemplate())
98          {
99              return ut.getValue();
100         }
101         return getUri().toASCIIString();
102     }
103     
104     @Override
105     public boolean equals(Object other)
106     {
107         if (other instanceof Link)
108         {
109             Link o = (Link) other;
110             return templateOrUri.equals(o.templateOrUri) &&
111                 ObjectUtils.equals(type, o.type);
112         }
113         return false;
114     }
115     
116     @Override
117     public int hashCode()
118     {
119         return templateOrUri.hashCode() + ((type == null) ? 0 : type.hashCode());
120     }
121 }