View Javadoc

1   package com.atlassian.marketplace.client.api;
2   
3   import java.io.UnsupportedEncodingException;
4   import java.net.URI;
5   import java.net.URLEncoder;
6   import java.util.Map;
7   import java.util.regex.Matcher;
8   import java.util.regex.Pattern;
9   
10  import com.atlassian.marketplace.client.model.Link;
11  import com.atlassian.marketplace.client.util.UriBuilder;
12  
13  import com.google.common.collect.ImmutableMap;
14  
15  /**
16   * A simple string wrapper that represents a URI template (RFC 6570).  The current implementation
17   * only provides for very simple expansion of template parameters.
18   * @see Link
19   */
20  public final class UriTemplate
21  {
22      private static final Pattern SIMPLE_PLACEHOLDER_REGEX = Pattern.compile("\\{([^}]*)\\}");
23      
24      private final String value;
25      
26      public static UriTemplate create(String value)
27      {
28          return new UriTemplate(value);
29      }
30      
31      private UriTemplate(String value)
32      {
33          this.value = value;
34      }
35  
36      /**
37       * Returns the template string.
38       */
39      public String getValue()
40      {
41          return value;
42      }
43      
44      /**
45       * Constructs a URI by substituting values for the named variable placeholders ("{name}" or {?queryName}")
46       * in the template.  Any placeholders that do not have a corresponding value in the "params" map will be
47       * left empty.
48       * @param params  map of placeholder names to values
49       * @return  a URI
50       */
51      public URI resolve(Map<String, String> params)
52      {
53          StringBuilder b = new StringBuilder();
54          int pos = 0;
55          Matcher m = SIMPLE_PLACEHOLDER_REGEX.matcher(value);
56          ImmutableMap.Builder<String, String> query = ImmutableMap.builder();
57          while (m.find()) {
58              b.append(value.substring(pos, m.start()));
59              String name = m.group(1);
60              if (name.startsWith("?"))
61              {
62                  for (String subName: name.substring(1).split(","))
63                  {
64                      String realName = subName.endsWith("*") ? subName.substring(0, subName.length() - 1) : subName;
65                      if (params.containsKey(realName))
66                      {
67                          query.put(realName, params.get(realName));
68                      }
69                  }
70              }
71              else
72              {
73                  String value = params.containsKey(name) ? params.get(name) : "";
74                  try
75                  {
76                      b.append(URLEncoder.encode(value, "UTF-8"));
77                  }
78                  catch (UnsupportedEncodingException e)
79                  {
80                      throw new RuntimeException(e); // UTF-8 should never be unavailable
81                  }
82              }
83              pos = m.end();
84          }
85          b.append(value.substring(pos));
86          UriBuilder ub = UriBuilder.fromUri(b.toString());
87          for (Map.Entry<String, String> e: query.build().entrySet())
88          {
89              ub.queryParam(e.getKey(), e.getValue());
90          }
91          return ub.build();
92      }
93      
94      @Override
95      public boolean equals(Object other)
96      {
97          return (other instanceof UriTemplate) && ((UriTemplate) other).value.equals(this.value);
98      }
99      
100     @Override
101     public int hashCode()
102     {
103         return value.hashCode();
104     }
105 }