Skip to contentMethod: from(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.model;
19:
20: import cz.cvut.kbss.jopa.model.metamodel.EntityType;
21: import cz.cvut.kbss.jopa.model.metamodel.Metamodel;
22: import cz.cvut.kbss.jopa.model.query.criteria.CriteriaQuery;
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.Predicate;
26: import cz.cvut.kbss.jopa.model.query.criteria.Root;
27: import cz.cvut.kbss.jopa.model.query.criteria.Selection;
28: import cz.cvut.kbss.jopa.query.criteria.AbstractPredicate;
29: import cz.cvut.kbss.jopa.query.criteria.CriteriaBuilderImpl;
30: import cz.cvut.kbss.jopa.query.criteria.CriteriaParameterFiller;
31: import cz.cvut.kbss.jopa.query.criteria.CriteriaQueryHolder;
32: import cz.cvut.kbss.jopa.query.criteria.RootImpl;
33: import cz.cvut.kbss.jopa.query.criteria.expressions.AbstractExpression;
34: import cz.cvut.kbss.jopa.query.soql.SoqlConstants;
35:
36: import java.util.ArrayList;
37: import java.util.Arrays;
38: import java.util.Collections;
39: import java.util.List;
40: import java.util.Objects;
41:
42: public class CriteriaQueryImpl<T> implements CriteriaQuery<T> {
43:
44: protected final CriteriaQueryHolder<T> query;
45: private final Metamodel metamodel;
46: private final CriteriaBuilderImpl cb;
47:
48:
49: public CriteriaQueryImpl(CriteriaQueryHolder<T> query, Metamodel metamodel, CriteriaBuilderImpl cb) {
50: this.query = Objects.requireNonNull(query);
51: this.metamodel = metamodel;
52: this.cb = cb;
53: }
54:
55: @Override
56: public <X> Root<X> from(Class<X> entityClass) {
57: RootImpl<X> root = new RootImpl<>(metamodel, null, entityClass, this.cb);
58: query.setRoot(root);
59: return root;
60: }
61:
62: @Override
63: public <X> Root<X> from(EntityType<X> entity) {
64: RootImpl<X> root = new RootImpl<>(metamodel, null, entity.getBindableJavaType(), this.cb);
65: query.setRoot(root);
66: return root;
67: }
68:
69: @Override
70: public CriteriaQuery<T> select(Selection<? extends T> selection) {
71: query.setSelection(selection);
72: return this;
73: }
74:
75: @Override
76: public CriteriaQuery<T> where(Expression<Boolean> expression) {
77: query.setWhere(cb.wrapExpressionToPredicateWithRepair(expression));
78: return this;
79: }
80:
81: @Override
82: public CriteriaQuery<T> where(Predicate... predicates) {
83: query.setWhere(cb.and(predicates));
84: return this;
85: }
86:
87: @Override
88: public CriteriaQuery<T> where(List<Predicate> predicates) {
89: return this.where(predicates.toArray(new Predicate[0]));
90: }
91:
92: @Override
93: public Class<T> getResultType() {
94: return query.getResultType();
95: }
96:
97: @Override
98: public CriteriaQuery<T> distinct(boolean b) {
99: query.setDistinct(b);
100: return this;
101: }
102:
103: @Override
104: public CriteriaQuery<T> distinct() {
105: return this.distinct(true);
106: }
107:
108: @Override
109: public boolean isDistinct() {
110: return query.isDistinct();
111: }
112:
113: @Override
114: public Selection<T> getSelection() {
115: return (Selection<T>) query.getSelection();
116: }
117:
118: @Override
119: public Predicate getRestriction() {
120: return query.getWhere();
121: }
122:
123: @Override
124: public CriteriaQuery<T> orderBy(List<Order> o) {
125: if (!o.isEmpty()) {
126: query.setOrderBy(o);
127: } else {
128: query.setOrderBy(null);
129: }
130: return this;
131: }
132:
133: @Override
134: public CriteriaQuery<T> orderBy(Order... o) {
135: if (o != null && o.length > 0) {
136: query.setOrderBy(Arrays.asList(o));
137: } else {
138: query.setOrderBy(null);
139: }
140: return this;
141: }
142:
143: @Override
144: public List<Order> getOrderList() {
145: if (query.getOrderBy() == null) {
146: return Collections.emptyList();
147: }
148: return new ArrayList<>(query.getOrderBy());
149: }
150:
151:
152: @Override
153: public CriteriaQuery<T> groupBy(Expression<?>... grouping) {
154: if (grouping != null && grouping.length > 0) {
155: query.setGroupBy(Arrays.asList(grouping));
156: } else {
157: query.setGroupBy(null);
158: }
159: return this;
160: }
161:
162: @Override
163: public CriteriaQuery<T> groupBy(List<Expression<?>> grouping) {
164: if (!grouping.isEmpty()) {
165: query.setGroupBy(grouping);
166: } else {
167: query.setGroupBy(null);
168: }
169: return this;
170: }
171:
172: @Override
173: public CriteriaQuery<T> having(Expression<Boolean> restriction) {
174: query.setHaving(cb.and(cb.wrapExpressionToPredicateWithRepair(restriction)));
175: return this;
176: }
177:
178: @Override
179: public CriteriaQuery<T> having(Predicate... restrictions) {
180: query.setHaving(cb.and(restrictions));
181: return this;
182: }
183:
184: /**
185: * Method translates criteria query to SOQL query and returns its string representation.
186: *
187: * @param parameterFiller Generator of parameter values in the query string
188: * @return string representation of SOQL query
189: */
190: public String translateQuery(CriteriaParameterFiller parameterFiller) {
191: StringBuilder stringBuilder = new StringBuilder();
192: stringBuilder.append(SoqlConstants.SELECT).append(' ');
193: if (isDistinct()) {
194: stringBuilder.append(SoqlConstants.DISTINCT).append(' ');
195: }
196: ((AbstractExpression) query.getSelection()).setExpressionToQuery(stringBuilder, parameterFiller);
197:
198: stringBuilder.append(' ').append(SoqlConstants.FROM).append(' ').append(((RootImpl) query.getRoot()).getJavaType().getSimpleName()).append(' ');
199: ((RootImpl) query.getRoot()).setExpressionToQuery(stringBuilder, parameterFiller);
200:
201: if (query.getWhere() != null && !query.getWhere().getExpressions().isEmpty()) {
202: stringBuilder.append(' ').append(SoqlConstants.WHERE).append(' ');
203: ((AbstractPredicate) query.getWhere()).setExpressionToQuery(stringBuilder, parameterFiller);
204: }
205:
206: if (query.getGroupBy() != null && !query.getGroupBy().isEmpty()) {
207: stringBuilder.append(' ').append(SoqlConstants.GROUP_BY).append(' ');
208: for (Expression groupBy : query.getGroupBy()) {
209: ((AbstractExpression) groupBy).setExpressionToQuery(stringBuilder, parameterFiller);
210: }
211: }
212:
213: if (query.getHaving() != null && !query.getHaving().getExpressions().isEmpty()) {
214: stringBuilder.append(" HAVING ");
215: ((AbstractPredicate) query.getHaving()).setExpressionToQuery(stringBuilder, parameterFiller);
216: }
217:
218: if (!getOrderList().isEmpty()) {
219: stringBuilder.append(' ').append(SoqlConstants.ORDER_BY).append(' ');
220: List<Order> orders = getOrderList();
221: for (int i = 0; i < orders.size(); i++) {
222: ((AbstractExpression) orders.get(i).getExpression()).setExpressionToQuery(stringBuilder, parameterFiller);
223: stringBuilder.append(' ').append(orders.get(i).isAscending() ? SoqlConstants.ASC : SoqlConstants.DESC);
224: if (orders.size() > 1 && (i + 1) != orders.size()) {
225: stringBuilder.append(", ");
226: }
227: }
228: }
229: return stringBuilder.toString();
230: }
231: }