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.AddonVersionExternalLinkType;
8   import com.atlassian.marketplace.client.api.ApplicationKey;
9   import com.atlassian.marketplace.client.api.HostingType;
10  import com.atlassian.marketplace.client.api.LicenseTypeId;
11  
12  import com.google.common.base.Function;
13  import com.google.common.base.Functions;
14  import com.google.common.base.Predicate;
15  import com.google.common.collect.ImmutableList;
16  
17  import static com.atlassian.fugue.Option.none;
18  import static com.atlassian.fugue.Option.option;
19  import static com.atlassian.fugue.Option.some;
20  import static com.google.common.collect.Iterables.transform;
21  
22  /**
23   * Information about a specific version of an {@link Addon}.
24   * @see com.atlassian.marketplace.client.api.Addons
25   * @see AddonVersionSummary
26   * @since 2.0.0
27   */
28  public final class AddonVersion extends AddonVersionBase
29  {
30      Embedded _embedded;
31      Integer buildNumber;
32      Option<String> youtubeId;
33      Map<String, URI> vendorLinks;
34      Option<ImmutableList<VersionCompatibility>> compatibilities;
35      TextProperties text;
36      @ReadOnly Option<LegacyProperties> legacy;
37  
38      @Override
39      public Option<ArtifactInfo> getArtifactInfo()
40      {
41          return _embedded.artifact;
42      }
43  
44      @Override
45      public Option<URI> getArtifactUri()
46      {
47          for (ArtifactInfo a: _embedded.artifact)
48          {
49              return some(a.getBinaryUri());
50          }
51          return none();
52      }
53  
54      @Override
55      public Option<URI> getRemoteDescriptorUri()
56      {
57          for (ArtifactInfo a: _embedded.artifact)
58          {
59              return a.getRemoteDescriptorUri();
60          }
61          return none();
62      }
63  
64      /**
65       * The version's build number, a value specified by the vendor (or, in the case of Atlassian
66       * Connect add-ons, set automatically by Marketplace) that distinguishes it from all other versions
67       * of the add-on and determines the correct ordering of versions.
68       * @see ModelBuilders.AddonVersionBuilder#buildNumber
69       */
70      public int getBuildNumber()
71      {
72          return buildNumber;
73      }
74      
75      /**
76       * A list of {@link VersionCompatibility} objects representing each of the
77       * {@link Application}s the add-on version is compatible with, and the compatible
78       * application version range.  For an existing add-on listing, there will always be
79       * at least one of these.
80       * @see #getCompatibilitiesIfSpecified()
81       */
82      public Iterable<VersionCompatibility> getCompatibilities()
83      {
84          return compatibilities.getOrElse(ImmutableList.<VersionCompatibility>of());
85      }
86      
87      /**
88       * Same as {@link #getCompatibilities}, but returns {@code none()} rather than an empty
89       * list if this is a new version that you are creating which has no compatibilities specified
90       * (meaning that it will inherit its compatibilities from the previous version).
91       */
92      public Option<Iterable<VersionCompatibility>> getCompatibilitiesIfSpecified()
93      {
94          return compatibilities.map(Functions.<Iterable<VersionCompatibility>>identity());
95      }
96      
97      /**
98       * Returns one of the optional vendor-specified external links for the add-on version.
99       * @param type specifies which type of link to get
100      * @return the link URI, or {@link Option#none()} if there is no such link
101      */
102     public Option<URI> getExternalLinkUri(AddonVersionExternalLinkType type)
103     {
104         if (type.canSetForNewAddonVersions())
105         {
106             return option(vendorLinks.get(type.getKey()));
107         }
108         else
109         {
110             for (LegacyProperties l: legacy)
111             {
112                 return option(l.vendorLinks.get(type.getKey()));
113             }
114             return none();
115         }
116     }
117     
118     @Override
119     public Iterable<AddonCategorySummary> getFunctionalCategories()
120     {
121         return _embedded.functionalCategories;
122     }
123 
124     /**
125      * The image/text "highlight" items that are featured in a public add-on listing; may be
126      * omitted for private versions.
127      * @see #getHighlightsIfSpecified()
128      * @see ModelBuilders.AddonVersionBuilder#highlights(Iterable)
129      */
130     public Iterable<Highlight> getHighlights()
131     {
132         return _embedded.highlights.getOrElse(ImmutableList.<Highlight>of());
133     }
134     
135     /**
136      * Same as {@link #getHighlights}, but returns {@code none()} rather than an empty
137      * list if this is a new version that you are creating which has no highlights specified
138      * (meaning that it will inherit its highlights from the previous version).
139      */
140     public Option<Iterable<Highlight>> getHighlightsIfSpecified()
141     {
142         return _embedded.highlights.map(Functions.<Iterable<Highlight>>identity());
143     }
144 
145     /**
146      * Information about the add-on version's software license type; may be omitted for
147      * private versions.
148      * @see ModelBuilders.AddonVersionBuilder#licenseType(Option)
149      * @see #getLicenseTypeId()
150      */
151     public Option<LicenseType> getLicenseType()
152     {
153         return _embedded.license;
154     }
155     
156     /**
157      * The unique resource identifier for the add-on version's software license type; may be
158      * omitted for private versions.
159      * @see ModelBuilders.AddonVersionBuilder#licenseTypeId(Option)
160      * @see #getLicenseType()
161      */
162     public Option<LicenseTypeId> getLicenseTypeId()
163     {
164         for (URI u: getLinks().getUri("license"))
165         {
166             return some(LicenseTypeId.fromUri(u));
167         }
168         return none();
169     }
170     
171     /**
172      * Optional descriptive text to be displayed in the add-on listing.
173      * @see ModelBuilders.AddonVersionBuilder#moreDetails(Option)
174      */
175     public Option<HtmlString> getMoreDetails()
176     {
177         return text.moreDetails;
178     }
179 
180     @Override
181     public PaymentModel getPaymentModel()
182     {
183         return paymentModel;
184     }
185 
186     /**
187      * Optional details about this release of the add-on (for instance, new features).
188      * @see ModelBuilders.AddonVersionBuilder#releaseNotes(Option)
189      */
190     public Option<HtmlString> getReleaseNotes()
191     {
192         return text.releaseNotes;
193     }
194 
195     /**
196      * A brief description of the nature or purpose of this release (for instance, "bug fixes").
197      * @see ModelBuilders.AddonVersionBuilder#releaseSummary(Option)
198      */
199     public Option<String> getReleaseSummary()
200     {
201         return text.releaseSummary;
202     }
203     
204     /**
205      * Screenshot images with optional captions.
206      * @see #getScreenshotsIfSpecified()
207      * @see ModelBuilders.AddonVersionBuilder#screenshots(Iterable)
208      */
209     public Iterable<Screenshot> getScreenshots()
210     {
211         return _embedded.screenshots.getOrElse(ImmutableList.<Screenshot>of());
212     }
213 
214     /**
215      * Same as {@link #getScreenshots}, but returns {@code none()} rather than an empty
216      * list if this is a new version that you are creating which has no screenshots specified
217      * (meaning that it will inherit its screenshots from the previous version).
218      */
219     public Option<Iterable<Screenshot>> getScreenshotsIfSpecified()
220     {
221         return _embedded.screenshots.map(Functions.<Iterable<Screenshot>>identity());
222     }
223 
224     @Override
225     public AddonVersionStatus getStatus()
226     {
227         return status;
228     }
229 
230     @Override
231     public boolean isStatic()
232     {
233         return staticAddon;
234     }
235     
236     /**
237      * The string key of a YouTube video to be featured in the add-on listing.
238      * @see ModelBuilders.AddonVersionBuilder#youtubeId(Option)
239      */
240     public Option<String> getYoutubeId()
241     {
242         return youtubeId;
243     }
244 
245     /**
246      * Returns just the application keys from the list of compatibilities.
247      * @see #getCompatibilities()
248      */
249     public Iterable<ApplicationKey> getCompatibleApplications()
250     {
251         return transform(getCompatibilities(), new Function<VersionCompatibility, ApplicationKey>()
252         {
253             public ApplicationKey apply(VersionCompatibility input)
254             {
255                 return input.getApplication();
256             }
257         });
258     }
259     
260     /**
261      * Shortcut for testing whether the version has any compatibility with the specified application.
262      * @see #getCompatibilities()
263      */
264     public boolean isCompatibleWithApplication(ApplicationKey application)
265     {
266         for (VersionCompatibility c: getCompatibilities())
267         {
268             if (c.getApplication().equals(application))
269             {
270                 return true;
271             }
272         }
273         return false;
274     }
275 
276     /**
277      * Shortcut for testing whether the version is compatible with the specified application
278      * build and hosting type.
279      * @see #getCompatibilities()
280      */
281     public boolean isCompatibleWith(Predicate<ApplicationKey> applicationCriteria, HostingType hostingType, int build)
282     {
283         for (VersionCompatibility c: getCompatibilities())
284         {
285             if (c.isCompatibleWith(applicationCriteria, hostingType, build))
286             {
287                 return true;
288             }
289         }
290         return false;
291     }
292 
293     static final class Embedded
294     {
295         Option<ArtifactInfo> artifact;
296         ImmutableList<AddonCategorySummary> functionalCategories;
297         Option<ImmutableList<Highlight>> highlights;
298         Option<LicenseType> license;
299         Option<ImmutableList<Screenshot>> screenshots;
300     }
301 
302     static final class LegacyProperties
303     {
304         Map<String, URI> vendorLinks;
305     }
306     
307     static final class TextProperties
308     {
309         Option<String> releaseSummary;
310         Option<HtmlString> moreDetails;
311         Option<HtmlString> releaseNotes;
312     }
313 }