View Javadoc

1   package com.atlassian.marketplace.client.api;
2   
3   import com.atlassian.fugue.Option;
4   
5   import static com.atlassian.fugue.Option.none;
6   import static com.atlassian.marketplace.client.api.QueryProperties.describeOptBoolean;
7   import static com.atlassian.marketplace.client.api.QueryProperties.describeOptEnum;
8   import static com.atlassian.marketplace.client.api.QueryProperties.describeParams;
9   import static com.google.common.base.Preconditions.checkNotNull;
10  
11  /**
12   * Encapsulates search parameters that can be passed to {@link Products#find(ProductQuery)}.
13   * @since 2.0.0
14   */
15  public final class ProductQuery implements QueryProperties.ApplicationCriteria,
16          QueryProperties.Bounds,
17          QueryProperties.Cost,
18          QueryProperties.Hosting,
19          QueryProperties.WithVersion
20  {
21      private static final ProductQuery DEFAULT_QUERY = builder().build();
22      
23      private final QueryBuilderProperties.ApplicationCriteriaHelper app;
24      private final Option<Cost> cost;
25      private final Option<HostingType> hosting;
26      private final boolean withVersion;
27      private final QueryBounds bounds;
28      
29      /**
30       * Returns a new {@link Builder} for constructing a ProductQuery.
31       */
32      public static Builder builder()
33      {
34          return new Builder();
35      }
36  
37      /**
38       * Returns a ProductQuery with no criteria, which will match any available product.
39       */
40      public static ProductQuery any()
41      {
42          return DEFAULT_QUERY;
43      }
44      
45      /**
46       * Returns a new {@link Builder} for constructing a ProductQuery based on an existing ProductQuery.
47       */
48      public static Builder builder(ProductQuery query)
49      {
50          Builder builder = builder()
51              .application(query.getApplication())
52              .appBuildNumber(query.getAppBuildNumber())
53              .cost(query.getCost())
54              .hosting(query.getHosting())
55              .withVersion(query.isWithVersion())
56              .bounds(query.getBounds());
57  
58          return builder;
59      }
60  
61      private ProductQuery(Builder builder)
62      {
63          app = builder.app;
64          cost = builder.cost;
65          hosting = builder.hosting;
66          withVersion = builder.withVersion;
67          bounds = builder.bounds;
68      }
69      
70      @Override
71      public Option<ApplicationKey> getApplication()
72      {
73          return app.application;
74      }
75      
76      @Override
77      public Option<Integer> getAppBuildNumber()
78      {
79          return app.appBuildNumber;
80      }
81      
82      @Override
83      public Option<Cost> getCost()
84      {
85          return cost;
86      }
87  
88      @Override
89      public Option<HostingType> getHosting()
90      {
91          return hosting;
92      }
93          
94      @Override
95      public boolean isWithVersion()
96      {
97          return withVersion;
98      }
99      
100     @Override
101     public QueryBounds getBounds()
102     {
103         return bounds;
104     }
105 
106     @SuppressWarnings("unchecked")
107     @Override
108     public String toString()
109     {
110         return describeParams("ProductQuery",
111             app.describe(),
112             describeOptEnum("cost", cost),
113             describeOptEnum("hosting", hosting),
114             describeOptBoolean("withVersion", withVersion),
115             bounds.describe()
116         );
117     }
118     
119     @Override
120     public boolean equals(Object other)
121     {
122         return (other instanceof ProductQuery) ? toString().equals(other.toString()) : false;
123     }
124 
125     @Override
126     public int hashCode()
127     {
128         return toString().hashCode();
129     }
130     
131     /**
132      * Builder class for {@link ProductQuery}.  Use {@link ProductQuery#builder()} to create an instance. 
133      */
134     public static class Builder implements QueryBuilderProperties.ApplicationCriteria<Builder>,
135         QueryBuilderProperties.Bounds<Builder>,
136         QueryBuilderProperties.Cost<Builder>,
137         QueryBuilderProperties.Hosting<Builder>,
138         QueryBuilderProperties.WithVersion<Builder>
139     {
140         private QueryBuilderProperties.ApplicationCriteriaHelper app = new QueryBuilderProperties.ApplicationCriteriaHelper();
141         private Option<Cost> cost = none();
142         private Option<HostingType> hosting = none();
143         private boolean withVersion = false;
144         private QueryBounds bounds = QueryBounds.defaultBounds();
145 
146         /**
147          * Returns an immutable {@link ProductQuery} based on the current builder properties.
148          */
149         public ProductQuery build()
150         {
151             return new ProductQuery(this);
152         }
153         
154         @Override
155         public Builder application(Option<ApplicationKey> application)
156         {
157             app = app.application(application);
158             return this;
159         }
160         
161         @Override
162         public Builder appBuildNumber(Option<Integer> appBuildNumber)
163         {
164             app = app.appBuildNumber(appBuildNumber);
165             return this;
166         }
167         
168         @Override
169         public Builder cost(Option<Cost> cost)
170         {
171             this.cost = checkNotNull(cost);
172             return this;
173         }
174 
175         @Override
176         public Builder hosting(Option<HostingType> hosting)
177         {
178             this.hosting = checkNotNull(hosting);
179             return this;
180         }
181         
182         @Override
183         public Builder withVersion(boolean withVersion)
184         {
185             this.withVersion = withVersion;
186             return this;
187         }
188         
189         @Override
190         public Builder bounds(QueryBounds bounds)
191         {
192             this.bounds = checkNotNull(bounds);
193             return this;
194         }
195     }
196 }