View Javadoc

1   package com.atlassian.marketplace.client.model;
2   
3   import java.net.URI;
4   import java.util.Map;
5   
6   import com.atlassian.fugue.Option;
7   import com.atlassian.marketplace.client.api.UriTemplate;
8   
9   import com.google.common.collect.ImmutableList;
10  import com.google.common.collect.ImmutableMap;
11  
12  import static com.atlassian.fugue.Option.none;
13  import static com.atlassian.fugue.Option.option;
14  import static com.atlassian.fugue.Option.some;
15  
16  /**
17   * A links map in the HAL-JSON format used by the Marketplace version 2 API.  For each link rel (key),
18   * there can be either a single URI, a single URI template, or an array of either.  Example of a
19   * valid links map:
20   * <code>
21   *   {
22   *     "simple": { "href": "/uri" },
23   *     "multiple": [ { "href": "/uri1" }, { "href": "/uri2" } ],
24   *     "withContentType": { "href": "/uri", "type": "text/html" },
25   *     "isATemplate": { "href": "/uri/{var}", "templated": true }
26   *   }
27   * </code>
28   */
29  public final class Links
30  {
31      public static final String REST_TYPE = "application/json";
32      public static final String WEB_TYPE = "text/html";
33  
34      private final Map<String, ImmutableList<Link>> items;
35  
36      public Links(Map<String, ImmutableList<Link>> items)
37      {
38          this.items = ImmutableMap.copyOf(items);
39      }
40  
41      /**
42       * Used internally.
43       */
44      public Map<String, ImmutableList<Link>> getItems()
45      {
46          return items;       
47      }
48  
49      URI requireUri(String rel)
50      {
51          for (URI uri: getUri(rel))
52          {
53              return uri;
54          }
55          throw new IllegalArgumentException("missing required REST link: " + rel);
56      }
57      
58      /**
59       * Returns the first {@link Link} matching the given key, if any.
60       */
61      public Option<Link> getLink(String rel)
62      {
63          for (Link link: getLinks(rel))
64          {
65              return some(link);
66          }
67          return none();
68      }
69  
70      /**
71       * Returns the first {@link Link} matching the given key and the given content type, if any.
72       */
73      public Option<Link> getLink(String rel, String contentType)
74      {
75          for (Link link: getLinks(rel))
76          {
77              if (link.getType().isEmpty() && contentType.equals(REST_TYPE))
78              {
79                  return some(link);
80              }
81              for (String type: link.getType())
82              {
83                  if (type.equalsIgnoreCase(contentType))
84                  {
85                      return some(link);
86                  }
87              }
88          }
89          return none();
90      }
91  
92      /**
93       * Returns every {@link Link} that matches the given key.
94       */
95      public Iterable<Link> getLinks(String rel)
96      {
97          return option(items.get(rel)).getOrElse(ImmutableList.<Link>of());
98      }
99  
100     /**
101      * Shortcut for getting the URI of the first {@link Link} that matches the given key.
102      */
103     public Option<URI> getUri(String rel)
104     {
105         for (Link link: getLink(rel))
106         {
107             return some(link.getUri());
108         }
109         return none();
110     }
111 
112     /**
113      * Shortcut for getting the URI of the first {@link Link} that matches the given key and content type.
114      */
115     public Option<URI> getUri(String rel, String contentType)
116     {
117         for (Link link: getLink(rel, contentType))
118         {
119             return some(link.getUri());
120         }
121         return none();
122     }
123 
124     /**
125      * Shortcut for getting the template of the first {@link Link} that matches the given key,
126      * if it is a template.
127      */
128     public Option<UriTemplate> getUriTemplate(String rel)
129     {
130         for (Link link: getLink(rel))
131         {
132             return link.getUriTemplate();
133         }
134         return none();
135     }
136     
137     /**
138      * Shortcut for getting the template of the first {@link Link} that matches the given key
139      * and content type, if it is a template.
140      */
141     public Option<UriTemplate> getUriTemplate(String rel, String contentType)
142     {
143         for (Link link: getLink(rel, contentType))
144         {
145             return link.getUriTemplate();
146         }
147         return none();
148     }
149 }