Project

General

Profile

Download (29.9 KB) Statistics
| Branch: | Tag: | Revision:
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

    
10
package eu.etaxonomy.cdm.persistence.dao.hibernate.common;
11

    
12
import java.util.ArrayList;
13
import java.util.List;
14
import java.util.UUID;
15

    
16
import org.apache.log4j.Logger;
17
import org.apache.lucene.analysis.standard.StandardAnalyzer;
18
import org.apache.lucene.queryparser.classic.ParseException;
19
import org.apache.lucene.queryparser.classic.QueryParser;
20
import org.hibernate.Criteria;
21
import org.hibernate.Query;
22
import org.hibernate.Session;
23
import org.hibernate.criterion.Criterion;
24
import org.hibernate.criterion.Order;
25
import org.hibernate.criterion.Projections;
26
import org.hibernate.criterion.Restrictions;
27
import org.hibernate.envers.query.AuditEntity;
28
import org.hibernate.envers.query.AuditQuery;
29
import org.hibernate.search.FullTextSession;
30
import org.hibernate.search.Search;
31
import org.hibernate.search.SearchFactory;
32

    
33
import eu.etaxonomy.cdm.model.common.CdmBase;
34
import eu.etaxonomy.cdm.model.common.Credit;
35
import eu.etaxonomy.cdm.model.common.IAnnotatableEntity;
36
import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
37
import eu.etaxonomy.cdm.model.common.IdentifiableSource;
38
import eu.etaxonomy.cdm.model.common.LSID;
39
import eu.etaxonomy.cdm.model.common.MarkerType;
40
import eu.etaxonomy.cdm.model.media.Rights;
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 class IdentifiableDaoBase<T extends IdentifiableEntity>
51
        extends AnnotatableDaoImpl<T>
52
        implements IIdentifiableDao<T>{
53

    
54
    @SuppressWarnings("unused")
55
    private static final Logger logger = Logger.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 query = prepareFindTitleCache(clazz, queryString, pageSize,
95
                pageNumber, matchMode, false);
96
        @SuppressWarnings("unchecked")
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 query = prepareFindTitleCache(clazz, queryString, null,
105
                null, matchMode, true);
106
        Long result = (Long)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 Query prepareFindTitleCache(Class<? extends T> clazz,
119
            String queryString, Integer pageSize, Integer pageNumber,
120
            MatchMode matchMode, boolean doCount) {
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 query = getSession().createQuery(hql);
133

    
134
        if(pageSize != null && !doCount) {
135
            query.setMaxResults(pageSize);
136
            if(pageNumber != null) {
137
                query.setFirstResult(pageNumber * pageSize);
138
            }
139
        }
140
        return query;
141
    }
142

    
143
    @Override
144
    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) {
145
        return findByParam(clazz, "titleCache", queryString, matchmode, criterion, pageSize, pageNumber, orderHints, propertyPaths);
146
    }
147

    
148
    @Override
149
    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) {
150
        return findByParam(clazz, "title", queryString, matchmode, criterion, pageSize, pageNumber, orderHints, propertyPaths);
151
    }
152

    
153
    @Override
154
    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) {
155
        return findByParamWithRestrictions(clazz, "titleCache", queryString, matchmode, restrictions, pageSize, pageNumber, orderHints, propertyPaths);
156
    }
157

    
158
    @Override
159
    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) {
160
        return findByParamWithRestrictions(clazz, "title", queryString, matchmode, restrictions, pageSize, pageNumber, orderHints, propertyPaths);
161
    }
162

    
163
    @Override
164
    public List<T> findByTitle(String queryString, MatchMode matchmode, int page, int pagesize, List<Criterion> criteria) {
165
        checkNotInPriorView("IdentifiableDaoBase.findByTitle(String queryString, MATCH_MODE matchmode, int page, int pagesize, List<Criterion> criteria)");
166
        Criteria crit = getSession().createCriteria(type);
167
        if (matchmode == MatchMode.EXACT) {
168
            crit.add(Restrictions.eq("titleCache", matchmode.queryStringFrom(queryString)));
169
        } else {
170
//			crit.add(Restrictions.ilike("titleCache", matchmode.queryStringFrom(queryString)));
171
            crit.add(Restrictions.like("titleCache", matchmode.queryStringFrom(queryString)));
172
        }
173
        if (pagesize >= 0) {
174
            crit.setMaxResults(pagesize);
175
        }
176
        if(criteria != null){
177
            for (Criterion criterion : criteria) {
178
                crit.add(criterion);
179
            }
180
        }
181
        crit.addOrder(Order.asc("titleCache"));
182
        int firstItem = (page - 1) * pagesize;
183
        crit.setFirstResult(firstItem);
184
        @SuppressWarnings("unchecked")
185
        List<T> results = crit.list();
186
        List<String> propertyPaths = null;
187
        defaultBeanInitializer.initializeAll(results, propertyPaths);
188
        return results;
189
    }
