84973a5794d4658b38a0180cf6c04da18d4595d7
[cdmlib.git] / cdmlib-persistence / src / main / java / eu / etaxonomy / cdm / persistence / dao / hibernate / common / IdentifiableDaoBase.java
1 /**
2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
5 *
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
8 */
9 package eu.etaxonomy.cdm.persistence.dao.hibernate.common;
10
11 import java.util.ArrayList;
12 import java.util.List;
13 import java.util.UUID;
14
15 import org.apache.logging.log4j.LogManager;import org.apache.logging.log4j.Logger;
16 import org.apache.lucene.analysis.standard.StandardAnalyzer;
17 import org.apache.lucene.queryparser.classic.ParseException;
18 import org.apache.lucene.queryparser.classic.QueryParser;
19 import org.hibernate.Criteria;
20 import org.hibernate.Session;
21 import org.hibernate.criterion.Criterion;
22 import org.hibernate.criterion.Order;
23 import org.hibernate.criterion.Projections;
24 import org.hibernate.criterion.Restrictions;
25 import org.hibernate.envers.query.AuditEntity;
26 import org.hibernate.envers.query.AuditQuery;
27 import org.hibernate.query.Query;
28 import org.hibernate.search.FullTextSession;
29 import org.hibernate.search.Search;
30 import org.hibernate.search.SearchFactory;
31
32 import eu.etaxonomy.cdm.model.common.CdmBase;
33 import eu.etaxonomy.cdm.model.common.Credit;
34 import eu.etaxonomy.cdm.model.common.IAnnotatableEntity;
35 import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
36 import eu.etaxonomy.cdm.model.common.IdentifiableSource;
37 import eu.etaxonomy.cdm.model.common.LSID;
38 import eu.etaxonomy.cdm.model.common.MarkerType;
39 import eu.etaxonomy.cdm.model.media.Rights;
40 import eu.etaxonomy.cdm.model.reference.OriginalSourceBase;
41 import eu.etaxonomy.cdm.model.term.DefinedTerm;
42 import eu.etaxonomy.cdm.persistence.dao.QueryParseException;
43 import eu.etaxonomy.cdm.persistence.dao.common.IIdentifiableDao;
44 import eu.etaxonomy.cdm.persistence.dao.common.Restriction;
45 import eu.etaxonomy.cdm.persistence.dto.SortableTaxonNodeQueryResult;
46 import eu.etaxonomy.cdm.persistence.dto.UuidAndTitleCache;
47 import eu.etaxonomy.cdm.persistence.query.MatchMode;
48 import eu.etaxonomy.cdm.persistence.query.OrderHint;
49
50 public abstract class IdentifiableDaoBase<T extends IdentifiableEntity>
51 extends AnnotatableDaoBaseImpl<T>
52 implements IIdentifiableDao<T>{
53
54 @SuppressWarnings("unused")
55 private static final Logger logger = LogManager.getLogger(IdentifiableDaoBase.class);
56
57 protected String defaultField = "titleCache_tokenized";
58 protected Class<? extends T> indexedClasses[];
59
60 public IdentifiableDaoBase(Class<T> type) {
61 super(type);
62 }
63
64
65 @Override
66 public List<T> findByTitle(String queryString) {
67 return findByTitle(queryString, null);
68 }
69
70 @Override
71 public List<T> findByTitle(String queryString, CdmBase sessionObject) {
72 /**
73 * FIXME why do we need to call update in a find* method? I don't know for sure
74 * that this is a good idea . . .
75 */
76 Session session = getSession();
77 if ( sessionObject != null ) {
78 session.update(sessionObject);
79 }
80 checkNotInPriorView("IdentifiableDaoBase.findByTitle(String queryString, CdmBase sessionObject)");
81 Criteria crit = session.createCriteria(type);
82 crit.add(Restrictions.ilike("titleCache", queryString));
83 @SuppressWarnings("unchecked")
84 List<T> results = crit.list();
85 List<String> propertyPaths = null;
86 defaultBeanInitializer.initializeAll(results, propertyPaths);
87 return results;
88 }
89
90 @Override
91 public List<String> findTitleCache(Class<? extends T> clazz, String queryString,
92 Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, MatchMode matchMode){
93
94 Query<String> query = prepareFindTitleCache(clazz, queryString, pageSize,
95 pageNumber, matchMode, false, String.class);
96
97 List<String> result = query.list();
98 return result;
99 }
100
101 @Override
102 public Long countTitleCache(Class<? extends T> clazz, String queryString, MatchMode matchMode){
103
104 Query<Long> query = prepareFindTitleCache(clazz, queryString, null,
105 null, matchMode, true, Long.class);
106 Long result = query.uniqueResult();
107 return result;
108 }
109
110 /**
111 * @param clazz filter by class - can be null to include all instances of type T
112 * @param queryString the query string to filter by
113 * @param pageSize
114 * @param pageNumber
115 * @param matchmode use a particular type of matching (can be null - defaults to exact matching)
116 * @return
117 */
118 private <R extends Object> Query<R> prepareFindTitleCache(Class<? extends T> clazz,
119 String queryString, Integer pageSize, Integer pageNumber,
120 MatchMode matchMode, boolean doCount, Class<R> resultClass) {
121 if(clazz == null) {
122 clazz = type;
123 }
124
125 String what = (doCount ? "count(distinct e.titleCache)": "distinct e.titleCache");
126
127 if(matchMode != null){
128 queryString = matchMode.queryStringFrom(queryString);
129 }
130 String hql = "select " + what + " from " + clazz.getName() + " e where e.titleCache like '" + queryString + "'";
131
132 Query<R> query = getSession().createQuery(hql, resultClass);
133
134 if (!doCount) {
135 this.addPageSizeAndNumber(query, pageSize, pageNumber);
136 }
137
138 return query;
139 }
140
141 @Override
142 public <S extends T> List<S> findByTitle(Class<S> clazz, String queryString, MatchMode matchmode, List<Criterion> criterion, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {
143 return findByParam(clazz, "titleCache", queryString, matchmode, criterion, pageSize, pageNumber, orderHints, propertyPaths);
144 }
145
146 @Override
147 public <S extends T> List<S> findByReferenceTitle(Class<S> clazz, String queryString, MatchMode matchmode, List<Criterion> criterion, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {
148 return findByParam(clazz, "title", queryString, matchmode, criterion, pageSize, pageNumber, orderHints, propertyPaths);
149 }
150
151 @Override
152 public <S extends T> List<S> findByTitleWithRestrictions(Class<S> clazz, String queryString, MatchMode matchmode, List<Restriction<?>> restrictions, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {
153 return findByParamWithRestrictions(clazz, "titleCache", queryString, matchmode, restrictions, pageSize, pageNumber, orderHints, propertyPaths);
154 }
155
156 @Override
157 public <S extends T> List<S> findByReferenceTitleWithRestrictions(Class<S> clazz, String queryString, MatchMode matchmode, List<Restriction<?>> restrictions, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {
158 return findByParamWithRestrictions(clazz, "title", queryString, matchmode, restrictions, pageSize, pageNumber, orderHints, propertyPaths);
159 }
160
161 @Override
162 public List<T> findByTitle(String queryString, MatchMode matchmode, int page, int pagesize, List<Criterion> criteria) {
163 checkNotInPriorView("IdentifiableDaoBase.findByTitle(String queryString, MATCH_MODE matchmode, int page, int pagesize, List<Criterion> criteria)");
164 Criteria crit = getSession().createCriteria(type);
165 if (matchmode == MatchMode.EXACT) {
166 crit.add(Restrictions.eq("titleCache", matchmode.queryStringFrom(queryString)));
167 } else {
168 // crit.add(Restrictions.ilike("titleCache", matchmode.queryStringFrom(queryString)));
169 crit.add(Restrictions.like("titleCache", matchmode.queryStringFrom(queryString)));
170 }
171 if (pagesize >= 0) {
172 crit.setMaxResults(pagesize);
173 }
174 if(criteria != null){
175 for (Criterion criterion : criteria) {
176 crit.add(criterion);
177 }
178 }
179 crit.addOrder(Order.asc("titleCache"));
180 int firstItem = (page - 1) * pagesize;
181 crit.setFirstResult(firstItem);
182 @SuppressWarnings("unchecked")
183 List<T> results = crit.list();
184 List<String> propertyPaths = null;
185 defaultBeanInitializer.initializeAll(results, propertyPaths);
186 return results;
187 }
188
189 @Override
190 public long countRights(T identifiableEntity) {
191 checkNotInPriorView("IdentifiableDaoBase.countRights(T identifiableEntity)");
192 Query<Long> query = getSession().createQuery("select count(rights) from " + type.getSimpleName() + " identifiableEntity join identifiableEntity.rights rights where identifiableEntity = :identifiableEntity",
193 Long.class);
194 query.setParameter("identifiableEntity",identifiableEntity);
195 return query.uniqueResult();
196 }
197
198 @Override
199 public long countSources(T identifiableEntity) {
200 checkNotInPriorView("IdentifiableDaoBase.countSources(T identifiableEntity)");
201 Query<Long> query = getSession().createQuery(
202 "SELECT COUNT(source) FROM "+identifiableEntity.getClass().getName() + " ie JOIN ie.sources source WHERE ie = :identifiableEntity",
203 Long.class);
204 query.setParameter("identifiableEntity", identifiableEntity);
205 return query.uniqueResult();
206 }
207
208 @Override
209 public List<Rights> getRights(T identifiableEntity, Integer pageSize, Integer pageNumber, List<String> propertyPaths) {
210 checkNotInPriorView("IdentifiableDaoBase.getRights(T identifiableEntity, Integer pageSize, Integer pageNumber, List<String> propertyPaths)");
211 Query<Rights> query = getSession().createQuery("select rights from " + type.getSimpleName() + " identifiableEntity join identifiableEntity.rights rights where identifiableEntity = :identifiableEntity",
212 Rights.class);
213 query.setParameter("identifiableEntity", identifiableEntity);
214 addPageSizeAndNumber(query, pageSize, pageNumber);
215 List<Rights> results = query.list();
216 defaultBeanInitializer.initializeAll(results, propertyPaths);
217 return results;
218 }
219
220 // @Override //TODO add to interface, maybe add property path
221 public List<Credit> getCredits(T identifiableEntity, Integer pageSize, Integer pageNumber) {
222 checkNotInPriorView("IdentifiableDaoBase.getCredits(T identifiableEntity, Integer pageSize, Integer pageNumber)");
223 Query<Credit> query = getSession().createQuery("select credits from " + type.getSimpleName() + " identifiableEntity join identifiableEntity.credits credits where identifiableEntity = :identifiableEntity",
224 Credit.class);
225 query.setParameter("identifiableEntity",identifiableEntity);
226 addPageSizeAndNumber(query, pageSize, pageNumber);
227
228 List<Credit> result = query.list();
229 return result;
230 }
231
232 @Override
233 public List<IdentifiableSource> getSources(T identifiableEntity, Integer pageSize, Integer pageNumber, List<String> propertyPaths) {
234
235 checkNotInPriorView("IdentifiableDaoBase.getSources(T identifiableEntity, Integer pageSize, Integer pageNumber)");
236 Query<OriginalSourceBase> query = getSession().createQuery(
237 " SELECT source "
238 + " FROM "+ identifiableEntity.getClass().getName()+ " ie JOIN ie.sources source "
239 + " WHERE ie.id = :id",
240 OriginalSourceBase.class); //IdentifiableEntity.sources is currently of type OriginalSourceBase, not IdentifiableSource. See comment on SourcedEntityBase.sources
241 query.setParameter("id", identifiableEntity.getId());
242 addPageSizeAndNumber(query, pageSize, pageNumber);
243
244 @SuppressWarnings({ "unchecked", "rawtypes" }) //see comment on createQuery
245 List<IdentifiableSource> results = (List)query.list();
246 defaultBeanInitializer.initializeAll(results, propertyPaths);
247 return results;
248 }
249
250 @Override
251 public List<T> findOriginalSourceByIdInSource(String idInSource, String idNamespace) {
252 checkNotInPriorView("IdentifiableDaoBase.findOriginalSourceByIdInSource(String idInSource, String idNamespace)");
253 Query<T> query = getSession().createQuery(
254 "Select c from " + type.getSimpleName() + " as c " +
255 "inner join c.sources as source " +
256 "where source.idInSource = :idInSource " +
257 " AND source.idNamespace = :idNamespace", type
258 );
259 query.setParameter("idInSource", idInSource);
260 query.setParameter("idNamespace", idNamespace);
261 //TODO integrate reference in where
262
263 List<T> result = query.list();
264 return result;
265 }
266
267 @Override
268 public T find(LSID lsid) {
269 checkNotInPriorView("IdentifiableDaoBase.find(LSID lsid)");
270 Criteria criteria = getSession().createCriteria(type);
271 criteria.add(Restrictions.eq("lsid.authority", lsid.getAuthority()));
272 criteria.add(Restrictions.eq("lsid.namespace", lsid.getNamespace()));
273 criteria.add(Restrictions.eq("lsid.object", lsid.getObject()));
274
275 if(lsid.getRevision() != null) {
276 criteria.add(Restrictions.eq("lsid.revision", lsid.getRevision()));
277 }
278
279 @SuppressWarnings("unchecked")
280 T object = (T)criteria.uniqueResult();
281 if(object != null) {
282 return object;
283 } else {
284 AuditQuery query = getAuditReader().createQuery().forRevisionsOfEntity(type, false, true);
285 query.add(AuditEntity.property("lsid_authority").eq(lsid.getAuthority()));
286 query.add(AuditEntity.property("lsid_namespace").eq(lsid.getNamespace()));
287 query.add(AuditEntity.property("lsid_object").eq(lsid.getObject()));
288
289 if(lsid.getRevision() != null) {
290 query.add(AuditEntity.property("lsid_revision").eq(lsid.getRevision()));
291 }
292
293 query.addOrder(AuditEntity.revisionNumber().asc());
294 query.setMaxResults(1);
295 query.setFirstResult(0);
296 @SuppressWarnings("unchecked")
297 List<Object[]> objs = query.getResultList();
298 if(objs.isEmpty()) {
299 return null;
300 } else {
301 @SuppressWarnings("unchecked")
302 T result = (T)objs.get(0)[0];
303 return result;
304 }
305 }
306 }
307
308 @SuppressWarnings("deprecation")
309 @Override
310 public String getTitleCache(UUID uuid, boolean refresh){
311 if (! refresh){
312 String queryStr = String.format("SELECT titleCache FROM %s t WHERE t.uuid = '%s'", type.getSimpleName() , uuid.toString());
313 Query<String> query = getSession().createQuery(queryStr, String.class);
314 List<String> list = query.list();
315 return list.isEmpty()? null : list.get(0);
316 }else{
317 T entity = this.findByUuid(uuid);
318 if (entity == null){
319 return null;
320 }
321 entity.setTitleCache(null);
322 return entity.getTitleCache();
323 }
324 }
325
326 @Override
327 public long countByTitle(Class<? extends T> clazz, String queryString, MatchMode matchmode, List<Criterion> criterion) {
328 return countByParam(clazz, "titleCache",queryString,matchmode,criterion);
329 }
330
331 @Override
332 public long countByReferenceTitle(Class<? extends T> clazz, String queryString, MatchMode matchmode, List<Criterion> criterion) {
333 return countByParam(clazz, "title",queryString,matchmode,criterion);
334 }
335
336 @Override
337 public long countByTitleWithRestrictions(Class<? extends T> clazz, String queryString, MatchMode matchmode, List<Restriction<?>> restrictions) {
338 return countByParamWithRestrictions(clazz, "titleCache", queryString, matchmode, restrictions);
339 }
340
341 @Override
342 public long countByReferenceTitleWithRestrictions(Class<? extends T> clazz, String queryString, MatchMode matchmode, List<Restriction<?>> restrictions) {
343 return countByParamWithRestrictions(clazz, "title", queryString, matchmode, restrictions);
344 }
345
346 @Override
347 public long count(Class<? extends T> clazz, String queryString) {
348 checkNotInPriorView("IdentifiableDaoBase.count(Class<? extends T> clazz, String queryString)");
349 QueryParser queryParser = new QueryParser(defaultField , new StandardAnalyzer());
350
351 try {
352 org.apache.lucene.search.Query query = queryParser.parse(queryString);
353
354 FullTextSession fullTextSession = Search.getFullTextSession(this.getSession());
355 org.hibernate.search.FullTextQuery fullTextQuery = null;
356
357 if(clazz == null) {
358 fullTextQuery = fullTextSession.createFullTextQuery(query, type);
359 } else {
360 fullTextQuery = fullTextSession.createFullTextQuery(query, clazz);
361 }
362
363 int result = fullTextQuery.getResultSize();
364 return result;
365
366 } catch (ParseException e) {
367 throw new QueryParseException(e, queryString);
368 }
369 }
370
371 @Override
372 public void optimizeIndex() {
373 FullTextSession fullTextSession = Search.getFullTextSession(getSession());
374 SearchFactory searchFactory = fullTextSession.getSearchFactory();
375 for(Class<?> clazz : indexedClasses) {
376 searchFactory.optimize(clazz); // optimize the indices ()
377 }
378 fullTextSession.flushToIndexes();
379 }
380
381 @Override
382 public void purgeIndex() {
383 FullTextSession fullTextSession = Search.getFullTextSession(getSession());
384 for(Class<?> clazz : indexedClasses) {
385 fullTextSession.purgeAll(clazz); // remove all objects of type t from indexes
386 }
387 fullTextSession.flushToIndexes();
388 }
389
390 @Override
391 public void rebuildIndex() {
392 FullTextSession fullTextSession = Search.getFullTextSession(getSession());
393
394 for(T t : list(null,null)) { // re-index all objects
395 fullTextSession.index(t);
396 }
397 fullTextSession.flushToIndexes();
398 }
399
400 @Override
401 public List<T> search(Class<? extends T> clazz, String queryString, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints,List<String> propertyPaths) {
402 checkNotInPriorView("IdentifiableDaoBase.search(Class<? extends T> clazz, String queryString, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints,List<String> propertyPaths)");
403 QueryParser queryParser = new QueryParser(defaultField, new StandardAnalyzer());
404
405 try {
406 org.apache.lucene.search.Query query = queryParser.parse(queryString);
407
408 FullTextSession fullTextSession = Search.getFullTextSession(getSession());
409 org.hibernate.search.FullTextQuery fullTextQuery = null;
410
411 if(clazz == null) {
412 fullTextQuery = fullTextSession.createFullTextQuery(query, type);
413 } else {
414 fullTextQuery = fullTextSession.createFullTextQuery(query, clazz);
415 }
416
417 addOrder(fullTextQuery,orderHints);
418
419 if(pageSize != null) {
420 fullTextQuery.setMaxResults(pageSize);
421 if(pageNumber != null) {
422 fullTextQuery.setFirstResult(pageNumber * pageSize);
423 } else {
424 fullTextQuery.setFirstResult(0);
425 }
426 }
427
428 @SuppressWarnings("unchecked")
429 List<T> result = fullTextQuery.list();
430 defaultBeanInitializer.initializeAll(result, propertyPaths);
431 return result;
432
433 } catch (ParseException e) {
434 throw new QueryParseException(e, queryString);
435 }
436 }
437
438 @Override
439 public String suggestQuery(String string) {
440 throw new UnsupportedOperationException("suggestQuery is not supported for objects of class " + type.getName());
441 }
442
443 @Override
444 public long countByTitle(String queryString) {
445 return countByTitle(queryString, null);
446 }
447
448 @Override
449 public long countByTitle(String queryString, CdmBase sessionObject) {
450 Session session = getSession();
451 if ( sessionObject != null ) {
452 session.update(sessionObject);
453 }
454 checkNotInPriorView("IdentifiableDaoBase.countByTitle(String queryString, CdmBase sessionObject)");
455 Criteria crit = session.createCriteria(type);
456 crit.add(Restrictions.ilike("titleCache", queryString))
457 .setProjection(Projections.rowCount());
458 long result = (Long)crit.uniqueResult();
459 return result;
460 }
461
462 @Override
463 public long countByTitle(String queryString, MatchMode matchMode, List<Criterion> criteria) {
464 checkNotInPriorView("IdentifiableDaoBase.findByTitle(String queryString, MATCH_MODE matchmode, int page, int pagesize, List<Criterion> criteria)");
465 Criteria crit = getCriteria(type);
466 if (matchMode == MatchMode.EXACT) {
467 crit.add(Restrictions.eq("titleCache", matchMode.queryStringFrom(queryString)));
468 } else {
469 // crit.add(Restrictions.ilike("titleCache", matchmode.queryStringFrom(queryString)));
470 crit.add(Restrictions.like("titleCache", matchMode.queryStringFrom(queryString)));
471 }
472
473 if(criteria != null){
474 for (Criterion criterion : criteria) {
475 crit.add(criterion);
476 }
477 }
478 crit.setProjection(Projections.rowCount());
479
480 long result = (Long)crit.uniqueResult();
481 return result;
482 }
483
484
485 @Override
486 public <S extends T> long countByIdentifier(Class<S> clazz,
487 String identifier, DefinedTerm identifierType, MatchMode matchMode) {
488 checkNotInPriorView("IdentifiableDaoBase.countByIdentifier(T clazz, String identifier, DefinedTerm identifierType, MatchMode matchmode)");
489
490 Class<?> clazzParam = clazz == null ? type : clazz;
491 String queryString = "SELECT count(*) FROM " + clazzParam.getSimpleName() + " as c " +
492 "INNER JOIN c.identifiers as ids " +
493 "WHERE (1=1) ";
494 if (matchMode == null){
495 matchMode = MatchMode.EXACT;
496 }
497 if (identifier != null){
498 queryString += " AND ids.identifier LIKE '" + matchMode.queryStringFrom(identifier) + "'";
499 }
500 if (identifierType != null){
501 queryString += " AND ids.type = :type";
502 }
503
504 Query<Long> query = getSession().createQuery(queryString, Long.class);
505 if (identifierType != null){
506 query.setParameter("type", identifierType);
507 }
508
509 return query.uniqueResult();
510 }
511
512 @Override
513 public <S extends T> List<Object[]> findByIdentifier(
514 Class<S> clazz, String identifier, DefinedTerm identifierType,
515 MatchMode matchMode, boolean includeEntity,
516 Integer pageSize, Integer pageNumber, List<String> propertyPaths) {
517
518 checkNotInPriorView("IdentifiableDaoBase.findByIdentifier(T clazz, String identifier, DefinedTerm identifierType, MatchMode matchmode, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths)");
519
520 Class<?> clazzParam = clazz == null ? type : clazz;
521 String queryString = "SELECT ids.type, ids.identifier, %s "
522 + "FROM %s as c " +
523 " INNER JOIN c.identifiers as ids " +
524 " WHERE (1=1) ";
525 queryString = String.format(queryString, (includeEntity ? "c":"c.uuid, c.titleCache") , clazzParam.getSimpleName());
526
527 //matchMode and identifier
528 if (matchMode == null){
529 matchMode = MatchMode.EXACT;
530 }
531 if (identifier != null){
532 queryString += " AND ids.identifier LIKE '" + matchMode.queryStringFrom(identifier) + "'";
533 }
534 if (identifierType != null){
535 queryString += " AND ids.type = :type";
536 }
537 //order
538 queryString +=" ORDER BY ids.type.uuid, ids.identifier, c.uuid ";
539
540 Query<Object[]> query = getSession().createQuery(queryString, Object[].class);
541
542 //parameters
543 if (identifierType != null){
544 query.setParameter("type", identifierType);
545 }
546
547 //paging
548 addPageSizeAndNumber(query, pageSize, pageNumber);
549
550 List<Object[]> results = query.list();
551 //initialize
552 if (includeEntity){
553 List<S> entities = new ArrayList<>();
554 for (Object[] result : results){
555 @SuppressWarnings("unchecked")
556 S entity = (S)result[2];
557 entities.add(entity);
558 }
559 defaultBeanInitializer.initializeAll(entities, propertyPaths);
560 }
561 return results;
562 }
563
564 @Override
565 public <S extends T> long countByMarker(Class<S> clazz, MarkerType markerType,
566 Boolean markerValue) {
567 checkNotInPriorView("IdentifiableDaoBase.countByMarker(T clazz, MarkerType markerType, Boolean markerValue)");
568
569 if (markerType == null){
570 return 0;
571 }
572 Class<?> clazzParam = clazz == null ? type : clazz;
573 String queryString = "SELECT count(*) FROM " + clazzParam.getSimpleName() + " as c " +
574 "INNER JOIN c.markers as mks " +
575 "WHERE (1=1) ";
576
577 if (markerValue != null){
578 queryString += " AND mks.flag = :flag";
579 }
580 queryString += " AND mks.markerType = :type";
581
582 Query<Long> query = getSession().createQuery(queryString, Long.class);
583 query.setParameter("type", markerType);
584 if (markerValue != null){
585 query.setParameter("flag", markerValue);
586 }
587
588 Long c = query.uniqueResult();
589 return c;
590 }
591
592 @Override
593 public <S extends T> List<Object[]> findByMarker(
594 Class<S> clazz, MarkerType markerType,
595 Boolean markerValue, boolean includeEntity, Integer pageSize, Integer pageNumber,
596 List<String> propertyPaths) {
597
598 checkNotInPriorView("IdentifiableDaoBase.findByMarker(T clazz, String identifier, DefinedTerm identifierType, MatchMode matchmode, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths)");
599 if (markerType == null){
600 return new ArrayList<>();
601 }
602
603 Class<?> clazzParam = clazz == null ? type : clazz;
604 String queryString = "SELECT mks.markerType, mks.flag, %s FROM %s as c " +
605 " INNER JOIN c.markers as mks " +
606 " WHERE (1=1) ";
607 queryString = String.format(queryString, (includeEntity ? "c":"c.uuid, c.titleCache") , clazzParam.getSimpleName());
608
609 //Matchmode and identifier
610 if (markerValue != null){
611 queryString += " AND mks.flag = :flag";
612 }
613 queryString += " AND mks.markerType = :type";
614
615 //order
616 queryString +=" ORDER BY mks.markerType.uuid, mks.flag, c.uuid ";
617
618 Query<Object[]> query = getSession().createQuery(queryString, Object[].class);
619
620 //parameters
621 query.setParameter("type", markerType);
622 if (markerValue != null){
623 query.setParameter("flag", markerValue);
624 }
625
626 //paging
627 addPageSizeAndNumber(query, pageSize, pageNumber);
628
629 List<Object[]> results = query.list();
630 //initialize
631 if (includeEntity){
632 List<S> entities = new ArrayList<>();
633 for (Object[] result : results){
634 @SuppressWarnings("unchecked")
635 S entity = (S)result[2];
636 entities.add(entity);
637 }
638 defaultBeanInitializer.initializeAll(entities, propertyPaths);
639 }
640 return results;
641 }
642
643 @Override
644 public List<UuidAndTitleCache<T>> getUuidAndTitleCacheByMarker(Integer limit, String pattern, MarkerType markerType){
645
646 if (markerType == null){
647 return new ArrayList<>();
648 }
649
650 String queryString = "SELECT c.uuid, c.titleCache FROM %s as c " +
651 " INNER JOIN c.markers as mks " +
652 " WHERE (1=1) ";
653 queryString = String.format(queryString, type.getSimpleName());
654
655 queryString += " AND mks.markerType = :type";
656 if (pattern != null){
657 queryString += " AND c.titleCache like :pattern";
658 pattern = pattern.replace("*", "%");
659 pattern = pattern.replace("?", "_");
660 pattern = pattern + "%";
661 }
662
663 Query<Object[]> query = getSession().createQuery(queryString, Object[].class);
664 if (pattern != null){
665 query.setParameter("pattern", pattern);
666 }
667 //parameters
668 query.setParameter("type", markerType);
669 query.setMaxResults(limit);
670
671 List<Object[]> results = query.list();
672 List<UuidAndTitleCache<T>> uuidAndTitleCacheResult = new ArrayList<>();
673 for (Object[] result:results){
674 uuidAndTitleCacheResult.add(new UuidAndTitleCache<>((UUID)result[0], (String)result[1]));
675 }
676
677 return uuidAndTitleCacheResult;
678 }
679
680 @Override
681 public List<UuidAndTitleCache<T>> getUuidAndTitleCache(Integer limit, String pattern){
682 return getUuidAndTitleCache(type, limit, pattern);
683 }
684
685 @Override
686 public <S extends T> List<UuidAndTitleCache<S>> getUuidAndTitleCache(Class<S> clazz, Integer limit, String pattern){
687 Session session = getSession();
688 if (clazz == null){
689 clazz = (Class)this.type;
690 }
691
692 Query<SortableTaxonNodeQueryResult> query = session.createQuery(
693 "SELECT new " + SortableTaxonNodeQueryResult.class.getName()
694 + " (uuid, id, titleCache) "
695 + " FROM " + clazz.getSimpleName()
696 + (pattern!=null ? " WHERE titleCache LIKE :pattern" : ""),
697 SortableTaxonNodeQueryResult.class);
698 if(pattern!=null){
699 pattern = pattern.replace("*", "%");
700 pattern = pattern.replace("?", "_");
701 pattern = pattern + "%";
702 query.setParameter("pattern", pattern);
703 }
704 if (limit != null){
705 query.setMaxResults(limit);
706 }
707 return getUuidAndTitleCache((Query)query);
708 }
709
710 @Override
711 public List<UuidAndTitleCache<T>> getUuidAndTitleCache(){
712 return getUuidAndTitleCache(type, null, null);
713 }
714
715 protected <E extends IAnnotatableEntity> List<UuidAndTitleCache<E>> getUuidAndAbbrevTitleCache(Query<Object[]> query){
716 List<UuidAndTitleCache<E>> list = new ArrayList<>();
717
718 List<Object[]> result = query.list();
719
720 for(Object[] object : result){
721 list.add(new UuidAndTitleCache<E>((UUID) object[0],(Integer) object[1], (String) object[3], (String) object[2]));
722 }
723 return list;
724 }
725
726 protected <E extends IAnnotatableEntity> List<UuidAndTitleCache<E>> getUuidAndTitleCache(Query query){
727
728 List<UuidAndTitleCache<E>> list = new ArrayList<>();
729 @SuppressWarnings("unchecked")
730 List<Object> result = query.list();
731
732 for(Object obj : result){
733 if (obj instanceof SortableTaxonNodeQueryResult) {
734 SortableTaxonNodeQueryResult stnqr = (SortableTaxonNodeQueryResult)obj;
735 list.add(new UuidAndTitleCache<>(stnqr.getTaxonNodeUuid(),stnqr.getTaxonNodeId(), stnqr.getTaxonTitleCache()));
736 }else{
737 Object[] object = (Object[])obj;
738 list.add(new UuidAndTitleCache<>((UUID) object[0],(Integer) object[1], (String) object[2]));
739 }
740 }
741 return list;
742 }
743
744 }