Project

General

Profile

Download (16.5 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.HashMap;
16
import java.util.Iterator;
17
import java.util.List;
18
import java.util.Map;
19
import java.util.Set;
20
import java.util.UUID;
21

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

    
32
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
33
import eu.etaxonomy.cdm.model.common.TreeIndex;
34
import eu.etaxonomy.cdm.model.taxon.Classification;
35
import eu.etaxonomy.cdm.model.taxon.Taxon;
36
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
37
import eu.etaxonomy.cdm.model.taxon.TaxonNodeAgentRelation;
38
import eu.etaxonomy.cdm.persistence.dao.hibernate.common.AnnotatableDaoImpl;
39
import eu.etaxonomy.cdm.persistence.dao.taxon.IClassificationDao;
40
import eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao;
41
import eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonNodeDao;
42
import eu.etaxonomy.cdm.persistence.dto.UuidAndTitleCache;
43

    
44
/**
45
 * @author a.mueller
46
 * @created 16.06.2009
47
 */
48
@Repository
49
@Qualifier("taxonNodeDaoHibernateImpl")
50
public class TaxonNodeDaoHibernateImpl extends AnnotatableDaoImpl<TaxonNode>
51
		implements ITaxonNodeDao {
52
	@SuppressWarnings("unused")
53
	private static final Logger logger = Logger.getLogger(TaxonNodeDaoHibernateImpl.class);
54

    
55
	@Autowired
56
	private ITaxonDao taxonDao;
57
	@Autowired
58
	private IClassificationDao classificationDao;
59

    
60
	public TaxonNodeDaoHibernateImpl() {
61
		super(TaxonNode.class);
62
	}
63
	@Override
64
	public UUID delete(TaxonNode persistentObject, boolean deleteChildren){
65
		Taxon taxon = persistentObject.getTaxon();
66
		taxon = HibernateProxyHelper.deproxy(taxon, Taxon.class);
67

    
68
		/*Session session = this.getSession();
69
		Query query = session.createQuery("from TaxonNode t where t.taxon = :taxon");
70
		query.setParameter("taxon", taxon);
71
		List result = query.list();*/
72
		if (taxon != null){
73
		    Hibernate.initialize(taxon);
74
		    Hibernate.initialize(taxon.getTaxonNodes());
75
			Set<TaxonNode> nodes = taxon.getTaxonNodes();
76
			//Hibernate.initialize(taxon.getTaxonNodes());
77
			for (TaxonNode node:nodes) {
78
			    System.out.println("Number of nodes: " + nodes.size());
79
                node = HibernateProxyHelper.deproxy(node, TaxonNode.class);
80

    
81
			    if (node.equals(persistentObject)){
82
			        if (node.hasChildNodes()){
83
			            Iterator<TaxonNode> childNodes = node.getChildNodes().iterator();
84
			            TaxonNode childNode;
85
			            List<TaxonNode> listForDeletion = new ArrayList<TaxonNode>();
86
	                    while (childNodes.hasNext()){
87
	                        childNode = childNodes.next();
88
	                        listForDeletion.add(childNode);
89
	                        childNodes.remove();
90

    
91
	                    }
92
	                    for (TaxonNode deleteNode:listForDeletion){
93
	                        delete(deleteNode, deleteChildren);
94
	                    }
95
	                }
96

    
97
			        taxon.removeTaxonNode(node, deleteChildren);
98
			        taxonDao.saveOrUpdate(taxon);
99
    				taxon = HibernateProxyHelper.deproxy(taxonDao.findByUuid(taxon.getUuid()), Taxon.class);
100
    				taxonDao.delete(taxon);
101

    
102
			    }
103
			}
104
		}
105

    
106
		UUID result = super.delete(persistentObject);
107

    
108
		return result;
109
	}
110

    
111
	@Override
112
	public List<TaxonNode> getTaxonOfAcceptedTaxaByClassification(Classification classification, Integer start, Integer end) {
113
		int classificationId = classification.getId();
114
		String limit = "";
115
		if(start !=null && end != null){
116
		    limit = "LIMIT "+start+"," +end;
117
		}
118
		//FIXME write test
119
        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;
120
        List<TaxonNode> result  = getSession().createSQLQuery(queryString).addEntity(TaxonNode.class).list();
121

    
122
       return result;
123
	}
124

    
125
    @Override
126
    public int countTaxonOfAcceptedTaxaByClassification(Classification classification){
127
        int classificationId = classification.getId();
128
        //FIXME write test
129
        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;
130
         List<BigInteger> result = getSession().createSQLQuery(queryString).list();
131
         return result.get(0).intValue ();
132
    }
133

    
134
    @Override
135
    public List<UuidAndTitleCache<TaxonNode>> listChildNodesAsUuidAndTitleCache(UuidAndTitleCache<TaxonNode> parent) {
136
        String queryString = "select tn.uuid, tn.id, tx.titleCache from TaxonNode tn INNER JOIN tn.taxon as tx where tn.parent.id = :parentId";
137
        Query query =  getSession().createQuery(queryString);
138
        query.setParameter("parentId", parent.getId());
139
        List<UuidAndTitleCache<TaxonNode>> list = new ArrayList<>();
140

    
141
        List<Object[]> result = query.list();
142

    
143
        for(Object[] object : result){
144
            list.add(new UuidAndTitleCache<TaxonNode>((UUID) object[0],(Integer) object[1], (String) object[2]));
145
        }
146
        return list;
147
    }
148

    
149
    @Override
150
    public List<UuidAndTitleCache<TaxonNode>> getUuidAndTitleCache(Integer limit, String pattern, UUID classificationUuid) {
151
        String queryString = "select tn.uuid, tn.id, tx.titleCache from TaxonNode tn "
152
        		+ "INNER JOIN tn.taxon as tx "
153
        		+ "INNER JOIN tn.classification as cls "
154
        		+ "WHERE tx.titleCache like :pattern ";
155
        if(classificationUuid!=null){
156
        	queryString += "AND cls.uuid = :classificationUuid";
157
        }
158
        Query query =  getSession().createQuery(queryString);
159

    
160
        query.setParameter("pattern", pattern.toLowerCase()+"%");
161
        query.setParameter("classificationUuid", classificationUuid);
162

    
163
        List<UuidAndTitleCache<TaxonNode>> list = new ArrayList<>();
164

    
165
        List<Object[]> result = query.list();
166

    
167
        for(Object[] object : result){
168
            list.add(new UuidAndTitleCache<TaxonNode>((UUID) object[0],(Integer) object[1], (String) object[2]));
169
        }
170
        return list;
171
    }
172

    
173
    /**
174
     * {@inheritDoc}
175
     */
176
    @Override
177
    public UuidAndTitleCache<TaxonNode> getParentUuidAndTitleCache(UuidAndTitleCache<TaxonNode> child) {
178
        String queryString = "select tn.parent.uuid, tn.parent.id, tn.parent.taxon.titleCache, tn.parent.classification.titleCache "
179
                + " from TaxonNode tn"
180
                + " LEFT OUTER JOIN tn.parent.taxon"
181
                + " where tn.id = :childId";
182
        Query query =  getSession().createQuery(queryString);
183
        query.setParameter("childId", child.getId());
184
        List<UuidAndTitleCache<TaxonNode>> list = new ArrayList<>();
185

    
186
        List<Object[]> result = query.list();
187

    
188
        for(Object[] object : result){
189
            UUID uuid = (UUID) object[0];
190
            Integer id = (Integer) object[1];
191
            String taxonTitleCache = (String) object[2];
192
            String classificationTitleCache = (String) object[3];
193
            if(taxonTitleCache!=null){
194
                list.add(new UuidAndTitleCache<TaxonNode>(uuid,id, taxonTitleCache));
195
            }
196
            else{
197
                list.add(new UuidAndTitleCache<TaxonNode>(uuid,id, classificationTitleCache));
198
            }
199
        }
200
        if(list.size()==1){
201
            return list.iterator().next();
202
        }
203
        return null;
204
    }
205

    
206
    @Override
207
    public List<TaxonNode> listChildrenOf(TaxonNode node, Integer pageSize, Integer pageIndex, List<String> propertyPaths, boolean recursive){
208
    	if (recursive == true){
209
    		Criteria crit = getSession().createCriteria(TaxonNode.class);
210
    		crit.add( Restrictions.like("treeIndex", node.treeIndex()+ "%") );
211
    		if(pageSize != null) {
212
                crit.setMaxResults(pageSize);
213
                if(pageIndex != null) {
214
                    crit.setFirstResult(pageIndex * pageSize);
215
                } else {
216
                    crit.setFirstResult(0);
217
                }
218
            }
219
    		List<TaxonNode> results = crit.list();
220
    		results.remove(node);
221
    		defaultBeanInitializer.initializeAll(results, propertyPaths);
222
    		return results;
223
    	}else{
224
    		return classificationDao.listChildrenOf(node.getTaxon(), node.getClassification(), pageSize, pageIndex, propertyPaths);
225
    	}
226

    
227
    }
228

    
229
    @Override
230
	public Long countChildrenOf(TaxonNode node, Classification classification,
231
			boolean recursive) {
232

    
233
		if (recursive == true){
234
			Criteria crit = getSession().createCriteria(TaxonNode.class);
235
    		crit.add( Restrictions.like("treeIndex", node.treeIndex()+ "%") );
236
    		crit.setProjection(Projections.rowCount());
237
    		return ((Integer)crit.uniqueResult().hashCode()).longValue();
238
		}else{
239
			return classificationDao.countChildrenOf(node.getTaxon(), classification);
240
		}
241
	}
242
    /**
243
     * {@inheritDoc}
244
     */
245
    @Override
246
    public List<TaxonNodeAgentRelation> listTaxonNodeAgentRelations(UUID taxonUuid, UUID classificationUuid,
247
            UUID agentUuid, UUID rankUuid, UUID relTypeUuid, Integer start, Integer limit, List<String> propertyPaths) {
248

    
249

    
250
        StringBuilder hql = prepareListTaxonNodeAgentRelations(taxonUuid, classificationUuid, agentUuid, rankUuid, relTypeUuid, false);
251

    
252
        Query query =  getSession().createQuery(hql.toString());
253

    
254
        if(limit != null) {
255
            query.setMaxResults(limit);
256
            if(start != null) {
257
                query.setFirstResult(start);
258
            }
259
        }
260

    
261
        setParamsForListTaxonNodeAgentRelations(taxonUuid, classificationUuid, agentUuid, rankUuid, relTypeUuid, query);
262

    
263
        List<TaxonNodeAgentRelation> records = query.list();
264

    
265
        if(propertyPaths != null) {
266
            defaultBeanInitializer.initializeAll(records, propertyPaths);
267
        }
268
        return records;
269
    }
270

    
271
    /**
272
     * {@inheritDoc}
273
     */
274
    @Override
275
    public long countTaxonNodeAgentRelations(UUID taxonUuid, UUID classificationUuid, UUID agentUuid, UUID rankUuid, UUID relTypeUuid) {
276

    
277
        StringBuilder hql = prepareListTaxonNodeAgentRelations(taxonUuid, classificationUuid, agentUuid, rankUuid, relTypeUuid, true);
278
        Query query =  getSession().createQuery(hql.toString());
279

    
280
        setParamsForListTaxonNodeAgentRelations(taxonUuid, classificationUuid, agentUuid, rankUuid, relTypeUuid, query);
281

    
282
        Long count = Long.parseLong(query.uniqueResult().toString());
283

    
284
        return count;
285
    }
286
    /**
287
     * @param taxonUuid
288
     * @param classificationUuid
289
     * @param agentUuid
290
     * @param relTypeUuid TODO
291
     * @param doCount TODO
292
     * @param rankId
293
     *     limit to taxa having this rank, only applies if <code>taxonUuid = null</code>
294
     * @return
295
     */
296
    private StringBuilder prepareListTaxonNodeAgentRelations(UUID taxonUuid, UUID classificationUuid, UUID agentUuid, UUID rankUuid, UUID relTypeUuid, boolean doCount) {
297

    
298
        StringBuilder hql = new StringBuilder();
299

    
300
        String join_fetch_mode = doCount ? "join" : "join fetch";
301

    
302
        if(doCount) {
303
            hql.append("select count(tnar)");
304
        } else {
305
            hql.append("select tnar");
306
        }
307

    
308
        hql.append(" from TaxonNodeAgentRelation as tnar ");
309
        if(taxonUuid != null) {
310
            // taxonUuid is search filter, do not fetch it
311
            hql.append(" join tnar.taxonNode as tn join tn.taxon as t ");
312
        } else {
313
            hql.append(join_fetch_mode).append(" tnar.taxonNode as tn ").append(join_fetch_mode).append(" tn.taxon as t ");
314
            if(rankUuid != null) {
315
                hql.append(" join t.name as n ");
316
            }
317
        }
318
        hql.append(" join tn.classification as c ");
319
        if(agentUuid != null) {
320
            // agentUuid is search filter, do not fetch it
321
//            hql.append(" join tnar.agent as a ");
322
            hql.append(join_fetch_mode).append(" tnar.agent as a ");
323
        } else {
324
            hql.append(join_fetch_mode).append(" tnar.agent as a ");
325
        }
326

    
327
        hql.append(" where 1 = 1 ");
328

    
329
        if(relTypeUuid != null) {
330
            hql.append(" and tnar.type.uuid = :relTypeUuid ");
331
        }
332

    
333
        if(taxonUuid != null) {
334
            hql.append(" and t.uuid = :taxonUuid ");
335
        } else {
336
            if(rankUuid != null) {
337
                hql.append(" and n.rank.uuid = :rankUuid ");
338
            }
339
        }
340
        if(classificationUuid != null) {
341
            hql.append(" and c.uuid = :classificationUuid ");
342
        }
343
        if(agentUuid != null) {
344
            hql.append(" and a.uuid = :agentUuid ");
345
        }
346

    
347
        hql.append(" order by a.titleCache");
348
        return hql;
349
    }
350
    /**
351
     * @param taxonUuid
352
     * @param classificationUuid
353
     * @param agentUuid
354
     * @param relTypeUuid TODO
355
     * @param query
356
     * @param rankId TODO
357
     */
358
    private void setParamsForListTaxonNodeAgentRelations(UUID taxonUuid, UUID classificationUuid, UUID agentUuid,
359
            UUID rankUuid, UUID relTypeUuid, Query query) {
360

    
361
        if(taxonUuid != null) {
362
            query.setParameter("taxonUuid", taxonUuid);
363
        } else {
364
            if(rankUuid != null) {
365
                query.setParameter("rankUuid", rankUuid);
366
            }
367
        }
368
        if(classificationUuid != null) {
369
            query.setParameter("classificationUuid", classificationUuid);
370
        }
371
        if(agentUuid != null) {
372
            query.setParameter("agentUuid", agentUuid);
373
        }
374
        if(relTypeUuid != null) {
375
            query.setParameter("relTypeUuid", relTypeUuid);
376
        }
377
    }
378

    
379
    @Override
380
    public Map<TreeIndex, Integer> rankOrderIndexForTreeIndex(List<TreeIndex> treeIndexes,
381
            Integer minRankOrderIndex,
382
            Integer maxRankOrderIndex) {
383

    
384
        Map<TreeIndex, Integer> result = new HashMap<>();
385
        if (treeIndexes == null || treeIndexes.isEmpty()){
386
            return result;
387
        }
388

    
389
        String hql = " SELECT tn.treeIndex, r.orderIndex "
390
                + " FROM TaxonNode tn JOIN tn.taxon t JOIN t.name n JOIN n.rank r "
391
                + " WHERE tn.treeIndex IN (:treeIndexes) ";
392
        if (minRankOrderIndex != null){
393
            hql += " AND r.orderIndex <= :minOrderIndex";
394
        }
395
        if (maxRankOrderIndex != null){
396
            hql += " AND r.orderIndex >= :maxOrderIndex";
397
        }
398

    
399
        Query query =  getSession().createQuery(hql);
400
        query.setParameterList("treeIndexes", TreeIndex.toString(treeIndexes));
401
        if (minRankOrderIndex != null){
402
            query.setParameter("minOrderIndex", minRankOrderIndex);
403
        }
404
        if (maxRankOrderIndex != null){
405
            query.setParameter("maxOrderIndex", maxRankOrderIndex);
406
        }
407

    
408
        @SuppressWarnings("unchecked")
409
        List<Object[]> list = query.list();
410
        for (Object[] o : list){
411
            result.put(TreeIndex.NewInstance((String)o[0]), (Integer)o[1]);
412
        }
413
        return result;
414
    }
415

    
416
    @Override
417
    public Map<TreeIndex, UuidAndTitleCache<?>> taxonUuidsForTreeIndexes(Collection<TreeIndex> treeIndexes) {
418
        Map<TreeIndex, UuidAndTitleCache<?>> result = new HashMap<>();
419
        if (treeIndexes == null || treeIndexes.isEmpty()){
420
            return result;
421
        }
422

    
423
        String hql = " SELECT tn.treeIndex, t.uuid, tnb.titleCache "
424
                + " FROM TaxonNode tn JOIN tn.taxon t Join t.name tnb "
425
                + " WHERE tn.treeIndex IN (:treeIndexes) ";
426
        Query query =  getSession().createQuery(hql);
427
        query.setParameterList("treeIndexes", TreeIndex.toString(treeIndexes));
428

    
429
        @SuppressWarnings("unchecked")
430
        List<Object[]> list = query.list();
431
        for (Object[] o : list){
432
            result.put(TreeIndex.NewInstance((String)o[0]), new UuidAndTitleCache<>((UUID)o[1], null, (String)o[2]));
433
        }
434
        return result;
435
    }
436

    
437

    
438

    
439
}
(4-4/4)