190

    
191
    @Override
192
    public long countRights(T identifiableEntity) {
193
        checkNotInPriorView("IdentifiableDaoBase.countRights(T identifiableEntity)");
194
        Query query = getSession().createQuery("select count(rights) from " + type.getSimpleName() + " identifiableEntity join identifiableEntity.rights rights where identifiableEntity = :identifiableEntity");
195
        query.setParameter("identifiableEntity",identifiableEntity);
196
        return (Long)query.uniqueResult();
197
    }
198

    
199
    @Override
200
    public long countSources(T identifiableEntity) {
201
        checkNotInPriorView("IdentifiableDaoBase.countSources(T identifiableEntity)");
202
        Query query = getSession().createQuery("SELECT COUNT(source) FROM "+identifiableEntity.getClass().getName() + " ie JOIN ie.sources source WHERE ie = :identifiableEntity");
203
        query.setParameter("identifiableEntity", identifiableEntity);
204
        return (Long)query.uniqueResult();
205
    }
206

    
207
    @Override
208
    public List<Rights> getRights(T identifiableEntity, Integer pageSize, Integer pageNumber, List<String> propertyPaths) {
209
        checkNotInPriorView("IdentifiableDaoBase.getRights(T identifiableEntity, Integer pageSize, Integer pageNumber, List<String> propertyPaths)");
210
        Query query = getSession().createQuery("select rights from " + type.getSimpleName() + " identifiableEntity join identifiableEntity.rights rights where identifiableEntity = :identifiableEntity");
211
        query.setParameter("identifiableEntity",identifiableEntity);
212
        setPagingParameter(query, pageSize, pageNumber);
213
        @SuppressWarnings("unchecked")
214
        List<Rights> results = query.list();
215
        defaultBeanInitializer.initializeAll(results, propertyPaths);
216
        return results;
217
    }
218

    
219
//    @Override  //TODO add to interface, maybe add property path
220
    public List<Credit> getCredits(T identifiableEntity, Integer pageSize, Integer pageNumber) {
221
        checkNotInPriorView("IdentifiableDaoBase.getCredits(T identifiableEntity, Integer pageSize, Integer pageNumber)");
222
        Query query = getSession().createQuery("select credits from " + type.getSimpleName() + " identifiableEntity join identifiableEntity.credits credits where identifiableEntity = :identifiableEntity");
223
        query.setParameter("identifiableEntity",identifiableEntity);
224
        setPagingParameter(query, pageSize, pageNumber);
225
        @SuppressWarnings("unchecked")
226
        List<Credit> result = query.list();
227
        return result;
228
    }
229

    
230
    @Override
231
    public List<IdentifiableSource> getSources(T identifiableEntity, Integer pageSize, Integer pageNumber, List<String> propertyPaths) {
232
        checkNotInPriorView("IdentifiableDaoBase.getSources(T identifiableEntity, Integer pageSize, Integer pageNumber)");
233
        Query query = getSession().createQuery("SELECT source FROM "+ identifiableEntity.getClass().getName()+ " ie JOIN ie.sources source WHERE ie.id = :id");
234
        query.setParameter("id",identifiableEntity.getId());
235
        setPagingParameter(query, pageSize, pageNumber);
236
        @SuppressWarnings("unchecked")
237
        List<IdentifiableSource> results = query.list();
238
        defaultBeanInitializer.initializeAll(results, propertyPaths);
239
        return results;
240
    }
241

    
242
    @Override
