Project

General

Profile

Download (8.21 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2018 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.taxonGraph;
10

    
11
import java.util.List;
12
import java.util.UUID;
13

    
14
import org.apache.logging.log4j.LogManager;import org.apache.logging.log4j.Logger;
15
import org.hibernate.Session;
16
import org.hibernate.query.Query;
17
import org.springframework.beans.factory.InitializingBean;
18
import org.springframework.beans.factory.annotation.Autowired;
19
import org.springframework.stereotype.Repository;
20
import org.springframework.transaction.annotation.Transactional;
21

    
22
import eu.etaxonomy.cdm.model.metadata.CdmPreference;
23
import eu.etaxonomy.cdm.model.metadata.CdmPreference.PrefKey;
24
import eu.etaxonomy.cdm.model.metadata.PreferencePredicate;
25
import eu.etaxonomy.cdm.model.metadata.PreferenceSubject;
26
import eu.etaxonomy.cdm.model.name.RegistrationStatus;
27
import eu.etaxonomy.cdm.model.name.TaxonName;
28
import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;
29
import eu.etaxonomy.cdm.persistence.dao.common.IPreferenceDao;
30
import eu.etaxonomy.cdm.persistence.dao.hibernate.common.CdmPreferenceCache;
31
import eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao;
32
import eu.etaxonomy.cdm.persistence.dao.taxonGraph.ITaxonGraphDao;
33
import eu.etaxonomy.cdm.persistence.dao.taxonGraph.TaxonGraphException;
34
import eu.etaxonomy.cdm.persistence.dto.TaxonGraphEdgeDTO;
35
import eu.etaxonomy.cdm.persistence.hibernate.TaxonGraphHibernateListener;
36

    
37
/**
38
 * Implementation of the abstract {@link AbstractHibernateTaxonGraphProcessor}
39
 * business logic to provide a <b>purely read only access</b> to graphs
40
 * consisting of {@link eu.etaxonomy.cdm.model.taxon.Taxon Taxa} and
41
 * {@link eu.etaxonomy.cdm.model.taxon.TaxonRelationship TaxonRelationships}.
42
 * These graphs allow for managing classification fragments in a graph
43
 * structure. All <code>write operation</code>, that is all modification of the
44
 * graph is done automatically solely by
45
 * {@link eu.etaxonomy.cdm.api.service.taxonGraph.TaxonGraphBeforeTransactionCompleteProcess}.
46
 * <p>
47
 * The conceptual idea for the resulting graph is described in <a href=
48
 * "https://dev.e-taxonomy.eu/redmine/issues/6173#6-N1T-Higher-taxon-graphs-with-includedIn-relations-taxon-relationships">#6173
49
 * 6) [N1T] Higher taxon-graphs with includedIn relations taxon
50
 * relationships}</a>. The
51
 * <code>TaxonGraphBeforeTransactionCompleteProcess</code> is instantiated and
52
 * used in the {@link TaxonGraphHibernateListener}.
53
 *
54
 * @author a.kohlbecker
55
 * @since Sep 26, 2018
56
 */
57
@Repository("taxonGraphDao")
58
@Transactional(readOnly = true) //NOTE by AM (2022-5): not sure if this is really needed, tests run without transactional, usually transaction borders are not defined in persistence, but this class is used a bit differently so I am not sure; keep it as it is for now to not brake working code
59
public class TaxonGraphDaoHibernateImpl
60
        extends AbstractHibernateTaxonGraphProcessor
61
        implements ITaxonGraphDao, InitializingBean {
62

    
63
    @SuppressWarnings("unused")
64
    private static final Logger logger = LogManager.getLogger(TaxonGraphDaoHibernateImpl.class);
65

    
66
    public TaxonGraphDaoHibernateImpl(IPreferenceDao preferenceDao) {
67
        super(preferenceDao);
68
    }
69

    
70
    private TaxonRelationshipType relType = TaxonRelationshipType.TAXONOMICALLY_INCLUDED_IN();
71

    
72
    public static final PrefKey CDM_PREF_KEY_SEC_REF_UUID = CdmPreference.NewKey(PreferenceSubject.NewDatabaseInstance(), PreferencePredicate.TaxonGraphSecRefUuid);
73

    
74
    @Autowired
75
    private ITaxonDao taxonDao;
76

    
77
    @Autowired
78
    private IPreferenceDao preferenceDao;
79

    
80
    @Override
81
    protected TaxonRelationshipType relType() {
82
        if(relType == null){
83
            relType = TaxonRelationshipType.TAXONOMICALLY_INCLUDED_IN();
84
        }
85
        return relType;
86
    }
87

    
88
    @Override
89
    public List<TaxonGraphEdgeDTO> listTaxonGraphEdgeDTOs(UUID fromTaxonUuid, UUID toTaxonUuid, TaxonRelationshipType type,
90
            boolean includeUnpublished, Integer pageSize, Integer pageIndex) {
91

    
92
        Query<TaxonGraphEdgeDTO> query = prepareTaxonGraphEdgeDTOs(
93
                fromTaxonUuid, toTaxonUuid, type, includeUnpublished, false, TaxonGraphEdgeDTO.class);
94

    
95

    
96
        if(pageSize != null) {
97
            query.setMaxResults(pageSize);
98
            if(pageIndex != null) {
99
                query.setFirstResult(pageIndex * pageSize);
100
            } else {
101
                query.setFirstResult(0);
102
            }
103
        }
104

    
105
        List<TaxonGraphEdgeDTO> result = query.list();
106
        return result;
107
    }
108

    
109
    @Override
110
    public long countTaxonGraphEdgeDTOs(UUID fromTaxonUuid, UUID toTaxonUuid, TaxonRelationshipType type,
111
            boolean includeUnpublished) {
112

    
113
        Query<Long> query = prepareTaxonGraphEdgeDTOs(fromTaxonUuid, toTaxonUuid, type, includeUnpublished, true, Long.class);
114
        Long count = query.uniqueResult();
115
        return count;
116
    }
117

    
118
    protected <R extends Object> Query<R> prepareTaxonGraphEdgeDTOs(UUID fromTaxonUuid, UUID toTaxonUuid, TaxonRelationshipType type,
119
            boolean includeUnpublished, boolean doCount, Class<R> returnedClass) {
120

    
121
        Session session = getSession();
122
        String hql = "";
123
        if(doCount){
124
            hql = "COUNT(tr.id)";
125
        } else {
126
            hql += "SELECT new eu.etaxonomy.cdm.persistence.dto.TaxonGraphEdgeDTO("
127
                    + " fromT.uuid, fromN.titleCache, fromN_R.idInVocabulary, fromN_R.orderIndex, "
128
                    + " toT.uuid, toN.titleCache, toN_R.idInVocabulary, toN_R.orderIndex, "
129
                    + " c.uuid, c.titleCache"
130
                    + ")";
131
        }
132
        hql += " FROM TaxonRelationship as tr "
133
                + " JOIN tr.source as s"
134
                + " JOIN s.citation as c"
135
                + " JOIN tr.relatedFrom as fromT"
136
                + " JOIN tr.relatedTo as toT"
137
                + " JOIN fromT.name as fromN"
138
                + " JOIN toT.name as toN"
139
                + " JOIN fromN.rank as fromN_R"
140
                + " JOIN toN.rank as toN_R"
141
                + " LEFT OUTER JOIN toN.registrations as toN_Reg"
142
                + " LEFT OUTER JOIN fromN.registrations as fromN_Reg"
143
                + " WHERE tr.type = :reltype"
144
                + " AND (fromN_Reg IS NULL OR fromN_Reg.status = :regStatus)"
145
                + " AND (toN_Reg IS NULL OR toN_Reg.status = :regStatus) "
146
                ;
147

    
148
        if(fromTaxonUuid != null){
149
            hql += " AND fromT.uuid = :fromTaxonUuid";
150
            if(!includeUnpublished){
151
                hql += " AND fromT.publish is true";
152
            }
153
        }
154
        if(toTaxonUuid != null){
155
            hql += " AND toT.uuid = :toTaxonUuid";
156
            if(!includeUnpublished){
157
                hql += " AND toT.publish is true";
158
            }
159
        }
160

    
161
        Query<R> query = session.createQuery(hql, returnedClass);
162
        query.setParameter("reltype", type);
163
        query.setParameter("regStatus", RegistrationStatus.PUBLISHED);
164
        if(fromTaxonUuid != null){
165
            query.setParameter("fromTaxonUuid", fromTaxonUuid);
166
        }
167
        if(toTaxonUuid != null){
168
            query.setParameter("toTaxonUuid", toTaxonUuid);
169
        }
170
        return query;
171
    }
172

    
173
    @Override
174
    public List<TaxonGraphEdgeDTO> edges(TaxonName fromName, TaxonName toName, boolean includeUnpublished) throws TaxonGraphException{
175
        UUID fromTaxonUUID = null;
176
        UUID toTaxonUUID = null;
177
        if(fromName != null){
178
            fromTaxonUUID = assureSingleTaxon(fromName).getUuid();
179
        }
180
        if(toName != null){
181
            toTaxonUUID = assureSingleTaxon(toName).getUuid();
182
        }
183
        return listTaxonGraphEdgeDTOs(fromTaxonUUID, toTaxonUUID, relType(), includeUnpublished, null, null);
184
    }
185

    
186
    @Override
187
    public List<TaxonGraphEdgeDTO> edges(UUID fromtaxonUuid, UUID toTaxonUuid, boolean includeUnpublished) throws TaxonGraphException{
188
        return listTaxonGraphEdgeDTOs(fromtaxonUuid, toTaxonUuid, relType(), includeUnpublished, null, null);
189
    }
190

    
191

    
192
    @Override
193
    public void afterPropertiesSet() throws Exception {
194
        CdmPreferenceCache.instance(preferenceDao);
195
    }
196

    
197
    @Override
198
    public Session getSession() {
199
        return taxonDao.getSession();
200
    }
201

    
202
}
(2-2/2)