Project

General

Profile

Download (21.8 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.taxon;
11

    
12
import java.math.BigInteger;
13
import java.util.ArrayList;
14
import java.util.Collection;
15
import java.util.Collections;
16
import java.util.HashMap;
17
import java.util.HashSet;
18
import java.util.Iterator;
19
import java.util.List;
20
import java.util.Map;
21
import java.util.Set;
22
import java.util.UUID;
23

    
24
import org.apache.log4j.Logger;
25
import org.hibernate.Criteria;
26
import org.hibernate.Hibernate;
27
import org.hibernate.Query;
28
import org.hibernate.criterion.Projections;
29
import org.hibernate.criterion.Restrictions;
30
import org.springframework.beans.factory.annotation.Autowired;
31
import org.springframework.beans.factory.annotation.Qualifier;
32
import org.springframework.stereotype.Repository;
33

    
34
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
35
import eu.etaxonomy.cdm.model.common.TreeIndex;
36
import eu.etaxonomy.cdm.model.reference.Reference;
37
import eu.etaxonomy.cdm.model.taxon.Classification;
38
import eu.etaxonomy.cdm.model.taxon.Taxon;
39
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
40
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
41
import eu.etaxonomy.cdm.model.taxon.TaxonNodeAgentRelation;
42
import eu.etaxonomy.cdm.model.taxon.UuidAndTitleCacheTaxonComparator;
43
import eu.etaxonomy.cdm.persistence.dao.hibernate.common.AnnotatableDaoImpl;
44
import eu.etaxonomy.cdm.persistence.dao.taxon.IClassificationDao;
45
import eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao;
46
import eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonNodeDao;
47
import eu.etaxonomy.cdm.persistence.dto.MergeResult;
48
import eu.etaxonomy.cdm.persistence.dto.TaxonNodeDto;
49
import eu.etaxonomy.cdm.persistence.dto.UuidAndTitleCache;
50

    
51
/**
52
 * @author a.mueller
53
 * @created 16.06.2009
54
 */
55
@Repository
56
@Qualifier("taxonNodeDaoHibernateImpl")
57
public class TaxonNodeDaoHibernateImpl extends AnnotatableDaoImpl<TaxonNode>
58
		implements ITaxonNodeDao {
59
	@SuppressWarnings("unused")
60
	private static final Logger logger = Logger.getLogger(TaxonNodeDaoHibernateImpl.class);
61

    
62
	@Autowired
63
	private ITaxonDao taxonDao;
64
	@Autowired
65
	private IClassificationDao classificationDao;
66

    
67
	public TaxonNodeDaoHibernateImpl() {
68
		super(TaxonNode.class);
69
	}
70
	@Override
71
	public UUID delete(TaxonNode persistentObject, boolean deleteChildren){
72
		Taxon taxon = persistentObject.getTaxon();
73
		taxon = HibernateProxyHelper.deproxy(taxon, Taxon.class);
74

    
75
		/*Session session = this.getSession();
76
		Query query = session.createQuery("from TaxonNode t where t.taxon = :taxon");
77
		query.setParameter("taxon", taxon);
78
		List result = query.list();*/
79
		if (taxon != null){
80
		    Hibernate.initialize(taxon);
81
		    Hibernate.initialize(taxon.getTaxonNodes());
82
			Set<TaxonNode> nodes = taxon.getTaxonNodes();
83
			//Hibernate.initialize(taxon.getTaxonNodes());
84
			for (TaxonNode node:nodes) {
85
			    node = HibernateProxyHelper.deproxy(node, TaxonNode.class);
86

    
87
			    if (node.equals(persistentObject)){
88
			        if (node.hasChildNodes()){
89
			            Iterator<TaxonNode> childNodes = node.getChildNodes().iterator();
90
			            TaxonNode childNode;
91
			            List<TaxonNode> listForDeletion = new ArrayList<TaxonNode>();
92
	                    while (childNodes.hasNext()){
93
	                        childNode = childNodes.next();
94
	                        listForDeletion.add(childNode);
95
	                        childNodes.remove();
96

    
97
	                    }
98
	                    for (TaxonNode deleteNode:listForDeletion){
99
	                        delete(deleteNode, deleteChildren);
100
	                    }
101
	                }
102

    
103
			        taxon.removeTaxonNode(node, deleteChildren);
104
			        taxonDao.saveOrUpdate(taxon);
105
    				taxon = HibernateProxyHelper.deproxy(taxonDao.findByUuid(taxon.getUuid()), Taxon.class);
106
    				taxonDao.delete(taxon);
107

    
108
			    }
109
			}
110
		}
111

    
112
		UUID result = super.delete(persistentObject);
113

    
114
		return result;
115
	}
116

    
117
	@Override
118
	public List<TaxonNode> getTaxonOfAcceptedTaxaByClassification(Classification classification, Integer start, Integer end) {
119
		int classificationId = classification.getId();
120
		String limit = "";
121
		if(start !=null && end != null){
122
		    limit = "LIMIT "+start+"," +end;
123
		}
124
		//FIXME write test
125
        String queryString = "SELECT DISTINCT nodes.*,taxa.titleCache FROM TaxonNode AS nodes LEFT JOIN TaxonBase AS taxa ON nodes.taxon_id = taxa.id WHERE taxa.DTYPE = 'Taxon' AND nodes.classification_id = " + classificationId + " ORDER BY taxa.titleCache " + limit;
126
        @SuppressWarnings("unchecked")
127
        List<TaxonNode> result  = getSession().createSQLQuery(queryString).addEntity(TaxonNode.class).list();
128

    
129
       return result;
130
	}
131

    
132
    @Override
133
    public int countTaxonOfAcceptedTaxaByClassification(Classification classification){
134
        int classificationId = classification.getId();
135
        //FIXME write test
136
        String queryString = "SELECT DISTINCT COUNT('nodes.*') FROM TaxonNode AS nodes LEFT JOIN TaxonBase AS taxa ON nodes.taxon_id = taxa.id WHERE taxa.DTYPE = 'Taxon' AND nodes.classification_id = " + classificationId;
137
         @SuppressWarnings("unchecked")
138
        List<BigInteger> result = getSession().createSQLQuery(queryString).list();
139
         return result.get(0).intValue ();
140
    }
141

    
142
    @Override
143
    public List<TaxonNodeDto> listChildNodesAsUuidAndTitleCache(UuidAndTitleCache<TaxonNode> parent) {
144
        String queryString = "select tn from TaxonNode tn INNER JOIN tn.taxon as tx where tn.parent.uuid = :parentId";
145
        Query query =  getSession().createQuery(queryString);
146
        query.setParameter("parentId", parent.getUuid());
147
        List<TaxonNodeDto> list = new ArrayList<>();
148

    
149
        @SuppressWarnings("unchecked")
150
        List<TaxonNode> result = query.list();
151

    
152
        for(TaxonNode object : result){
153
            list.add(new TaxonNodeDto(object));
154
        }
155
        return list;
156
    }
157

    
158
    @Override
159
    public List<UuidAndTitleCache<TaxonNode>> getUuidAndTitleCache(Integer limit, String pattern, UUID classificationUuid) {
160
        String queryString = "select tn.uuid, tn.id, tx.titleCache, tx.name.rank from TaxonNode tn "
161
        		+ "INNER JOIN tn.taxon as tx "
162
        		+ "INNER JOIN tn.classification as cls "
163
        		+ "WHERE tx.titleCache like :pattern ";
164
        if(classificationUuid!=null){
165
        	queryString += "AND cls.uuid = :classificationUuid";
166
        }
167
        Query query =  getSession().createQuery(queryString);
168

    
169
        query.setParameter("pattern", pattern.toLowerCase()+"%");
170
        query.setParameter("classificationUuid", classificationUuid);
171

    
172
        List<UuidAndTitleCache<TaxonNode>> list = new ArrayList<>();
173

    
174
        @SuppressWarnings("unchecked")
175
        List<Object[]> result = query.list();
176

    
177
        if (result != null){
178
            Collections.sort(result, new UuidAndTitleCacheTaxonComparator());
179
        }
180
        for(Object[] object : result){
181
            list.add(new UuidAndTitleCache<TaxonNode>((UUID) object[0],(Integer) object[1], (String) object[2]));
182
        }
183
        return list;
184
    }
185

    
186
    /**
187
     * {@inheritDoc}
188
     */
189
    @Override
190
    public UuidAndTitleCache<TaxonNode> getParentUuidAndTitleCache(UuidAndTitleCache<TaxonNode> child) {
191
        String queryString = "select tn.parent.uuid, tn.parent.id, tn.parent.taxon.titleCache, tn.parent.classification.titleCache "
192
                + " from TaxonNode tn"
193
                + " LEFT OUTER JOIN tn.parent.taxon"
194
                + " where tn.id = :childId";
195
        Query query =  getSession().createQuery(queryString);
196
        query.setParameter("childId", child.getId());
197
        List<UuidAndTitleCache<TaxonNode>> list = new ArrayList<>();
198

    
199
        @SuppressWarnings("unchecked")
200
        List<Object[]> result = query.list();
201

    
202
        for(Object[] object : result){
203
            UUID uuid = (UUID) object[0];
204
            Integer id = (Integer) object[1];
205
            String taxonTitleCache = (String) object[2];
206
            String classificationTitleCache = (String) object[3];
207
            if(taxonTitleCache!=null){
208
                list.add(new UuidAndTitleCache<TaxonNode>(uuid,id, taxonTitleCache));
209
            }
210
            else{
211
                list.add(new UuidAndTitleCache<TaxonNode>(uuid,id, classificationTitleCache));
212
            }
213
        }
214
        if(list.size()==1){
215
            return list.iterator().next();
216
        }
217
        return null;
218
    }
219

    
220
    @Override
221
    public List<TaxonNode> listChildrenOf(TaxonNode node, Integer pageSize, Integer pageIndex, List<String> propertyPaths, boolean recursive){
222
    	if (recursive == true){
223
    		Criteria crit = getSession().createCriteria(TaxonNode.class);
224
    		crit.add( Restrictions.like("treeIndex", node.treeIndex()+ "%") );
225
    		if(pageSize != null) {
226
                crit.setMaxResults(pageSize);
227
                if(pageIndex != null) {
228
                    crit.setFirstResult(pageIndex * pageSize);
229
                } else {
230
                    crit.setFirstResult(0);
231
                }
232
            }
233
    		@SuppressWarnings("unchecked")
234
            List<TaxonNode> results = crit.list();
235
    		results.remove(node);
236
    		defaultBeanInitializer.initializeAll(results, propertyPaths);
237
    		return results;
238
    	}else{
239
    		return classificationDao.listChildrenOf(node.getTaxon(), node.getClassification(), pageSize, pageIndex, propertyPaths);
240
    	}
241

    
242
    }
243

    
244
    @Override
245
	public Long countChildrenOf(TaxonNode node, Classification classification,
246
			boolean recursive) {
247

    
248
		if (recursive == true){
249
			Criteria crit = getSession().createCriteria(TaxonNode.class);
250
    		crit.add( Restrictions.like("treeIndex", node.treeIndex()+ "%") );
251
    		crit.setProjection(Projections.rowCount());
252
    		return ((Integer)crit.uniqueResult().hashCode()).longValue();
253
		}else{
254
			return classificationDao.countChildrenOf(node.getTaxon(), classification);
255
		}
256
	}
257
    /**
258
     * {@inheritDoc}
259
     */
260
    @Override
261
    public List<TaxonNodeAgentRelation> listTaxonNodeAgentRelations(UUID taxonUuid, UUID classificationUuid,
262
            UUID agentUuid, UUID rankUuid, UUID relTypeUuid, Integer start, Integer limit, List<String> propertyPaths) {
263

    
264

    
265
        StringBuilder hql = prepareListTaxonNodeAgentRelations(taxonUuid, classificationUuid, agentUuid, rankUuid, relTypeUuid, false);
266

    
267
        Query query =  getSession().createQuery(hql.toString());
268

    
269
        if(limit != null) {
270
            query.setMaxResults(limit);
271
            if(start != null) {
272
                query.setFirstResult(start);
273
            }
274
        }
275

    
276
        setParamsForListTaxonNodeAgentRelations(taxonUuid, classificationUuid, agentUuid, rankUuid, relTypeUuid, query);
277

    
278
        @SuppressWarnings("unchecked")
279
        List<TaxonNodeAgentRelation> records = query.list();
280

    
281
        if(propertyPaths != null) {
282
            defaultBeanInitializer.initializeAll(records, propertyPaths);
283
        }
284
        return records;
285
    }
286

    
287
    /**
288
     * {@inheritDoc}
289
     */
290
    @Override
291
    public long countTaxonNodeAgentRelations(UUID taxonUuid, UUID classificationUuid, UUID agentUuid, UUID rankUuid, UUID relTypeUuid) {
292

    
293
        StringBuilder hql = prepareListTaxonNodeAgentRelations(taxonUuid, classificationUuid, agentUuid, rankUuid, relTypeUuid, true);
294
        Query query =  getSession().createQuery(hql.toString());
295

    
296
        setParamsForListTaxonNodeAgentRelations(taxonUuid, classificationUuid, agentUuid, rankUuid, relTypeUuid, query);
297

    
298
        Long count = Long.parseLong(query.uniqueResult().toString());
299

    
300
        return count;
301
    }
302
    /**
303
     * @param taxonUuid
304
     * @param classificationUuid
305
     * @param agentUuid
306
     * @param relTypeUuid TODO
307
     * @param doCount TODO
308
     * @param rankId
309
     *     limit to taxa having this rank, only applies if <code>taxonUuid = null</code>
310
     * @return
311
     */
312
    private StringBuilder prepareListTaxonNodeAgentRelations(UUID taxonUuid, UUID classificationUuid, UUID agentUuid, UUID rankUuid, UUID relTypeUuid, boolean doCount) {
313

    
314
        StringBuilder hql = new StringBuilder();
315

    
316
        String join_fetch_mode = doCount ? "join" : "join fetch";
317

    
318
        if(doCount) {
319
            hql.append("select count(tnar)");
320
        } else {
321
            hql.append("select tnar");
322
        }
323

    
324
        hql.append(" from TaxonNodeAgentRelation as tnar ");
325
        if(taxonUuid != null) {
326
            // taxonUuid is search filter, do not fetch it
327
            hql.append(" join tnar.taxonNode as tn join tn.taxon as t ");
328
        } else {
329
            hql.append(join_fetch_mode).append(" tnar.taxonNode as tn ").append(join_fetch_mode).append(" tn.taxon as t ");
330
            if(rankUuid != null) {
331
                hql.append(" join t.name as n ");
332
            }
333
        }
334
        hql.append(" join tn.classification as c ");
335
        if(agentUuid != null) {
336
            // agentUuid is search filter, do not fetch it
337
//            hql.append(" join tnar.agent as a ");
338
            hql.append(join_fetch_mode).append(" tnar.agent as a ");
339
        } else {
340
            hql.append(join_fetch_mode).append(" tnar.agent as a ");
341
        }
342

    
343
        hql.append(" where 1 = 1 ");
344

    
345
        if(relTypeUuid != null) {
346
            hql.append(" and tnar.type.uuid = :relTypeUuid ");
347
        }
348

    
349
        if(taxonUuid != null) {
350
            hql.append(" and t.uuid = :taxonUuid ");
351
        } else {
352
            if(rankUuid != null) {
353
                hql.append(" and n.rank.uuid = :rankUuid ");
354
            }
355
        }
356
        if(classificationUuid != null) {
357
            hql.append(" and c.uuid = :classificationUuid ");
358
        }
359
        if(agentUuid != null) {
360
            hql.append(" and a.uuid = :agentUuid ");
361
        }
362

    
363
        hql.append(" order by a.titleCache");
364
        return hql;
365
    }
366
    /**
367
     * @param taxonUuid
368
     * @param classificationUuid
369
     * @param agentUuid
370
     * @param relTypeUuid TODO
371
     * @param query
372
     * @param rankId TODO
373
     */
374
    private void setParamsForListTaxonNodeAgentRelations(UUID taxonUuid, UUID classificationUuid, UUID agentUuid,
375
            UUID rankUuid, UUID relTypeUuid, Query query) {
376

    
377
        if(taxonUuid != null) {
378
            query.setParameter("taxonUuid", taxonUuid);
379
        } else {
380
            if(rankUuid != null) {
381
                query.setParameter("rankUuid", rankUuid);
382
            }
383
        }
384
        if(classificationUuid != null) {
385
            query.setParameter("classificationUuid", classificationUuid);
386
        }
387
        if(agentUuid != null) {
388
            query.setParameter("agentUuid", agentUuid);
389
        }
390
        if(relTypeUuid != null) {
391
            query.setParameter("relTypeUuid", relTypeUuid);
392
        }
393
    }
394

    
395
    @Override
396
    public Map<TreeIndex, Integer> rankOrderIndexForTreeIndex(List<TreeIndex> treeIndexes,
397
            Integer minRankOrderIndex,
398
            Integer maxRankOrderIndex) {
399

    
400
        Map<TreeIndex, Integer> result = new HashMap<>();
401
        if (treeIndexes == null || treeIndexes.isEmpty()){
402
            return result;
403
        }
404

    
405
        String hql = " SELECT tn.treeIndex, r.orderIndex "
406
                + " FROM TaxonNode tn JOIN tn.taxon t JOIN t.name n JOIN n.rank r "
407
                + " WHERE tn.treeIndex IN (:treeIndexes) ";
408
        if (minRankOrderIndex != null){
409
            hql += " AND r.orderIndex <= :minOrderIndex";
410
        }
411
        if (maxRankOrderIndex != null){
412
            hql += " AND r.orderIndex >= :maxOrderIndex";
413
        }
414

    
415
        Query query =  getSession().createQuery(hql);
416
        query.setParameterList("treeIndexes", TreeIndex.toString(treeIndexes));
417
        if (minRankOrderIndex != null){
418
            query.setParameter("minOrderIndex", minRankOrderIndex);
419
        }
420
        if (maxRankOrderIndex != null){
421
            query.setParameter("maxOrderIndex", maxRankOrderIndex);
422
        }
423

    
424
        @SuppressWarnings("unchecked")
425
        List<Object[]> list = query.list();
426
        for (Object[] o : list){
427
            result.put(TreeIndex.NewInstance((String)o[0]), (Integer)o[1]);
428
        }
429
        return result;
430
    }
431

    
432
    @Override
433
    public Map<TreeIndex, UuidAndTitleCache<?>> taxonUuidsForTreeIndexes(Collection<TreeIndex> treeIndexes) {
434
        Map<TreeIndex, UuidAndTitleCache<?>> result = new HashMap<>();
435
        if (treeIndexes == null || treeIndexes.isEmpty()){
436
            return result;
437
        }
438

    
439
        String hql = " SELECT tn.treeIndex, t.uuid, tnb.titleCache "
440
                + " FROM TaxonNode tn JOIN tn.taxon t Join t.name tnb "
441
                + " WHERE tn.treeIndex IN (:treeIndexes) ";
442
        Query query =  getSession().createQuery(hql);
443
        query.setParameterList("treeIndexes", TreeIndex.toString(treeIndexes));
444

    
445
        @SuppressWarnings("unchecked")
446
        List<Object[]> list = query.list();
447
        for (Object[] o : list){
448
            result.put(TreeIndex.NewInstance((String)o[0]), new UuidAndTitleCache<>((UUID)o[1], null, (String)o[2]));
449
        }
450
        return result;
451
    }
452

    
453

    
454
    /**
455
     * {@inheritDoc}
456
     */
457
    //#3465
458
    @Override
459
    public Set<TaxonBase> setSecundumForSubtreeAcceptedTaxa(TreeIndex subTreeIndex, Reference newSec, boolean overwriteExisting, boolean includeSharedTaxa, boolean emptyDetail) {
460
        //for some reason this does not work, maybe because the listeners are not activated,
461
        //but also the first taxon for some reason does not get updated in terms of secundum, but only by the udpate listener
462
//        String where = "SELECT t.id FROM TaxonNode tn JOIN tn.taxon t " +
463
//                " WHERE tn.treeIndex like '%s%%' ORDER BY t.id";
464
//        where = String.format(where, subTreeIndex.toString());
465
//        Query query1 = getSession().createQuery(where);
466
//        List l = query1.list();
467
//
468
//        String hql = "UPDATE Taxon SET sec = :newSec, publish=false WHERE id IN (" + where + ")";
469
//        Query query = getSession().createQuery(hql);
470
//        query.setParameter("newSec", newSec);
471
//        int n = query.executeUpdate();
472

    
473
        String queryStr = acceptedForSubtreeQueryStr(includeSharedTaxa, subTreeIndex);
474
        if (!overwriteExisting){
475
            queryStr += " AND t.sec IS NULL ";
476
        }
477
        return setSecundum(newSec, emptyDetail, queryStr);
478

    
479
    }
480

    
481
    @Override
482
    public Set<TaxonBase> setSecundumForSubtreeSynonyms(TreeIndex subTreeIndex, Reference newSec, boolean overwriteExisting, boolean includeSharedTaxa, boolean emptyDetail) {
483

    
484
        String queryStr = synonymForSubtreeQueryStr(includeSharedTaxa, subTreeIndex);
485
        if (!overwriteExisting){
486
            queryStr += " AND syn.sec IS NULL ";
487
        }
488
        return setSecundum(newSec, emptyDetail, queryStr);
489
    }
490
    /**
491
     * @param newSec
492
     * @param emptyDetail
493
     * @param queryStr
494
     * @return
495
     */
496
    @SuppressWarnings("unchecked")
497
    private <T extends TaxonBase<?>> Set<T> setSecundum(Reference newSec, boolean emptyDetail, String queryStr) {
498
        Query query = getSession().createQuery(queryStr);
499
        @SuppressWarnings("unchecked")
500
        List<T> synonymList = query.list();
501
        MergeResult mergeResult;
502
        Set<T> result = new HashSet<>();
503
        for (T taxonBase : synonymList){
504
            if (taxonBase != null){
505
                taxonBase = (T) taxonDao.load(taxonBase.getUuid());
506
                taxonBase.setSec(newSec);
507
                if (emptyDetail){
508
                    taxonBase.setSecMicroReference(null);
509
                }
510
               result.add(taxonBase);
511
            }
512

    
513
        }
514
      return result;
515
    }
516

    
517

    
518
    /**
519
     * {@inheritDoc}
520
     */
521
    @Override
522
    public Set<TaxonBase> setPublishForSubtreeAcceptedTaxa(TreeIndex subTreeIndex, boolean publish,
523
            boolean includeSharedTaxa) {
524
        String queryStr = acceptedForSubtreeQueryStr(includeSharedTaxa, subTreeIndex);
525
        return setPublish(publish, queryStr);
526
    }
527

    
528
    /**
529
     * {@inheritDoc}
530
     */
531
    @Override
532
    public Set<TaxonBase> setPublishForSubtreeSynonyms(TreeIndex subTreeIndex, boolean publish,
533
            boolean includeSharedTaxa) {
534
        String queryStr = synonymForSubtreeQueryStr(includeSharedTaxa, subTreeIndex);
535
        return setPublish(publish, queryStr);
536
    }
537

    
538
    /**
539
     * @param publish
540
     * @param queryStr
541
     * @return
542
     */
543
    private <T extends TaxonBase<?>> Set<T> setPublish(boolean publish, String queryStr) {
544
        Query query = getSession().createQuery(queryStr);
545
        @SuppressWarnings("unchecked")
546
        List<T> taxonList = query.list();
547
        Set<T> result = new HashSet<>();
548
        for (T taxon : taxonList){
549
            taxon = (T)taxonDao.load(taxon.getUuid());
550
            taxon.setPublish(publish);
551
            result.add(taxon);
552
        }
553
        return result;
554
    }
555

    
556

    
557
    /**
558
     * @param includeSharedTaxa
559
     * @param subTreeIndex
560
     * @return
561
     */
562
    private String synonymForSubtreeQueryStr(boolean includeSharedTaxa, TreeIndex subTreeIndex) {
563
        String queryStr = "SELECT syn "
564
                + " FROM TaxonNode tn JOIN tn.taxon t JOIN t.synonyms syn"
565
                + " WHERE tn.treeIndex like '%s%%' ";
566
        if (!includeSharedTaxa){
567
            queryStr += " AND t.taxonNodes.size <= 1  ";
568
        }
569
        queryStr = String.format(queryStr, subTreeIndex.toString());
570

    
571
        return queryStr;
572
    }
573

    
574
    private String acceptedForSubtreeQueryStr(boolean includeSharedTaxa, TreeIndex subTreeIndex) {
575
        String queryStr = "SELECT t "
576
                + " FROM TaxonNode tn JOIN tn.taxon t "
577
                + " WHERE tn.treeIndex like '%s%%' ";
578
        if (!includeSharedTaxa){
579
            queryStr += " AND t.taxonNodes.size <= 1  ";
580
        }
581
        queryStr = String.format(queryStr, subTreeIndex.toString());
582

    
583
        return queryStr;
584
    }
585

    
586

    
587
}
(4-4/5)