243
    public List<T> findOriginalSourceByIdInSource(String idInSource, String idNamespace) {
244
        checkNotInPriorView("IdentifiableDaoBase.findOriginalSourceByIdInSource(String idInSource, String idNamespace)");
245
        Query query = getSession().createQuery(
246
                "Select c from " + type.getSimpleName() + " as c " +
247
                "inner join c.sources as source " +
248
                "where source.idInSource = :idInSource " +
249
                    " AND source.idNamespace = :idNamespace"
250
            );
251
        query.setString("idInSource", idInSource);
252
        query.setString("idNamespace", idNamespace);
253
        //TODO integrate reference in where
254

    
255
        @SuppressWarnings("unchecked")
256
        List<T> result = query.list();
257
        return result;
258
    }
259

    
260
    @Override
261
    public T find(LSID lsid) {
262
        checkNotInPriorView("IdentifiableDaoBase.find(LSID lsid)");
263
        Criteria criteria = getSession().createCriteria(type);
264
        criteria.add(Restrictions.eq("lsid.authority", lsid.getAuthority()));
265
        criteria.add(Restrictions.eq("lsid.namespace", lsid.getNamespace()));
266
        criteria.add(Restrictions.eq("lsid.object", lsid.getObject()));
267

    
268
        if(lsid.getRevision() != null) {
269
            criteria.add(Restrictions.eq("lsid.revision", lsid.getRevision()));
270
        }
271

    
272
        @SuppressWarnings("unchecked")
273
		T object = (T)criteria.uniqueResult();
274
        if(object != null) {
275
            return object;
276
        } else {
277
            AuditQuery query = getAuditReader().createQuery().forRevisionsOfEntity(type, false, true);
278
            query.add(AuditEntity.property("lsid_authority").eq(lsid.getAuthority()));
279
            query.add(AuditEntity.property("lsid_namespace").eq(lsid.getNamespace()));
280
            query.add(AuditEntity.property("lsid_object").eq(lsid.getObject()));
281

    
282
            if(lsid.getRevision() != null) {
283
                query.add(AuditEntity.property("lsid_revision").eq(lsid.getRevision()));
284
            }
285

    
286
            query.addOrder(AuditEntity.revisionNumber().asc());
287
            query.setMaxResults(1);
288
            query.setFirstResult(0);
289
            @SuppressWarnings("unchecked")
290
			List<Object[]> objs = query.getResultList();
291
            if(objs.isEmpty()) {
292
                return null;
293
            } else {
294
                @SuppressWarnings("unchecked")
295
				T result = (T)objs.get(0)[0];
296
                return result;
297
            }
298
        }
299
    }
300

    
301
    @SuppressWarnings("deprecation")
302
    @Override
303
    public String getTitleCache(UUID uuid, boolean refresh){
304
        if (! refresh){
305
            String queryStr = String.format("SELECT titleCache FROM %s t WHERE t.uuid = '%s'", type.getSimpleName() , uuid.toString());
306
            Query query = getSession().createQuery(queryStr);
307
            List<?> list = query.list();
308
            return list.isEmpty()? null : (String)list.get(0);
309
        }else{
310
            T entity = this.findByUuid(uuid);
311
            if (entity == null){
312
                return null;
313
            }
314
            entity.setTitleCache(null);
315
            return entity.getTitleCache();
316
        }
317
    }
318

    
319
    @Override
320
    public long countByTitle(Class<? extends T> clazz, String queryString,  MatchMode matchmode, List<Criterion> criterion) {
321
        return countByParam(clazz, "titleCache",queryString,matchmode,criterion);
322
    }
323

    
324
    @Override
325
    public long countByReferenceTitle(Class<? extends T> clazz, String queryString, MatchMode matchmode, List<Criterion> criterion) {
326
        return countByParam(clazz, "title",queryString,matchmode,criterion);
327
    }
328

    
329
    @Override
330
    public long countByTitleWithRestrictions(Class<? extends T> clazz, String queryString,	MatchMode matchmode, List<Restriction<?>> restrictions) {
331
        return countByParamWithRestrictions(clazz, "titleCache", queryString, matchmode, restrictions);
332
    }
333

    
334
    @Override
335
    public long countByReferenceTitleWithRestrictions(Class<? extends T> clazz, String queryString,	MatchMode matchmode, List<Restriction<?>> restrictions) {
336
        return countByParamWithRestrictions(clazz, "title", queryString, matchmode, restrictions);
337
    }
