Skip to content

Method: createQuery(Class)

1: /*
2: * JOPA
3: * Copyright (C) 2024 Czech Technical University in Prague
4: *
5: * This library is free software; you can redistribute it and/or
6: * modify it under the terms of the GNU Lesser General Public
7: * License as published by the Free Software Foundation; either
8: * version 3.0 of the License, or (at your option) any later version.
9: *
10: * This library is distributed in the hope that it will be useful,
11: * but WITHOUT ANY WARRANTY; without even the implied warranty of
12: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13: * Lesser General Public License for more details.
14: *
15: * You should have received a copy of the GNU Lesser General Public
16: * License along with this library.
17: */
18: package cz.cvut.kbss.jopa.query.criteria;
19:
20: import cz.cvut.kbss.jopa.model.CriteriaQueryImpl;
21: import cz.cvut.kbss.jopa.model.metamodel.Metamodel;
22: import cz.cvut.kbss.jopa.model.query.criteria.CriteriaBuilder;
23: import cz.cvut.kbss.jopa.model.query.criteria.Expression;
24: import cz.cvut.kbss.jopa.model.query.criteria.Order;
25: import cz.cvut.kbss.jopa.model.query.criteria.ParameterExpression;
26: import cz.cvut.kbss.jopa.model.query.criteria.Path;
27: import cz.cvut.kbss.jopa.model.query.criteria.Predicate;
28: import cz.cvut.kbss.jopa.query.criteria.expressions.AbsFunction;
29: import cz.cvut.kbss.jopa.query.criteria.expressions.AbstractExpression;
30: import cz.cvut.kbss.jopa.query.criteria.expressions.AbstractPathExpression;
31: import cz.cvut.kbss.jopa.query.criteria.expressions.CeilFunction;
32: import cz.cvut.kbss.jopa.query.criteria.expressions.CountFunction;
33: import cz.cvut.kbss.jopa.query.criteria.expressions.ExpressionEqualImpl;
34: import cz.cvut.kbss.jopa.query.criteria.expressions.ExpressionGreaterThanImpl;
35: import cz.cvut.kbss.jopa.query.criteria.expressions.ExpressionGreaterThanOrEqualImpl;
36: import cz.cvut.kbss.jopa.query.criteria.expressions.ExpressionInImpl;
37: import cz.cvut.kbss.jopa.query.criteria.expressions.ExpressionLessThanImpl;
38: import cz.cvut.kbss.jopa.query.criteria.expressions.ExpressionLessThanOrEqualImpl;
39: import cz.cvut.kbss.jopa.query.criteria.expressions.ExpressionLikeImpl;
40: import cz.cvut.kbss.jopa.query.criteria.expressions.ExpressionLiteralImpl;
41: import cz.cvut.kbss.jopa.query.criteria.expressions.ExpressionNotEqualImpl;
42: import cz.cvut.kbss.jopa.query.criteria.expressions.ExpressionNotLikeImpl;
43: import cz.cvut.kbss.jopa.query.criteria.expressions.FloorFunction;
44: import cz.cvut.kbss.jopa.query.criteria.expressions.IsMemberExpression;
45: import cz.cvut.kbss.jopa.query.criteria.expressions.LangFunction;
46: import cz.cvut.kbss.jopa.query.criteria.expressions.LengthFunction;
47: import cz.cvut.kbss.jopa.query.criteria.expressions.LowerFunction;
48: import cz.cvut.kbss.jopa.query.criteria.expressions.OrderImpl;
49: import cz.cvut.kbss.jopa.query.criteria.expressions.ParameterExpressionImpl;
50: import cz.cvut.kbss.jopa.query.criteria.expressions.UpperFunction;
51:
52: import java.util.Arrays;
53: import java.util.Collection;
54:
55: public class CriteriaBuilderImpl implements CriteriaBuilder {
56:
57: private final Metamodel metamodel;
58:
59: public CriteriaBuilderImpl(Metamodel metamodel) {
60: this.metamodel = metamodel;
61: }
62:
63: @Override
64: public <T> CriteriaQueryImpl<T> createQuery(Class<T> resultClass) {
65: return new CriteriaQueryImpl<>(new CriteriaQueryHolder<>(resultClass), metamodel, this);
66: }
67:
68: @Override
69: public <N extends Number> Expression<N> abs(Expression<N> x) {
70: validateFunctionArgument(x);
71: return new AbsFunction<>((Class<N>) x.getJavaType(), (AbstractPathExpression) x, this);
72: }
73:
74: private void validateFunctionArgument(Expression<?> x) {
75: if (!(x instanceof AbstractPathExpression)) {
76: throw new IllegalArgumentException("Function can be applied only to path expressions.");
77: }
78: }
79:
80: @Override
81: public Expression<Integer> count(Expression<?> x) {
82: validateFunctionArgument(x);
83: return new CountFunction((AbstractPathExpression) x, this);
84: }
85:
86: @Override
87: public <N extends Number> Expression<N> ceil(Expression<N> x) {
88: validateFunctionArgument(x);
89: return new CeilFunction<>((Class<N>) x.getJavaType(), (AbstractPathExpression) x, this);
90: }
91:
92: @Override
93: public <N extends Number> Expression<N> floor(Expression<N> x) {
94: validateFunctionArgument(x);
95: return new FloorFunction<>((Class<N>) x.getJavaType(), (AbstractPathExpression) x, this);
96: }
97:
98: @Override
99: public Expression<Integer> length(Expression<String> x) {
100: validateFunctionArgument(x);
101: return new LengthFunction((AbstractPathExpression) x, this);
102: }
103:
104: @Override
105: public <T> ParameterExpression<T> parameter(Class<T> paramClass) {
106: if (paramClass == null) {
107: throw new IllegalArgumentException("Class must be defined.");
108: }
109: return new ParameterExpressionImpl<>(paramClass, null, this);
110: }
111:
112: @Override
113: public <T> ParameterExpression<T> parameter(Class<T> paramClass, String name) {
114: if (paramClass == null) {
115: throw new IllegalArgumentException("Class must be defined.");
116: }
117: return new ParameterExpressionImpl<>(paramClass, name, this);
118: }
119:
120: @Override
121: public <T> Expression<T> literal(T value) {
122: if (value == null) {
123: throw new IllegalArgumentException("Literal cannot be null.");
124: }
125: return new ExpressionLiteralImpl<>(value, this);
126: }
127:
128: @Override
129: public Expression<String> literal(String value, String languageTag) {
130: if (value == null) {
131: throw new IllegalArgumentException("Literal cannot be null.");
132: }
133: return new ExpressionLiteralImpl<>(value, languageTag, this);
134: }
135:
136: @Override
137: public Expression<String> lower(Expression<String> x) {
138: validateFunctionArgument(x);
139: return new LowerFunction((AbstractPathExpression) x, this);
140: }
141:
142: @Override
143: public Expression<String> upper(Expression<String> x) {
144: validateFunctionArgument(x);
145: return new UpperFunction((AbstractPathExpression) x, this);
146: }
147:
148: @Override
149: public Expression<String> lang(Path<String> x) {
150: validateFunctionArgument(x);
151: return new LangFunction((AbstractPathExpression) x, this);
152: }
153:
154: @Override
155: public Order asc(Expression<?> x) {
156: return new OrderImpl(x);
157: }
158:
159: @Override
160: public Order desc(Expression<?> x) {
161: return new OrderImpl(x, false);
162: }
163:
164:
165: @Override
166: public Predicate and(Expression<Boolean> x, Expression<Boolean> y) {
167: return new CompoundedPredicateImpl(Predicate.BooleanOperator.AND, Arrays.asList(x, y), this);
168: }
169:
170: @Override
171: public Predicate and(Predicate... restrictions) {
172: if (restrictions.length == 1) {
173: return new SimplePredicateImpl(restrictions[0], this);
174: } else {
175: return new CompoundedPredicateImpl(Predicate.BooleanOperator.AND, Arrays.asList(restrictions), this);
176: }
177: }
178:
179: @Override
180: public Predicate or(Expression<Boolean> x, Expression<Boolean> y) {
181: return new CompoundedPredicateImpl(Predicate.BooleanOperator.OR, Arrays.asList(x, y), this);
182: }
183:
184: @Override
185: public Predicate or(Predicate... restrictions) {
186: if (restrictions.length == 1) {
187: return new SimplePredicateImpl(Predicate.BooleanOperator.OR, restrictions[0], this);
188: } else {
189: return new CompoundedPredicateImpl(Predicate.BooleanOperator.OR, Arrays.asList(restrictions), this);
190: }
191: }
192:
193: @Override
194: public Predicate equal(Expression<?> x, Expression<?> y) {
195: return new SimplePredicateImpl(
196: new ExpressionEqualImpl((AbstractExpression<?>) x, (AbstractExpression<?>) y, this), this);
197: }
198:
199: @Override
200: public Predicate equal(Expression<?> x, Object y) {
201: return new SimplePredicateImpl(
202: new ExpressionEqualImpl((AbstractExpression<?>) x, new ExpressionLiteralImpl<>(y, this), this), this);
203: }
204:
205: @Override
206: public Predicate equal(Expression<?> x, String y, String languageTag) {
207: return new SimplePredicateImpl(
208: new ExpressionEqualImpl((AbstractExpression<?>) x, new ExpressionLiteralImpl<>(y, languageTag, this),
209: this), this);
210: }
211:
212: @Override
213: public Predicate notEqual(Expression<?> x, Expression<?> y) {
214: return new SimplePredicateImpl(
215: new ExpressionNotEqualImpl((AbstractExpression<?>) x, (AbstractExpression<?>) y, this), this);
216: }
217:
218: @Override
219: public Predicate notEqual(Expression<?> x, Object y) {
220: return new SimplePredicateImpl(
221: new ExpressionNotEqualImpl((AbstractExpression<?>) x, new ExpressionLiteralImpl<>(y, this), this),
222: this);
223:
224: }
225:
226: @Override
227: public Predicate like(Expression<String> x, Expression<String> pattern) {
228: return new SimplePredicateImpl(
229: new ExpressionLikeImpl((AbstractExpression<String>) x, (AbstractExpression<String>) pattern, this),
230: this);
231: }
232:
233: @Override
234: public Predicate like(Expression<String> x, String pattern) {
235: return new SimplePredicateImpl(
236: new ExpressionLikeImpl((AbstractExpression<String>) x, new ExpressionLiteralImpl<>(pattern, this),
237: this), this);
238: }
239:
240: @Override
241: public Predicate notLike(Expression<String> x, Expression<String> pattern) {
242: return new SimplePredicateImpl(
243: new ExpressionNotLikeImpl((AbstractExpression<String>) x, (AbstractExpression<String>) pattern, this),
244: this);
245: }
246:
247: @Override
248: public Predicate notLike(Expression<String> x, String pattern) {
249: return new SimplePredicateImpl(
250: new ExpressionNotLikeImpl((AbstractExpression<String>) x, new ExpressionLiteralImpl<>(pattern, this),
251: this), this);
252: }
253:
254: @Override
255: public Predicate not(Expression<Boolean> restriction) {
256: return wrapExpressionToPredicateWithRepair(restriction).not();
257: }
258:
259: @Override
260: public <T> In<T> in(Expression<? extends T> expression) {
261: return new ExpressionInImpl<>(expression, this);
262: }
263:
264: @Override
265: public <T> In<T> notIn(Expression<? extends T> expression) {
266: In<T> inExpression = new ExpressionInImpl<>(expression, this);
267: inExpression.not();
268: return inExpression;
269: }
270:
271: @Override
272: public <E, C extends Collection<E>> Predicate isMember(E elem, Expression<C> collection) {
273: return new IsMemberExpression<>(elem, collection, this);
274: }
275:
276: @Override
277: public <E, C extends Collection<E>> Predicate isNotMember(E elem, Expression<C> collection) {
278: final IsMemberExpression<E> expr = new IsMemberExpression<>(elem, collection, this);
279: expr.not();
280: return expr;
281: }
282:
283: @Override
284: public <Y extends Comparable<? super Y>> Predicate greaterThan(Expression<? extends Y> x,
285: Expression<? extends Y> y) {
286: return new SimplePredicateImpl(
287: new ExpressionGreaterThanImpl((AbstractExpression<Y>) x, (AbstractExpression<Y>) y, this), this);
288: }
289:
290: @Override
291: public <Y extends Comparable<? super Y>> Predicate greaterThan(Expression<? extends Y> x, Y y) {
292: return new SimplePredicateImpl(
293: new ExpressionGreaterThanImpl((AbstractExpression<Y>) x, new ExpressionLiteralImpl<>(y, this), this),
294: this);
295: }
296:
297: @Override
298: public <Y extends Comparable<? super Y>> Predicate greaterThanOrEqual(Expression<? extends Y> x,
299: Expression<? extends Y> y) {
300: return new SimplePredicateImpl(
301: new ExpressionGreaterThanOrEqualImpl((AbstractExpression<Y>) x, (AbstractExpression<Y>) y, this), this);
302: }
303:
304: @Override
305: public <Y extends Comparable<? super Y>> Predicate greaterThanOrEqual(Expression<? extends Y> x, Y y) {
306: return new SimplePredicateImpl(
307: new ExpressionGreaterThanOrEqualImpl((AbstractExpression<Y>) x, new ExpressionLiteralImpl<>(y, this),
308: this), this);
309: }
310:
311: @Override
312: public <Y extends Comparable<? super Y>> Predicate lessThan(Expression<? extends Y> x, Expression<? extends Y> y) {
313: return new SimplePredicateImpl(
314: new ExpressionLessThanImpl((AbstractExpression<Y>) x, (AbstractExpression<Y>) y, this), this);
315: }
316:
317: @Override
318: public <Y extends Comparable<? super Y>> Predicate lessThan(Expression<? extends Y> x, Y y) {
319: return new SimplePredicateImpl(
320: new ExpressionLessThanImpl((AbstractExpression<Y>) x, new ExpressionLiteralImpl<>(y, this), this),
321: this);
322: }
323:
324: @Override
325: public <Y extends Comparable<? super Y>> Predicate lessThanOrEqual(Expression<? extends Y> x,
326: Expression<? extends Y> y) {
327: return new SimplePredicateImpl(
328: new ExpressionLessThanOrEqualImpl((AbstractExpression<Y>) x, (AbstractExpression<Y>) y, this), this);
329: }
330:
331: @Override
332: public <Y extends Comparable<? super Y>> Predicate lessThanOrEqual(Expression<? extends Y> x, Y y) {
333: return new SimplePredicateImpl(
334: new ExpressionLessThanOrEqualImpl((AbstractExpression<Y>) x, new ExpressionLiteralImpl<>(y, this),
335: this), this);
336: }
337:
338:
339: /**
340: * Method wraps given boolean expression to Predicate and if path expression occur, it wrap it to
341: * ExpressionEqualsImpl before. For example: {@literal Expression<Boolean> expression =
342: * factory.get("attributeName");} Looks like boolean expression but in fact it is not boolean expression, so we need
343: * to fix this.
344: *
345: * @param expression - boolean or path expression
346: * @return Expression wrapped in Predicate
347: */
348: public Predicate wrapExpressionToPredicateWithRepair(Expression<Boolean> expression) {
349: if (expression instanceof Predicate) {
350: return (Predicate) expression;
351: } else if (expression instanceof AbstractPathExpression) {
352: return new SimplePredicateImpl(
353: new ExpressionEqualImpl((AbstractExpression) expression, (AbstractExpression) this.literal(true),
354: this), this);
355: } else {
356: return new SimplePredicateImpl(expression, this);
357: }
358: }
359:
360: }