View Javadoc

1   package com.atlassian.marketplace.client.impl;
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.MpacException;
8   import com.atlassian.marketplace.client.api.AddonQuery;
9   import com.atlassian.marketplace.client.api.AddonVersionSpecifier;
10  import com.atlassian.marketplace.client.api.AddonVersionsQuery;
11  import com.atlassian.marketplace.client.api.Addons;
12  import com.atlassian.marketplace.client.api.Page;
13  import com.atlassian.marketplace.client.api.PageReference;
14  import com.atlassian.marketplace.client.api.PricingType;
15  import com.atlassian.marketplace.client.api.UriTemplate;
16  import com.atlassian.marketplace.client.http.SimpleHttpResponse;
17  import com.atlassian.marketplace.client.model.Addon;
18  import com.atlassian.marketplace.client.model.AddonPricing;
19  import com.atlassian.marketplace.client.model.AddonReference;
20  import com.atlassian.marketplace.client.model.AddonSummary;
21  import com.atlassian.marketplace.client.model.AddonVersion;
22  import com.atlassian.marketplace.client.model.AddonVersionSummary;
23  import com.atlassian.marketplace.client.util.UriBuilder;
24  
25  import com.google.common.base.Function;
26  import com.google.common.collect.ImmutableMap;
27  
28  import org.apache.commons.io.input.NullInputStream;
29  
30  import static com.atlassian.fugue.Option.none;
31  import static com.atlassian.fugue.Option.some;
32  import static com.atlassian.marketplace.client.impl.ApiHelper.JSON;
33  import static com.atlassian.marketplace.client.impl.ApiHelper.getTemplatedLink;
34  import static com.atlassian.marketplace.client.impl.ApiHelper.withAccessToken;
35  import static com.atlassian.marketplace.client.impl.ApiHelper.withZeroLimit;
36  
37  final class AddonsImpl extends ApiImplBase implements Addons
38  {
39      AddonsImpl(ApiHelper apiHelper, InternalModel.MinimalLinks root) throws MpacException
40      {
41          super(apiHelper, root, "addons");
42      }
43  
44      @Override
45      public Option<Addon> getByKey(String addonKey, AddonQuery query) throws MpacException
46      {
47          InternalModel.Addons collectionRep = getEmptyBaseCollectionRep();
48          UriTemplate byKeyTemplate = ApiHelper.requireLinkUriTemplate(collectionRep.getLinks(), "byKey", InternalModel.Addons.class);
49          UriBuilder uri = UriBuilder.fromUri(byKeyTemplate.resolve(ImmutableMap.of("addonKey", addonKey)));
50          ApiHelper.addAddonQueryParams(query, uri);
51          return apiHelper.getOptionalEntity(uri.build(), Addon.class);
52      }
53      
54      @Override
55      public Page<AddonSummary> find(AddonQuery query) throws MpacException
56      {
57          final UriBuilder uri = fromApiRoot();
58          ApiHelper.addAddonQueryParams(query, uri);
59          return apiHelper.getMore(new PageReference<AddonSummary>(
60              uri.build(), query.getBounds(), pageReader(InternalModel.Addons.class)));
61      }
62  
63      @Override
64      public Addon createAddon(Addon addon) throws MpacException
65      {
66          // When we query the newly created add-on, we need to add withVersion=true to ensure that you also
67          // get the version (since you were required to provide an initial version when you created it)
68          Function<URI, URI> resultUriTransform = new Function<URI, URI>()
69          {
70              @Override
71              public URI apply(URI uri)
72              {
73                  return UriBuilder.fromUri(uri).queryParam("withVersion", true).build();
74              }
75          }; 
76          return genericCreate(getApiRoot(), addon, resultUriTransform);
77      }
78      
79      @Override
80      public Addon updateAddon(Addon original, Addon updated) throws MpacException
81      {
82          return genericUpdate(original.getSelfUri(), original, updated);
83      }
84      
85      @Override
86      public Option<AddonVersion> getVersion(String addonKey, AddonVersionSpecifier version, AddonVersionsQuery query) throws MpacException
87      {
88          for (Addon a: getByKey(addonKey, AddonQuery.builder().accessToken(query.getAccessToken()).build()))
89          {
90              UriBuilder uri = UriBuilder.fromUri(getVersionUri(a, version));
91              ApiHelper.addAddonVersionsQueryParams(query, uri);
92              return apiHelper.getOptionalEntity(uri.build(), AddonVersion.class);
93          }
94          return none();
95      }
96  
97      @Override
98      public Page<AddonVersionSummary> getVersions(String addonKey, AddonVersionsQuery query) throws MpacException
99      {
100         for (Addon a: getByKey(addonKey, AddonQuery.builder().accessToken(query.getAccessToken()).build()))
101         {
102             UriBuilder uri = UriBuilder.fromUri(getVersionsUri(a));
103             ApiHelper.addAddonVersionsQueryParams(query, uri);
104             return apiHelper.getMore(new PageReference<AddonVersionSummary>(
105                 uri.build(), query.getBounds(), pageReader(InternalModel.AddonVersions.class)));
106         }
107         return Page.empty();
108     }
109     
110     @Override
111     public AddonVersion createVersion(String addonKey, AddonVersion version) throws MpacException
112     {
113         for (Addon a: getByKey(addonKey, AddonQuery.any()))
114         {
115             return genericCreate(getVersionsUri(a), version);
116         }
117         throw new MpacException.ServerError(404);
118     }
119 
120     @Override
121     public AddonVersion updateVersion(AddonVersion original, AddonVersion updated) throws MpacException
122     {
123         return genericUpdate(original.getSelfUri(), original, updated);
124     }
125     
126     @Override
127     public Option<AddonPricing> getPricing(String addonKey, PricingType pricingType) throws MpacException
128     {
129         for (Addon a: getByKey(addonKey, AddonQuery.any()))
130         {
131             for (URI uri: a.getPricingUri(pricingType))
132             {
133                 return apiHelper.getOptionalEntity(uri, AddonPricing.class);
134             }
135         }
136         return none();
137     }
138     
139     @Override
140     public Page<AddonReference> findBanners(AddonQuery query) throws MpacException
141     {
142         InternalModel.Addons collectionRep = getEmptyBaseCollectionRep();
143         final UriBuilder uri = UriBuilder.fromUri(apiHelper.requireLinkUri(collectionRep.getLinks(), "banners", collectionRep.getClass()));
144         ApiHelper.addAddonQueryParams(query, uri);
145         return apiHelper.getMore(new PageReference<AddonReference>(uri.build(), query.getBounds(),
146             pageReader(InternalModel.AddonReferences.class)));
147     }
148 
149     @Override
150     public Page<AddonReference> findRecommendations(String addonKey, AddonQuery query) throws MpacException
151     {
152         for (Addon a: getByKey(addonKey, AddonQuery.any()))
153         {
154             for (URI u: a.getLinks().getUri("recommendations"))
155             {
156                 final UriBuilder uri = UriBuilder.fromUri(u);
157                 ApiHelper.addAddonQueryParams(query, uri);
158                 return apiHelper.getMore(new PageReference<AddonReference>(uri.build(), query.getBounds(),
159                     pageReader(InternalModel.AddonReferences.class)));
160             }
161         }
162         return Page.empty();
163     }
164 
165     @Override
166     public boolean claimAccessToken(String addonKey, String token) throws MpacException
167     {
168         for (Addon a: getByKey(addonKey, AddonQuery.builder().accessToken(some(token)).build()))
169         {
170             for (URI collUri: a.getLinks().getUri("tokens"))
171             {
172                 InternalModel.MinimalLinks rep = apiHelper.getEntity(withZeroLimit(withAccessToken(collUri, token)),
173                     InternalModel.MinimalLinks.class);
174                 UriTemplate t = ApiHelper.requireLinkUriTemplate(rep.getLinks(), "byToken", rep.getClass());
175                 URI uri = apiHelper.resolveLink(t.resolve(ImmutableMap.of("token", token)));
176                 SimpleHttpResponse r = apiHelper.getHttp().post(uri, new NullInputStream(0), 0, JSON, JSON);
177                 try
178                 {
179                     switch (r.getStatus())
180                     {
181                         case 200:
182                         case 204:
183                             return true;
184                         case 400:  // request had no Origin
185                         case 403:  // token exists, but Origin doesn't match
186                         case 404:  // token doesn't exist
187                             return false;
188                         default:
189                             throw apiHelper.responseException(r);
190                     }
191                 }
192                 finally
193                 {
194                     r.close();
195                 }
196             }
197         }
198         return false;
199     }
200     
201     private InternalModel.Addons getEmptyBaseCollectionRep() throws MpacException
202     {
203         return apiHelper.getEntity(withZeroLimit(getApiRoot()), InternalModel.Addons.class);
204     }
205 
206     private InternalModel.AddonVersions getEmptyVersionCollectionRep(Addon a) throws MpacException
207     {
208         URI uri = withZeroLimit(getVersionsUri(a));
209         return apiHelper.getEntity(uri, InternalModel.AddonVersions.class);
210     }
211     
212     private URI getVersionsUri(Addon a) throws MpacException
213     {
214         return apiHelper.requireLinkUri(a.getLinks(), "versions", Addon.class);
215     }
216     
217     private URI getVersionUri(Addon a, AddonVersionSpecifier v) throws MpacException
218     {
219         InternalModel.AddonVersions collectionRep = getEmptyVersionCollectionRep(a);
220         for (Either<String, Integer> specifiedVersion: v.getSpecifiedVersion())
221         {
222             for (String name: specifiedVersion.left())
223             {
224                 return getTemplatedLink(collectionRep, "byName", "name", name);
225             }
226             for (Integer build: specifiedVersion.right())
227             {
228                 return getTemplatedLink(collectionRep, "byBuild", "pluginBuildNumber", String.valueOf(build));
229             }
230         }
231         return apiHelper.requireLinkUri(collectionRep.getLinks(), "latest", InternalModel.AddonVersions.class);
232     }
233 }