338

    
339
    @Override
340
    public long count(Class<? extends T> clazz, String queryString) {
341
        checkNotInPriorView("IdentifiableDaoBase.count(Class<? extends T> clazz, String queryString)");
342
        QueryParser queryParser = new QueryParser(defaultField , new StandardAnalyzer());
343

    
344
        try {
345
            org.apache.lucene.search.Query query = queryParser.parse(queryString);
346

    
347
            FullTextSession fullTextSession = Search.getFullTextSession(this.getSession());
348
            org.hibernate.search.FullTextQuery fullTextQuery = null;
349

    
350
            if(clazz == null) {
351
                fullTextQuery = fullTextSession.createFullTextQuery(query, type);
352
            } else {
353
                fullTextQuery = fullTextSession.createFullTextQuery(query, clazz);
354
            }
355

    
356
            int  result = fullTextQuery.getResultSize();
357
            return result;
358

    
359
        } catch (ParseException e) {
360
            throw new QueryParseException(e, queryString);
361
        }
362
    }
363

    
364
    @Override
365
    public void optimizeIndex() {
366
        FullTextSession fullTextSession = Search.getFullTextSession(getSession());
367
        SearchFactory searchFactory = fullTextSession.getSearchFactory();
368
        for(Class<?> clazz : indexedClasses) {
369
            searchFactory.optimize(clazz); // optimize the indices ()
370
        }
371
        fullTextSession.flushToIndexes();
372
    }
373

    
374
    @Override
375
    public void purgeIndex() {
376
        FullTextSession fullTextSession = Search.getFullTextSession(getSession());
377
        for(Class<?> clazz : indexedClasses) {
378
            fullTextSession.purgeAll(clazz); // remove all objects of type t from indexes
379
        }
380
        fullTextSession.flushToIndexes();
381
    }
382

    
383
    @Override
384
    public void rebuildIndex() {
385
        FullTextSession fullTextSession = Search.getFullTextSession(getSession());
386

    
387
        for(T t : list(null,null)) { // re-index all objects
388
            fullTextSession.index(t);
389
        }
390
        fullTextSession.flushToIndexes();
391
    }
392

    
393
    @Override
394
    public List<T> search(Class<? extends T> clazz, String queryString,	Integer pageSize, Integer pageNumber, List<OrderHint> orderHints,List<String> propertyPaths) {
395
        checkNotInPriorView("IdentifiableDaoBase.search(Class<? extends T> clazz, String queryString, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints,List<String> propertyPaths)");
396
        QueryParser queryParser = new QueryParser(defaultField, new StandardAnalyzer());
397

    
398
        try {
399
            org.apache.lucene.search.Query query = queryParser.parse(queryString);
400

    
401
            FullTextSession fullTextSession = Search.getFullTextSession(getSession());
402
            org.hibernate.search.FullTextQuery fullTextQuery = null;
403

    
404
            if(clazz == null) {
405
                fullTextQuery = fullTextSession.createFullTextQuery(query, type);
406
            } else {
407
                fullTextQuery = fullTextSession.createFullTextQuery(query, clazz);
408
            }
409

    
410
            addOrder(fullTextQuery,orderHints);
411

    
412
            if(pageSize != null) {
413
                fullTextQuery.setMaxResults(pageSize);
414
                if(pageNumber != null) {
415
                    fullTextQuery.setFirstResult(pageNumber * pageSize);
416
                } else {
417
                    fullTextQuery.setFirstResult(0);
418
                }
419
            }
420

    
421
            @SuppressWarnings("unchecked")
422
			List<T> result = fullTextQuery.list();
423
            defaultBeanInitializer.initializeAll(result, propertyPaths);
424
            return result;
425

    
426
        } catch (ParseException e) {
427
            throw new QueryParseException(e, queryString);
428
        }
429
    }
430

    
431
    @Override
432
    public String suggestQuery(String string) {
433
        throw new UnsupportedOperationException("suggestQuery is not supported for objects of class " + type.getName());
434
    }
435

    
436
    @Override
437
    public long countByTitle(String queryString) {
438
        return countByTitle(queryString, null);
439
    }
440

    
441
    @Override
