Project

General

Profile

Download (8.55 KB) Statistics
| Branch: | Tag: | Revision:
1
// $Id$
2
/**
3
* Copyright (C) 2007 EDIT
4
* European Distributed Institute of Taxonomy
5
* http://www.e-taxonomy.eu
6
*
7
* The contents of this file are subject to the Mozilla Public License Version 1.1
8
* See LICENSE.TXT at the top of this package for the full license terms.
9
*/
10

    
11
package eu.etaxonomy.cdm.persistence.dao.hibernate.taxon;
12

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

    
17
import org.apache.log4j.Logger;
18
import org.hibernate.Query;
19
import org.springframework.beans.factory.annotation.Autowired;
20
import org.springframework.beans.factory.annotation.Qualifier;
21
import org.springframework.stereotype.Repository;
22

    
23
import eu.etaxonomy.cdm.model.name.Rank;
24
import eu.etaxonomy.cdm.model.taxon.Classification;
25
import eu.etaxonomy.cdm.model.taxon.Taxon;
26
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
27
import eu.etaxonomy.cdm.persistence.dao.hibernate.common.IdentifiableDaoBase;
28
import eu.etaxonomy.cdm.persistence.dao.taxon.IClassificationDao;
29
import eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonNodeDao;
30

    
31
/**
32
 * @author a.mueller
33
 * @created 16.06.2009
34
 * @version 1.0
35
 */
