View Javadoc
1   /*
2    * Licensed to The Apereo Foundation under one or more contributor license
3    * agreements. See the NOTICE file distributed with this work for additional
4    * information regarding copyright ownership.
5    *
6    *
7    * The Apereo Foundation licenses this file to you under the Educational
8    * Community License, Version 2.0 (the "License"); you may not use this file
9    * except in compliance with the License. You may obtain a copy of the License
10   * at:
11   *
12   *   http://opensource.org/licenses/ecl2.txt
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
17   * License for the specific language governing permissions and limitations under
18   * the License.
19   *
20   */
21  package org.opencastproject.assetmanager.impl.query;
22  
23  import static com.entwinemedia.fn.Stream.$;
24  
25  import com.entwinemedia.fn.Fn;
26  import com.entwinemedia.fn.Stream;
27  import com.entwinemedia.fn.data.Opt;
28  import com.mysema.query.types.EntityPath;
29  import com.mysema.query.types.Expression;
30  import com.mysema.query.types.OrderSpecifier;
31  import com.mysema.query.types.expr.BooleanExpression;
32  
33  import javax.annotation.Nullable;
34  import javax.annotation.ParametersAreNonnullByDefault;
35  
36  /**
37   * Collect contributions to a JPA query.
38   * Each of the builder methods creates a new instance.
39   */
40  @ParametersAreNonnullByDefault
41  public final class SelectQueryContribution {
42    // CHECKSTYLE:OFF
43    final Stream<Expression<?>> fetch;
44    final Stream<EntityPath<?>> from;
45    final Stream<Join> join;
46    final Opt<BooleanExpression> where;
47    final Opt<Integer> offset;
48    final Opt<Integer> limit;
49    final Stream<OrderSpecifier<?>> order;
50    // CHECKSTYLE:ON
51  
52    public SelectQueryContribution(
53            Stream<Expression<?>> fetch,
54            Stream<EntityPath<?>> from,
55            Stream<Join> join,
56            Opt<BooleanExpression> where,
57            Opt<Integer> offset,
58            Opt<Integer> limit,
59            Stream<OrderSpecifier<?>> order) {
60      this.fetch = fetch;
61      this.from = from;
62      this.join = join;
63      this.where = where;
64      this.offset = offset;
65      this.limit = limit;
66      this.order = order;
67    }
68  
69    /** Create a new, empty contribution. */
70    public static SelectQueryContribution mk() {
71      return new SelectQueryContribution(
72          Stream.<Expression<?>>empty(),
73          Stream.<EntityPath<?>>empty(),
74          Stream.<Join>empty(),
75          Opt.<BooleanExpression>none(),
76          Opt.<Integer>none(),
77          Opt.<Integer>none(),
78          Stream.<OrderSpecifier<?>>empty()
79      );
80    }
81  
82    /** Set the `fetch` contribution. */
83    SelectQueryContribution fetch(Stream<? extends Expression<?>> fetch) {
84      return new SelectQueryContribution((Stream<Expression<?>>) fetch, from, join, where, offset, limit, order);
85    }
86  
87    /** Add to the `from` contribution. */
88    SelectQueryContribution addFetch(Stream<? extends Expression<?>> fetch) {
89      return new SelectQueryContribution(this.fetch.append(fetch), from, join, where, offset, limit, order);
90    }
91  
92    /** Set the `from` contribution. */
93    SelectQueryContribution from(Stream<? extends EntityPath<?>> from) {
94      return new SelectQueryContribution(fetch, (Stream<EntityPath<?>>) from, join, where, offset, limit, order);
95    }
96  
97    /** Add to the `from` contribution. */
98    SelectQueryContribution addFrom(Stream<? extends EntityPath<?>> from) {
99      return new SelectQueryContribution(fetch, this.from.append(from), join, where, offset, limit, order);
100   }
101 
102   /** Set the `join` contribution. */
103   SelectQueryContribution join(Stream<Join> join) {
104     return new SelectQueryContribution(fetch, from, join, where, offset, limit, order);
105   }
106 
107   /** Set the `join` contribution. */
108   SelectQueryContribution join(Join join) {
109     return join($(join));
110   }
111 
112   /** Add to the `join` contribution. */
113   SelectQueryContribution addJoin(Stream<Join> join) {
114     return new SelectQueryContribution(fetch, from, this.join.append(join), where, offset, limit, order);
115   }
116 
117   /** Add to the `join` contribution. */
118   SelectQueryContribution addJoin(Join join) {
119     return addJoin($(join));
120   }
121 
122   /* -------------------------------------------------------------------------------------------------------------- */
123 
124   /** Set the `where` contribution. */
125   SelectQueryContribution where(Opt<BooleanExpression> where) {
126     return new SelectQueryContribution(fetch, from, join, where, offset, limit, order);
127   }
128 
129   /** Set the `where` contribution. */
130   SelectQueryContribution where(@Nullable BooleanExpression where) {
131     return where(Opt.nul(where));
132   }
133 
134   /** Add to the `where` contribution using boolean "and". */
135   SelectQueryContribution andWhere(Opt<BooleanExpression> where) {
136     return where(JpaFns.allOf(this.where, where));
137   }
138 
139   /** Add to the `where` contribution using boolean "and". */
140   SelectQueryContribution andWhere(@Nullable BooleanExpression where) {
141     return andWhere(Opt.nul(where));
142   }
143 
144   /* -------------------------------------------------------------------------------------------------------------- */
145 
146   /** Set the `offset` contribution. */
147   SelectQueryContribution offset(Opt<Integer> offset) {
148     return new SelectQueryContribution(fetch, from, join, where, offset, limit, order);
149   }
150 
151   /** Set the `offset` contribution. */
152   SelectQueryContribution offset(Integer offset) {
153     return offset(Opt.some(offset));
154   }
155 
156   /** Set the `limit` contribution. */
157   SelectQueryContribution limit(Opt<Integer> limit) {
158     return new SelectQueryContribution(fetch, from, join, where, offset, limit, order);
159   }
160 
161   /** Set the `limit` contribution. */
162   SelectQueryContribution limit(Integer limit) {
163     return limit(Opt.some(limit));
164   }
165 
166   /** Set the `order` contribution. */
167   SelectQueryContribution order(Stream<? extends OrderSpecifier<?>> order) {
168     return new SelectQueryContribution(fetch, from, join, where, offset, limit, (Stream<OrderSpecifier<?>>) order);
169   }
170 
171   /** Add to the `order` contribution. */
172   SelectQueryContribution addOrder(Stream<? extends OrderSpecifier<?>> order) {
173     return new SelectQueryContribution(fetch, from, join, where, offset, limit, this.order.append(order));
174   }
175 
176   static final Fn<SelectQueryContribution, Stream<Expression<?>>> getFetch
177       = new Fn<SelectQueryContribution, Stream<Expression<?>>>() {
178         @Override public Stream<Expression<?>> apply(SelectQueryContribution c) {
179           return c.fetch;
180         }
181       };
182 
183   static final Fn<SelectQueryContribution, Stream<EntityPath<?>>> getFrom
184       = new Fn<SelectQueryContribution, Stream<EntityPath<?>>>() {
185         @Override public Stream<EntityPath<?>> apply(SelectQueryContribution c) {
186           return c.from;
187         }
188       };
189 
190   static final Fn<SelectQueryContribution, Stream<Join>> getJoin
191       = new Fn<SelectQueryContribution, Stream<Join>>() {
192         @Override public Stream<Join> apply(SelectQueryContribution c) {
193           return c.join;
194         }
195       };
196 
197   static final Fn<SelectQueryContribution, Opt<BooleanExpression>> getWhere
198       = new Fn<SelectQueryContribution, Opt<BooleanExpression>>() {
199         @Override public Opt<BooleanExpression> apply(SelectQueryContribution c) {
200           return c.where;
201         }
202       };
203 
204   static final Fn<SelectQueryContribution, Stream<OrderSpecifier<?>>> getOrder
205       = new Fn<SelectQueryContribution, Stream<OrderSpecifier<?>>>() {
206         @Override public Stream<OrderSpecifier<?>> apply(SelectQueryContribution c) {
207           return c.order;
208         }
209       };
210 }