442
    public long countByTitle(String queryString, CdmBase sessionObject) {
443
        Session session = getSession();
444
        if ( sessionObject != null ) {
445
            session.update(sessionObject);
446
        }
447
        checkNotInPriorView("IdentifiableDaoBase.countByTitle(String queryString, CdmBase sessionObject)");
448
        Criteria crit = session.createCriteria(type);
449
        crit.add(Restrictions.ilike("titleCache", queryString))
450
            .setProjection(Projections.rowCount());
451
        long result =  (Long)crit.uniqueResult();
452
        return result;
453
    }
454

    
455
    @Override
456
    public long countByTitle(String queryString, MatchMode matchMode, List<Criterion> criteria) {
457
        checkNotInPriorView("IdentifiableDaoBase.findByTitle(String queryString, MATCH_MODE matchmode, int page, int pagesize, List<Criterion> criteria)");
458
        Criteria crit = getCriteria(type);
459
        if (matchMode == MatchMode.EXACT) {
460
            crit.add(Restrictions.eq("titleCache", matchMode.queryStringFrom(queryString)));
461
        } else {
462
//			crit.add(Restrictions.ilike("titleCache", matchmode.queryStringFrom(queryString)));
463
            crit.add(Restrictions.like("titleCache", matchMode.queryStringFrom(queryString)));
464
        }
465

    
466
        if(criteria != null){
467
            for (Criterion criterion : criteria) {
468
                crit.add(criterion);
469
            }
470
        }
471
        crit.setProjection(Projections.rowCount());
472

    
473
        long result = (Long)crit.uniqueResult();
474
        return result;
475
    }
476

    
477

    
478
	@Override
479
	public <S extends T> long countByIdentifier(Class<S> clazz,
480
			String identifier, DefinedTerm identifierType, MatchMode matchMode) {
481
		checkNotInPriorView("IdentifiableDaoBase.countByIdentifier(T clazz, String identifier, DefinedTerm identifierType, MatchMode matchmode)");
482

    
483
		Class<?> clazzParam = clazz == null ? type : clazz;
484
		String queryString = "SELECT count(*) FROM " + clazzParam.getSimpleName() + " as c " +
485
	                "INNER JOIN c.identifiers as ids " +
486
	                "WHERE (1=1) ";
487
		if (matchMode == null){
488
		    matchMode = MatchMode.EXACT;
489
		}
490
		if (identifier != null){
491
			queryString += " AND ids.identifier LIKE '" + matchMode.queryStringFrom(identifier)  + "'";
492
		}
493
		if (identifierType != null){
494
        	queryString += " AND ids.type = :type";
495
        }
496

    
497
		Query query = getSession().createQuery(queryString);
498
        if (identifierType != null){
499
        	query.setEntity("type", identifierType);
500
        }
501

    
502
		return (Long)query.uniqueResult();
503
	}
504

    
505
	@Override
506
	public <S extends T> List<Object[]> findByIdentifier(
507
			Class<S> clazz, String identifier, DefinedTerm identifierType,
508
			MatchMode matchMode, boolean includeEntity,
509
			Integer pageSize, Integer pageNumber, List<String> propertyPaths) {
510

    
511
		checkNotInPriorView("IdentifiableDaoBase.findByIdentifier(T clazz, String identifier, DefinedTerm identifierType, MatchMode matchmode, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths)");
512

    
513
		Class<?> clazzParam = clazz == null ? type : clazz;
514
		String queryString = "SELECT ids.type, ids.identifier, %s "
515
		        + "FROM %s as c " +
516
                " INNER JOIN c.identifiers as ids " +
517
                " WHERE (1=1) ";
518
		queryString = String.format(queryString, (includeEntity ? "c":"c.uuid, c.titleCache") , clazzParam.getSimpleName());
519

    
520
		//matchMode and identifier
521
		if (matchMode == null){
522
		    matchMode = MatchMode.EXACT;
523
		}
524
		if (identifier != null){
525
			queryString += " AND ids.identifier LIKE '" + matchMode.queryStringFrom(identifier)  + "'";
526
		}
527
        if (identifierType != null){
528
        	queryString += " AND ids.type = :type";
529
        }
530
        //order
531
        queryString +=" ORDER BY ids.type.uuid, ids.identifier, c.uuid ";
532

    
533
		Query query = getSession().createQuery(queryString);
534

    
535
		//parameters
536
		if (identifierType != null){
537
        	query.setEntity("type", identifierType);
538
        }
539

    
540
        //paging
541
        setPagingParameter(query, pageSize, pageNumber);
542

    
543
        @SuppressWarnings("unchecked")
544
		List<Object[]> results = query.list();
545
        //initialize
546
        if (includeEntity){
547
        	List<S> entities = new ArrayList<>();
548
        	for (Object[] result : results){
549
        		@SuppressWarnings("unchecked")
550
				S entity = (S)result[2];
551
        		entities.add(entity);
552
        	}
553
        	defaultBeanInitializer.initializeAll(entities, propertyPaths);
554
        }
555
        return results;
556
	}