36
@Repository
37
@Qualifier("classificationDaoHibernateImpl")
38
public class ClassificationDaoHibernateImpl extends IdentifiableDaoBase<Classification>
39
        implements IClassificationDao {
40
    @SuppressWarnings("unused")
41
    private static final Logger logger = Logger.getLogger(ClassificationDaoHibernateImpl.class);
42

    
43
    @Autowired
44
    private ITaxonNodeDao taxonNodeDao;
45

    
46
    public ClassificationDaoHibernateImpl() {
47
        super(Classification.class);
48
        indexedClasses = new Class[1];
49
        indexedClasses[0] = Classification.class;
50
    }
51

    
52
    @Override
53
    @SuppressWarnings("unchecked")
54
    public List<TaxonNode> listRankSpecificRootNodes(Classification classification, Rank rank,
55
            Integer limit, Integer start, List<String> propertyPaths, int queryIndex){
56

    
57
        List<TaxonNode> results = new ArrayList<TaxonNode>();
58
        Query[] queries = prepareRankSpecificRootNodes(classification, rank, false);
59

    
60
        // since this method is using two queries sequentially the handling of limit and start
61
        // is a bit more complex
62
        // the prepareRankSpecificRootNodes returns 1 or 2 queries
63

    
64
        Query q = queries[queryIndex];
65
        if(limit != null) {
66
            q.setMaxResults(limit);
67
            if(start != null) {
68
                q.setFirstResult(start);
69
            }
70
        }
71
//        long start_t = System.currentTimeMillis();
72
        results = q.list();
73
//        System.err.println("dao.listRankSpecificRootNodes() - query[" + queryIndex + "].list() " + (System.currentTimeMillis() - start_t));
74
//        start_t = System.currentTimeMillis();
75
        defaultBeanInitializer.initializeAll(results, propertyPaths);
76
//        System.err.println("dao.listRankSpecificRootNodes() - defaultBeanInitializer.initializeAll() " + (System.currentTimeMillis() - start_t));
77

    
78
        return results;
79

    
80
    }
81

    
82
    @Override
83
    public long[] countRankSpecificRootNodes(Classification classification, Rank rank) {
84

    
85
        long[] result = new long[(rank == null ? 1 : 2)];
86
        Query[] queries = prepareRankSpecificRootNodes(classification, rank, true);
87
        int i = 0;
88
        for(Query q : queries) {
89
            result[i++] = (Long)q.uniqueResult();
90
        }
91
        return result;
92
    }
93

    
94
    /**
95
     * See <a href="http://dev.e-taxonomy.eu/trac/wiki/CdmClassificationRankSpecificRootnodes">
96
     * http://dev.e-taxonomy.eu/trac/wiki/CdmClassificationRankSpecificRootnodes</a>
97
     *
98
     * @param classification
99
     * @param rank
100
     * @return
101
     *      one or two Queries as array, depending on the <code>rank</code> parameter:
102
     *      <code>rank == null</code>: array with one item, <code>rank != null</code>: array with two items.
103
     */
104
    private Query[] prepareRankSpecificRootNodes(Classification classification, Rank rank, boolean doCount) {
105
        Query query1;
106
        Query query2 = null;
107

    
108
        String whereClassification = "";
109
        if (classification != null){
110
            whereClassification = " AND tn.classification = :classification ";
111
        }
112

    
113
        String selectWhat = doCount ? "count(distinct tn)" : "distinct tn";
114

    
115
        String joinFetch = doCount ? "" : " JOIN FETCH tn.taxon t JOIN FETCH t.name n LEFT JOIN FETCH n.rank LEFT JOIN FETCH t.sec ";
116

    
117
        if(rank == null){
118
            String hql = "SELECT " + selectWhat + " FROM TaxonNode tn" +
119
                    joinFetch +
120
                    " WHERE tn.parent.parent = null " +
121
                    whereClassification;
122
            query1 = getSession().createQuery(hql);
123
        } else {
124
            // this is for the cases
125
            //   - exact match of the ranks
126
            //   - rank of root node is lower but is has no parents
127
            String hql1 = "SELECT " + selectWhat + " FROM TaxonNode tn " +
128
                    joinFetch +
129
                    " WHERE " +
130
                    " (tn.taxon.name.rank = :rank" +
131
                    "   OR (tn.taxon.name.rank.orderIndex > :rankOrderIndex AND tn.parent.parent = null)" +
132
                    " )"
133
                    + whereClassification ;
134

    
135
            // this is for the case
136
            //   - rank of root node is lower and it has a parent with higher rank
137
            String hql2 = "SELECT " + selectWhat + " FROM TaxonNode tn JOIN tn.parent as parent" +
138
                    joinFetch +
139
                    " WHERE " +
140
                    " (tn.taxon.name.rank.orderIndex > :rankOrderIndex AND parent.taxon.name.rank.orderIndex < :rankOrderIndex )"
141
                    + whereClassification ;
142
            query1 = getSession().createQuery(hql1);
143
            query2 = getSession().createQuery(hql2);
144
            query1.setParameter("rank", rank);
145
            query1.setParameter("rankOrderIndex", rank.getOrderIndex());
146
            query2.setParameter("rankOrderIndex", rank.getOrderIndex());
147
        }
148

    
149
        if (classification != null){
150
            query1.setParameter("classification", classification);
151
            if(query2 != null) {
152
                query2.setParameter("classification", classification);
153
            }
154
        }
155
        if(query2 != null) {
156
            return new Query[]{query1, query2};
157
        } else {
158
            return new Query[]{query1};
159
        }
160
    }
161

    
162
    @Override
163
    public List<TaxonNode> listChildrenOf(Taxon taxon, Classification classification, Integer pageSize, Integer pageIndex, List<String> propertyPaths){
164
    	 Query query = prepareListChildrenOf(taxon, classification, false);
165

    
166
         setPagingParameter(query, pageSize, pageIndex);
167

    
168
         @SuppressWarnings("unchecked")
169
         List<TaxonNode> result = query.list();
170
         //check if array is "empty" (not containing null objects)
171
         if(!result.isEmpty() && result.iterator().next()==null){
172
         	return java.util.Collections.emptyList();
173
         }
174
         defaultBeanInitializer.initializeAll(result, propertyPaths);
175
         return result;
176
    }
177

    
178

    
179

    
180
    @Override
181
    public Long countChildrenOf(Taxon taxon, Classification classification){
182
        Query query = prepareListChildrenOf(taxon, classification, true);
183
        Long count = (Long) query.uniqueResult();
184
        return count;
185
    }
186

    
187
    private Query prepareListChildrenOf(Taxon taxon, Classification classification, boolean doCount){
188

    
189
    	String selectWhat = doCount ? "count(cn)" : "cn";
190

    
191
         String hql = "select " + selectWhat + " from TaxonNode as tn left join tn.classification as c left join tn.taxon as t  left join tn.childNodes as cn "
192
                 + "where t = :taxon and c = :classification";
193
         Query query = getSession().createQuery(hql);
194
         query.setParameter("taxon", taxon);
195
         query.setParameter("classification", classification);
196
         return query;
197
    }
198

    
199

    
200
    @Override
201
    public UUID delete(Classification persistentObject){
202
        //delete all childnodes, then delete the tree
203

    
204
        List<TaxonNode> nodes = persistentObject.getChildNodes();
205
        List<TaxonNode> nodesTmp = new ArrayList<TaxonNode>(nodes);
206

    
207
//        Iterator<TaxonNode> nodesIterator = nodes.iterator();
208
        for(TaxonNode node : nodesTmp){
209
            persistentObject.deleteChildNode(node, true);
210
            taxonNodeDao.delete(node, true);
211
        }
212

    
213
        TaxonNode rootNode = persistentObject.getRootNode();
214
        persistentObject.removeRootNode();
215
        taxonNodeDao.delete(rootNode);
216
        super.delete(persistentObject);
217

    
218
        return persistentObject.getUuid();
219
    }
220

    
221

    
222

    
223

    
224
}
(1-1/4)