1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.opencastproject.assetmanager.impl.query;
22
23 import static com.entwinemedia.fn.Stream.$;
24 import static org.opencastproject.assetmanager.impl.query.PropertyPredicates.NONE;
25 import static org.opencastproject.assetmanager.impl.query.PropertyPredicates.NO_VALUE;
26
27 import org.opencastproject.assetmanager.api.Availability;
28 import org.opencastproject.assetmanager.api.PropertyName;
29 import org.opencastproject.assetmanager.api.Value.ValueType;
30 import org.opencastproject.assetmanager.api.query.ADeleteQuery;
31 import org.opencastproject.assetmanager.api.query.AQueryBuilder;
32 import org.opencastproject.assetmanager.api.query.ASelectQuery;
33 import org.opencastproject.assetmanager.api.query.Field;
34 import org.opencastproject.assetmanager.api.query.Predicate;
35 import org.opencastproject.assetmanager.api.query.PropertyField;
36 import org.opencastproject.assetmanager.api.query.Target;
37 import org.opencastproject.assetmanager.api.query.VersionField;
38 import org.opencastproject.assetmanager.impl.AssetManagerImpl;
39 import org.opencastproject.assetmanager.impl.RuntimeTypes;
40 import org.opencastproject.assetmanager.impl.persistence.EntityPaths;
41 import org.opencastproject.assetmanager.impl.persistence.QPropertyDto;
42 import org.opencastproject.assetmanager.impl.persistence.QSnapshotDto;
43 import org.opencastproject.assetmanager.impl.query.DeleteQueryContribution.Where;
44 import org.opencastproject.util.RequireUtil;
45
46 import com.entwinemedia.fn.Fn;
47 import com.entwinemedia.fn.Stream;
48 import com.entwinemedia.fn.data.Opt;
49 import com.mysema.query.jpa.impl.JPAQueryFactory;
50 import com.mysema.query.support.Expressions;
51 import com.mysema.query.types.expr.BooleanExpression;
52
53 import java.util.Date;
54
55 import javax.annotation.Nonnull;
56
57 public final class AQueryBuilderImpl implements AQueryBuilder, EntityPaths {
58 private static final Stream<QSnapshotDto> FROM_SNAPSHOT = $Q_SNAPSHOT;
59
60 private final AssetManagerImpl am;
61
62 public AQueryBuilderImpl(AssetManagerImpl am) {
63 this.am = am;
64 }
65
66
67 private static Fn<Target, SelectQueryContribution> contributeSelect(final JPAQueryFactory f) {
68 return new Fn<Target, SelectQueryContribution>() {
69 @Override public SelectQueryContribution apply(Target t) {
70 return RuntimeTypes.convert(t).contributeSelect(f);
71 }
72 };
73 }
74
75 @Override public ASelectQuery select(final Target... target) {
76 return new AbstractASelectQuery(am) {
77 @Override public SelectQueryContribution contributeSelect(JPAQueryFactory f) {
78 final Stream<SelectQueryContribution> c = $(target).map(AQueryBuilderImpl.contributeSelect(f));
79 return SelectQueryContribution.mk()
80 .fetch(c.bind(SelectQueryContribution.getFetch))
81 .from(c.bind(SelectQueryContribution.getFrom))
82 .join(c.bind(SelectQueryContribution.getJoin))
83 .where(Opt.nul(JpaFns.allOf(c.bind(SelectQueryContribution.getWhere))));
84 }
85 };
86 }
87
88 @Override public ADeleteQuery delete(final String owner, final Target target) {
89 RequireUtil.notEmpty(owner, "owner");
90 return new AbstractADeleteQuery(am, owner) {
91 @Override public DeleteQueryContribution contributeDelete(String owner) {
92 final DeleteQueryContribution c = RuntimeTypes.convert(target).contributeDelete(owner);
93 return DeleteQueryContribution.mk()
94 .from(c.from)
95 .targetPredicate(c.targetPredicate)
96 .where(c.where);
97
98
99
100
101
102
103
104
105
106 }
107 };
108 }
109
110
111 @Override public Predicate mediaPackageIds(final String... mpIds) {
112 return new AbstractPredicate() {
113
114 @Override public SelectQueryContribution contributeSelect(JPAQueryFactory f) {
115 return SelectQueryContribution.mk().from(FROM_SNAPSHOT).where(Q_SNAPSHOT.mediaPackageId.in(mpIds));
116 }
117
118
119 @Override public DeleteQueryContribution contributeDelete(String owner) {
120 return DeleteQueryContribution.mk().where(new Where() {
121 @Override public BooleanExpression fromSnapshot(@Nonnull QSnapshotDto e) {
122 return e.mediaPackageId.in(mpIds);
123 }
124
125 @Override public BooleanExpression fromProperty(@Nonnull QPropertyDto p) {
126 return p.mediaPackageId.in(mpIds);
127 }
128 });
129 }
130
131 };
132 }
133
134 @Override public Predicate mediaPackageId(final String mpId) {
135 return new AbstractPredicate() {
136
137 @Override public SelectQueryContribution contributeSelect(JPAQueryFactory f) {
138 return SelectQueryContribution.mk().from(FROM_SNAPSHOT).where(Q_SNAPSHOT.mediaPackageId.eq(mpId));
139 }
140
141
142 @Override public DeleteQueryContribution contributeDelete(String owner) {
143 return DeleteQueryContribution.mk().where(new Where() {
144 @Override public BooleanExpression fromSnapshot(@Nonnull QSnapshotDto e) {
145 return e.mediaPackageId.eq(mpId);
146 }
147
148 @Override public BooleanExpression fromProperty(@Nonnull QPropertyDto p) {
149 return p.mediaPackageId.eq(mpId);
150 }
151 });
152 }
153
154 };
155 }
156
157 @Override public Field<String> mediapackageId() {
158 return new SimpleSnapshotField<>(Q_SNAPSHOT.mediaPackageId);
159 }
160
161
162
163
164 private abstract static class SnapshotBasedPredicate extends AbstractPredicate {
165
166 @Override public SelectQueryContribution contributeSelect(JPAQueryFactory f) {
167 return SelectQueryContribution.mk().from(FROM_SNAPSHOT).where(mkSnapshotFieldPredicate(Q_SNAPSHOT));
168 }
169
170
171 @Override public DeleteQueryContribution contributeDelete(String owner) {
172 return DeleteQueryContribution.mk().where(new Where() {
173 @Override public BooleanExpression fromSnapshot(@Nonnull QSnapshotDto e) {
174 return mkSnapshotFieldPredicate(e);
175 }
176
177 @Override public BooleanExpression fromProperty(@Nonnull QPropertyDto p) {
178 return mkSnapshotFieldPredicate(Q_SNAPSHOT);
179 }
180 });
181 }
182
183 protected abstract BooleanExpression mkSnapshotFieldPredicate(QSnapshotDto e);
184 }
185
186 @Override public Field<String> seriesId() {
187 return new SimpleSnapshotField<>(Q_SNAPSHOT.seriesId);
188 }
189
190 @Override public Predicate organizationId(final String orgId) {
191 return new SnapshotBasedPredicate() {
192 @Override protected BooleanExpression mkSnapshotFieldPredicate(QSnapshotDto e) {
193 return e.organizationId.eq(orgId);
194 }
195 };
196 }
197
198 @Override public Field<String> organizationId() {
199 return new SimpleSnapshotField<>(Q_SNAPSHOT.organizationId);
200 }
201
202 @Override public Field<String> owner() {
203 return new SimpleSnapshotField<>(Q_SNAPSHOT.owner);
204 }
205
206 @Override public Predicate availability(final Availability availability) {
207 return new SnapshotBasedPredicate() {
208 @Override protected BooleanExpression mkSnapshotFieldPredicate(QSnapshotDto e) {
209 return e.availability.eq(availability.name());
210 }
211 };
212 }
213
214 @Override public Predicate storage(final String storage) {
215 return new SnapshotBasedPredicate() {
216 @Override protected BooleanExpression mkSnapshotFieldPredicate(QSnapshotDto e) {
217 return e.storageId.eq(storage);
218 }
219 };
220 }
221
222
223
224
225 @Override public Predicate hasPropertiesOf(final String namespace) {
226 return new AbstractPredicate() {
227
228 @Override public SelectQueryContribution contributeSelect(JPAQueryFactory f) {
229 return SelectQueryContribution.mk()
230 .where(PropertyPredicates.mkWhereSelect(Opt.some(namespace), NONE, NO_VALUE));
231 }
232
233
234 @Override public DeleteQueryContribution contributeDelete(String owner) {
235 return DeleteQueryContribution.mk()
236 .where(PropertyPredicates.mkWhereDelete(Opt.some(namespace), NONE, NO_VALUE));
237 }
238 };
239 }
240
241
242 @Override public Predicate hasProperties() {
243 return new AbstractPredicate() {
244
245 @Override public SelectQueryContribution contributeSelect(JPAQueryFactory f) {
246 return SelectQueryContribution.mk()
247 .where(PropertyPredicates.mkWhereSelect(NONE, NONE, NO_VALUE));
248 }
249
250
251 @Override public DeleteQueryContribution contributeDelete(String owner) {
252 return DeleteQueryContribution.mk()
253 .where(PropertyPredicates.mkWhereDelete(NONE, NONE, NO_VALUE));
254 }
255 };
256 }
257
258 @Override public Field<Date> archived() {
259 return new SimpleSnapshotField<>(Q_SNAPSHOT.archivalDate);
260 }
261
262 @Override public VersionField version() {
263 return new VersionFieldImpl();
264 }
265
266 @Override public <A> PropertyField<A> property(ValueType<A> ev, String namespace, String name) {
267 return new PropertyFieldImpl<>(ev, PropertyName.mk(namespace, name));
268 }
269
270 @Override public <A> PropertyField<A> property(ValueType<A> ev, PropertyName fqn) {
271 return new PropertyFieldImpl<>(ev, fqn);
272 }
273
274 @Override public Target snapshot() {
275 return new AbstractTarget() {
276 @Override public SelectQueryContribution contributeSelect(JPAQueryFactory f) {
277 return SelectQueryContribution.mk().from(FROM_SNAPSHOT).fetch($Q_SNAPSHOT);
278 }
279
280 @Override public DeleteQueryContribution contributeDelete(String owner) {
281 return DeleteQueryContribution.mk().from(FROM_SNAPSHOT).where(Q_SNAPSHOT.owner.eq(owner));
282 }
283 };
284 }
285
286 @Override public Target propertiesOf(final String... namespace) {
287 return propertyTarget(namespace);
288 }
289
290 @Override public Target properties(PropertyName... fqn) {
291 return propertyTarget(fqn);
292 }
293
294 @Override public Target nothing() {
295 return new AbstractTarget() {
296 @Override public SelectQueryContribution contributeSelect(JPAQueryFactory f) {
297 return SelectQueryContribution.mk();
298 }
299
300 @Override public DeleteQueryContribution contributeDelete(String owner) {
301 return DeleteQueryContribution.mk();
302 }
303
304 };
305 }
306
307 @Override public Predicate always() {
308 return new AbstractPredicate() {
309
310 @Override public SelectQueryContribution contributeSelect(JPAQueryFactory f) {
311 return SelectQueryContribution.mk().where(Expressions.booleanTemplate("true = true"));
312 }
313
314
315 @Override public DeleteQueryContribution contributeDelete(String owner) {
316 return DeleteQueryContribution.mk().where(Expressions.booleanTemplate("true = true"));
317 }
318 };
319 }
320
321
322
323
324
325 static Target propertyTarget(String... namespace) {
326 final Stream<BooleanExpression> onExpressions = $(namespace).map(new Fn<String, BooleanExpression>() {
327 @Override public BooleanExpression apply(String namespace) {
328 return Q_PROPERTY.namespace.eq(namespace);
329 }
330 });
331 return propertyTarget(onExpressions);
332 }
333
334 static Target propertyTarget(PropertyName... fqn) {
335 final Stream<BooleanExpression> onExpressions = $(fqn).map(new Fn<PropertyName, BooleanExpression>() {
336 @Override public BooleanExpression apply(PropertyName name) {
337 return Q_PROPERTY.namespace.eq(name.getNamespace()).and(Q_PROPERTY.propertyName.eq(name.getName()));
338 }
339 });
340 return propertyTarget(onExpressions);
341 }
342
343
344
345
346
347 private static Target propertyTarget(final Stream<BooleanExpression> onExpressions) {
348 return new AbstractTarget() {
349 @Override public SelectQueryContribution contributeSelect(JPAQueryFactory f) {
350
351 final BooleanExpression on = Q_PROPERTY.mediaPackageId
352 .eq(Q_SNAPSHOT.mediaPackageId)
353 .and(JpaFns.anyOf(onExpressions));
354 return SelectQueryContribution.mk().join($(new Join(Q_SNAPSHOT, Q_PROPERTY, on))).fetch($Q_PROPERTY);
355 }
356
357 @Override public DeleteQueryContribution contributeDelete(String owner) {
358 return DeleteQueryContribution.mk().from($Q_PROPERTY).targetPredicate(JpaFns.anyOf(onExpressions));
359 }
360 };
361 }
362 }