557

    
558
    @Override
559
    public <S extends T> long countByMarker(Class<S> clazz, MarkerType markerType,
560
            Boolean markerValue) {
561
        checkNotInPriorView("IdentifiableDaoBase.countByMarker(T clazz, MarkerType markerType, Boolean markerValue)");
562

    
563
        if (markerType == null){
564
            return 0;
565
        }
566
        Class<?> clazzParam = clazz == null ? type : clazz;
567
        String queryString = "SELECT count(*) FROM " + clazzParam.getSimpleName() + " as c " +
568
                    "INNER JOIN c.markers as mks " +
569
                    "WHERE (1=1) ";
570

    
571
        if (markerValue != null){
572
            queryString += " AND mks.flag = :flag";
573
        }
574
        queryString += " AND mks.markerType = :type";
575

    
576
        Query query = getSession().createQuery(queryString);
577
        query.setEntity("type", markerType);
578
        if (markerValue != null){
579
            query.setBoolean("flag", markerValue);
580
        }
581

    
582
        Long c = (Long)query.uniqueResult();
583
        return c;
584
    }
585

    
586
	@Override
587
    public <S extends T> List<Object[]> findByMarker(
588
            Class<S> clazz, MarkerType markerType,
589
            Boolean markerValue, boolean includeEntity, Integer pageSize, Integer pageNumber,
590
            List<String> propertyPaths) {
591

    
592
        checkNotInPriorView("IdentifiableDaoBase.findByMarker(T clazz, String identifier, DefinedTerm identifierType, MatchMode matchmode, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths)");
593
        if (markerType == null){
594
            return new ArrayList<>();
595
        }
596

    
597
        Class<?> clazzParam = clazz == null ? type : clazz;
598
        String queryString = "SELECT mks.markerType, mks.flag, %s FROM %s as c " +
599
                " INNER JOIN c.markers as mks " +
600
                " WHERE (1=1) ";
601
        queryString = String.format(queryString, (includeEntity ? "c":"c.uuid, c.titleCache") , clazzParam.getSimpleName());
602

    
603
        //Matchmode and identifier
604
        if (markerValue != null){
605
            queryString += " AND mks.flag = :flag";
606
        }
607
        queryString += " AND mks.markerType = :type";
608

    
609
        //order
610
        queryString +=" ORDER BY mks.markerType.uuid, mks.flag, c.uuid ";
611

    
612
        Query query = getSession().createQuery(queryString);
613

    
614
        //parameters
615
        query.setEntity("type", markerType);
616
        if (markerValue != null){
617
            query.setBoolean("flag", markerValue);
618
        }
619

    
620
        //paging
621
        setPagingParameter(query, pageSize, pageNumber);
622

    
623
        @SuppressWarnings("unchecked")
624
        List<Object[]> results = query.list();
625
        //initialize
626
        if (includeEntity){
627
            List<S> entities = new ArrayList<>();
628
            for (Object[] result : results){
629
            	@SuppressWarnings("unchecked")
630
				S entity = (S)result[2];
631
        		entities.add(entity);
632
            }
633
            defaultBeanInitializer.initializeAll(entities, propertyPaths);
634
        }
635
        return results;
636
    }
637

    
638
    @Override
639
    public List<UuidAndTitleCache<T>> getUuidAndTitleCacheByMarker(Integer limit, String pattern, MarkerType markerType){
640

    
641
        if (markerType == null){
642
            return new ArrayList<>();
643
        }
644

    
645
        String queryString = "SELECT c.uuid, c.titleCache FROM %s as c " +
646
                " INNER JOIN c.markers as mks " +
647
                " WHERE (1=1) ";
648
        queryString = String.format(queryString, type.getSimpleName());
649

    
650
        queryString += " AND mks.markerType = :type";
651
        if (pattern != null){
652
            queryString += " AND c.titleCache like :pattern";
653
            pattern = pattern.replace("*", "%");
654
            pattern = pattern.replace("?", "_");
655
            pattern = pattern + "%";
656
        }
657

    
658
        Query query = getSession().createQuery(queryString);
659
        if (pattern != null){
660
            query.setParameter("pattern", pattern);
661
        }
662
        //parameters
663
        query.setEntity("type", markerType);
664
        query.setMaxResults(limit);
665

    
666
        @SuppressWarnings("unchecked")
667
        List<Object[]> results = query.list();
668
        List<UuidAndTitleCache<T>> uuidAndTitleCacheResult = new ArrayList<>();
669
        for (Object[] result:results){
670
            uuidAndTitleCacheResult.add(new UuidAndTitleCache<>((UUID)result[0], (String)result[1]));
671
        }
672

    
673
        return uuidAndTitleCacheResult;
674
    }
675

    
676
    @Override
677
    public List<UuidAndTitleCache<T>> getUuidAndTitleCache(Integer limit, String pattern){
678
        return getUuidAndTitleCache(type, limit, pattern);
679
    }
680

    
681
    @Override
682
    public <S extends T> List<UuidAndTitleCache<S>> getUuidAndTitleCache(Class<S> clazz, Integer limit, String pattern){
683
        Session session = getSession();
684
        if (clazz == null){
685
            clazz = (Class)this.type;
686
        }
687

    
688
        Query query = session.createQuery(
689
                "SELECT new " + SortableTaxonNodeQueryResult.class.getName() + "("
690
                + " uuid, id, titleCache "
691
                + ") "
692
                + " FROM " + clazz.getSimpleName()
693
                + (pattern!=null ? " WHERE titleCache LIKE :pattern" : ""));
694
        if(pattern!=null){
695
            pattern = pattern.replace("*", "%");
696
            pattern = pattern.replace("?", "_");
697
            pattern = pattern + "%";
698
            query.setParameter("pattern", pattern);
699
        }
700
        if (limit != null){
701
           query.setMaxResults(limit);
702
        }
703
        return getUuidAndTitleCache(query);
704
    }
705

    
706
    @Override
707
    public List<UuidAndTitleCache<T>> getUuidAndTitleCache(){
708
        return getUuidAndTitleCache(type, null, null);
709
    }
710

    
711
    protected <E extends IAnnotatableEntity> List<UuidAndTitleCache<E>> getUuidAndAbbrevTitleCache(Query query){
712
        List<UuidAndTitleCache<E>> list = new ArrayList<>();
713

    
714
		@SuppressWarnings("unchecked")
715
        List<Object[]> result = query.list();
716

    
717
        for(Object[] object : result){
718
            list.add(new UuidAndTitleCache<E>((UUID) object[0],(Integer) object[1], (String) object[3], (String) object[2]));
719
        }
720
        return list;
721
    }
722

    
723
    protected <E extends IAnnotatableEntity> List<UuidAndTitleCache<E>> getUuidAndTitleCache(Query query){
724

    
725
        List<UuidAndTitleCache<E>> list = new ArrayList<>();
726
		@SuppressWarnings("unchecked")
727
        List<Object> result = query.list();
728

    
729
        for(Object obj : result){
730
            if (obj instanceof SortableTaxonNodeQueryResult) {
731
                SortableTaxonNodeQueryResult stnqr = (SortableTaxonNodeQueryResult) obj;
732
                list.add(new UuidAndTitleCache<>(stnqr.getTaxonNodeUuid(),stnqr.getTaxonNodeId(), stnqr.getTaxonTitleCache()));
733
            }else{
734
                Object[] object = (Object[])obj;
735
                list.add(new UuidAndTitleCache<>((UUID) object[0],(Integer) object[1], (String) object[2]));
736
            }
737
        }
738
        return list;
739
    }
740

    
741
}
(9-9/18)