b03922e4aa27accdaa53104bab982b5c85af9095
[cdmlib.git] / cdmlib-persistence / src / main / java / eu / etaxonomy / cdm / persistence / dao / hibernate / reference / ReferenceDaoHibernateImpl.java
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 package eu.etaxonomy.cdm.persistence.dao.hibernate.reference;
10
11 import java.util.ArrayList;
12 import java.util.HashSet;
13 import java.util.List;
14 import java.util.Set;
15 import java.util.UUID;
16
17 import org.apache.log4j.Logger;
18 import org.hibernate.Criteria;
19 import org.hibernate.Hibernate;
20 import org.hibernate.Query;
21 import org.hibernate.Session;
22 import org.hibernate.criterion.Restrictions;
23 import org.hibernate.search.FullTextSession;
24 import org.hibernate.search.Search;
25 import org.springframework.beans.factory.annotation.Qualifier;
26 import org.springframework.stereotype.Repository;
27
28 import eu.etaxonomy.cdm.model.common.DefinedTermBase;
29 import eu.etaxonomy.cdm.model.reference.IArticle;
30 import eu.etaxonomy.cdm.model.reference.IBookSection;
31 import eu.etaxonomy.cdm.model.reference.IInProceedings;
32 import eu.etaxonomy.cdm.model.reference.IPrintedUnitBase;
33 import eu.etaxonomy.cdm.model.reference.IReport;
34 import eu.etaxonomy.cdm.model.reference.IThesis;
35 import eu.etaxonomy.cdm.model.reference.Reference;
36 import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
37 import eu.etaxonomy.cdm.model.reference.ReferenceType;
38 import eu.etaxonomy.cdm.model.taxon.TaxonBase;
39 import eu.etaxonomy.cdm.persistence.dao.hibernate.common.IdentifiableDaoBase;
40 import eu.etaxonomy.cdm.persistence.dao.reference.IReferenceDao;
41 import eu.etaxonomy.cdm.persistence.dto.UuidAndTitleCache;
42 import eu.etaxonomy.cdm.persistence.query.MatchMode;
43 import eu.etaxonomy.cdm.persistence.query.OrderHint;
44 import eu.etaxonomy.cdm.strategy.cache.reference.DefaultReferenceCacheStrategy;
45
46 /**
47 * @author a.mueller
48 *
49 */
50 @Repository
51 @Qualifier("referenceDaoHibernateImpl")
52 public class ReferenceDaoHibernateImpl extends IdentifiableDaoBase<Reference> implements IReferenceDao {
53 private static final Logger logger = Logger.getLogger(ReferenceDaoHibernateImpl.class);
54
55 public ReferenceDaoHibernateImpl() {
56 super(Reference.class);
57 }
58
59 @Override
60 public void rebuildIndex() {
61 FullTextSession fullTextSession = Search.getFullTextSession(getSession());
62
63 for(Reference reference : list(null,null)) { // re-index all agents
64 Hibernate.initialize(reference.getAuthorship());
65
66 if(reference.getType().equals(ReferenceType.Article)) {
67 Hibernate.initialize(((IArticle)reference).getInJournal());
68 } else if(reference.getType().equals(ReferenceType.BookSection)) {
69 Hibernate.initialize(((IBookSection)reference).getInBook());
70 } else if(reference.getType().equals(ReferenceType.InProceedings)) {
71 Hibernate.initialize(((IInProceedings)reference).getInProceedings());
72 }else if(reference.getType().equals(ReferenceType.Thesis)) {
73 Hibernate.initialize(((IThesis)reference).getSchool());
74 } else if(reference.getType().equals(ReferenceType.Report)) {
75 Hibernate.initialize(((IReport)reference).getInstitution());
76 } else if(reference.getType().isPrintedUnit()) {
77 Hibernate.initialize(((IPrintedUnitBase)reference).getInSeries());
78 }
79 fullTextSession.index(reference);
80 }
81 fullTextSession.flushToIndexes();
82 }
83
84 @Override
85 public List<UuidAndTitleCache<Reference>> getUuidAndTitle(){
86 List<UuidAndTitleCache<Reference>> list = new ArrayList<UuidAndTitleCache<Reference>>();
87 Session session = getSession();
88
89 Query query = session.createQuery("select uuid, id, titleCache from " + type.getSimpleName());
90
91 @SuppressWarnings("unchecked")
92 List<Object[]> result = query.list();
93
94 for(Object[] object : result){
95 list.add(new UuidAndTitleCache<Reference>(type, (UUID) object[0], (Integer)object[1], (String) object[2]));
96 }
97
98 return list;
99 }
100
101 @Override
102 public List<UuidAndTitleCache<Reference>> getUuidAndTitle(Set<UUID> uuids){
103 List<UuidAndTitleCache<Reference>> list = new ArrayList<UuidAndTitleCache<Reference>>();
104
105 Criteria criteria = null;
106
107 criteria = getSession().createCriteria(Reference.class);
108 criteria.add(Restrictions.in("uuid", uuids ) );
109
110 @SuppressWarnings("unchecked")
111 List<Reference> result = criteria.list();
112
113 for(Reference object : result){
114 list.add(new UuidAndTitleCache<Reference>(type, object.getUuid(), object.getId(), object.getTitleCache()));
115 }
116
117 return list;
118 }
119
120 @Override
121 public List<UuidAndTitleCache<Reference>> getUuidAndTitleCache(Integer limit, String pattern, ReferenceType refType) {
122 List<UuidAndTitleCache<Reference>> list = new ArrayList<>();
123 Session session = getSession();
124
125 String queryString = "SELECT " +"r.uuid, r.id, r.titleCache, ab.titleCache "
126 + " FROM " + type.getSimpleName() + " AS r LEFT OUTER JOIN r.authorship AS ab ";
127
128 if (refType != null || pattern != null){
129 queryString += " WHERE (1=1) ";
130 if (refType != null ){
131 queryString += " AND (r.type = :type OR r.type = :genericType) " ;
132 }
133 if (pattern != null){
134 queryString += " AND (r.titleCache LIKE :pattern) ";
135 }
136 }
137
138 Query query;
139 //if (pattern != null){
140 query = session.createQuery(queryString);
141 // }else{
142 // query = session.createQuery("SELECT " +"r.uuid, r.id, r.titleCache, ab.titleCache FROM " + type.getSimpleName() + " AS r LEFT OUTER JOIN r.authorship AS ab ");//"select uuid, titleCache from " + type.getSimpleName());
143 // }
144
145 if (limit != null){
146 query.setMaxResults(limit);
147 }
148 if (pattern != null){
149 pattern = pattern.replace("*", "%");
150 pattern = pattern.replace("?", "_");
151 pattern = pattern + "%";
152 query.setParameter("pattern", pattern);
153 }
154 if (refType != null){
155 query.setParameter("type", refType);
156 query.setParameter("genericType", ReferenceType.Generic);
157 }
158 @SuppressWarnings("unchecked")
159 List<Object[]> result = query.list();
160
161 for(Object[] object : result){
162 String referenceTitle = (String) object[2];
163
164 if(referenceTitle != null){
165 String teamTitle = (String) object[3];
166 referenceTitle = DefaultReferenceCacheStrategy.putAuthorToEndOfString(referenceTitle, teamTitle);
167
168 list.add(new UuidAndTitleCache<Reference>(Reference.class, (UUID) object[0],(Integer)object[1], referenceTitle));
169 }else{
170 logger.warn("Title cache of reference is null. This should not happen. Please fix data. UUID: " + object[0]);
171 }
172 }
173
174 return list;
175 }
176
177 @Override
178 public List<Object[]> findByIdentifierAbbrev(String identifier, DefinedTermBase identifierType,
179 MatchMode matchmode,Integer limit){
180 checkNotInPriorView("IdentifiableDaoBase.findByIdentifier(T clazz, String identifier, DefinedTerm identifierType, MatchMode matchmode, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths)");
181
182
183 String queryString = "SELECT ids.type, ids.identifier, %s FROM %s as c " +
184 " INNER JOIN c.identifiers as ids " +
185 " WHERE (1=1) ";
186 queryString = String.format(queryString, "c.uuid, c.titleCache, c.abbrevTitleCache" , "Reference");
187
188 //Matchmode and identifier
189 if (identifier != null){
190 if (matchmode == null || matchmode == MatchMode.EXACT){
191 queryString += " AND ids.identifier = '" + identifier + "'";
192 }else {
193 queryString += " AND ids.identifier LIKE '" + matchmode.queryStringFrom(identifier) + "'";
194 }
195 }
196 if (identifierType != null){
197 queryString += " AND ids.type = :type";
198 }
199 //order
200 queryString +=" ORDER BY ids.type.uuid, ids.identifier, c.uuid ";
201
202 Query query = getSession().createQuery(queryString);
203
204 //parameters
205 if (identifierType != null){
206 query.setEntity("type", identifierType);
207 }
208
209
210
211 List<Object[]> results = query.list();
212 //initialize
213
214 return results;
215 }
216
217 @Override
218 public List<Reference> getAllReferencesForPublishing(){
219 @SuppressWarnings("unchecked")
220 List<Reference> references = getSession().createQuery("SELECT r FROM Reference r "+
221 "WHERE r.id IN "+
222 "(SELECT m.markedObj.id FROM Marker m WHERE "+
223 "m.markerType.id = "+
224 "(SELECT dtb.id FROM DefinedTermBase dtb, Representation r WHERE r MEMBER OF dtb.representations AND r.text='publish'))").list();
225 return references;
226 }
227
228 @Override
229 public List<Reference> getAllNotNomenclaturalReferencesForPublishing(){
230
231 @SuppressWarnings("unchecked")
232 List<Reference> references = getSession().createQuery("select t.nomenclaturalReference from TaxonName t").list();
233 String queryString = "from Reference b where b not in (:referenceList) and b in (:publish)" ;
234 Query referenceQuery = getSession().createQuery(queryString).setParameterList("referenceList", references);
235 referenceQuery.setParameterList("publish", getAllReferencesForPublishing());
236 @SuppressWarnings("unchecked")
237 List<Reference> resultRefernces =referenceQuery.list();
238
239 return resultRefernces;
240 }
241
242 // the result list held doubles therefore I put a "distinct" in the query string
243 @Override
244 public List<Reference> getAllNomenclaturalReferences() {
245 @SuppressWarnings("unchecked")
246 List<Reference> references = getSession().createQuery(
247 "SELECT DISTINCT t.nomenclaturalReference FROM TaxonName t").list();
248 return references;
249 }
250
251
252 @Override
253 public List<Reference> getSubordinateReferences(Reference reference) {
254
255 List<Reference> references = new ArrayList();
256 List<Reference> subordinateReferences = new ArrayList<Reference>();
257
258 Query query = getSession().createQuery("select r from Reference r where r.inReference = (:reference)");
259 query.setParameter("reference", reference);
260
261 @SuppressWarnings("unchecked")
262 List<Reference> list = query.list();
263 references.addAll(list);
264 for(Reference ref : references){
265 subordinateReferences.addAll(getSubordinateReferences(ref));
266 }
267 references.addAll(subordinateReferences);
268 return references;
269 }
270
271 @Override
272 public List<TaxonBase> listCoveredTaxa(Reference reference, boolean includeSubordinateReferences, List<OrderHint> orderHints, List<String> propertyPaths) {
273
274 /*
275 * <li>taxon.name.nomenclaturalreference</li>
276 * <li>taxon.descriptions.descriptionElement.sources.citation</li>
277 * <li>taxon.descriptions.descriptionSources</li>
278 * <li>taxon.name.descriptions.descriptionElement.sources</li>
279 * <li>taxon.name.descriptions.descriptionSources</li>
280 */
281
282 //TODO implement search in nameDescriptions
283 Set<Reference> referenceSet = new HashSet<Reference>();
284 referenceSet.add(reference);
285 if(includeSubordinateReferences){
286 referenceSet.addAll(getSubordinateReferences(reference));
287 }
288
289
290 StringBuilder taxonDescriptionSql = new StringBuilder();
291 taxonDescriptionSql.append(
292 "select distinct t from Taxon t " +
293 // TaxonDescription
294 "left join t.descriptions td " +
295 "left join td.descriptionSources td_s " +
296 "left join td.descriptionElements td_e " +
297 "left join td_e.sources td_e_s " +
298 // TaxonNameDescription
299 "left join t.name n " +
300 "left join n.descriptions nd " +
301 "left join nd.descriptionSources nd_s " +
302 "left join nd.descriptionElements nd_e " +
303 "left join nd_e.sources nd_e_s " +
304
305 "where td_e_s.citation in (:referenceBase_1) " +
306 "or td_s in (:referenceBase_2) " +
307 "or nd_e_s.citation in (:referenceBase_3) " +
308 "or nd_s in (:referenceBase_4) or " +
309 "n.nomenclaturalReference in (:referenceBase_5) or " +
310 "t.sec in (:referenceBase_6)"
311 );
312
313 if (orderHints != null && orderHints.size() > 0){
314 taxonDescriptionSql.append(" order by ");
315 int i = 0;
316 for (OrderHint hint : orderHints) {
317 if(i > 0) {
318 taxonDescriptionSql.append(", ");
319 }
320 taxonDescriptionSql.append("t.").append(hint.toHql());
321 }
322 }
323
324 // TODO include:
325 // name relations
326 // taxon relations
327
328 Query query = getSession().createQuery(taxonDescriptionSql.toString());
329 query.setParameterList("referenceBase_1", referenceSet);
330 query.setParameterList("referenceBase_2", referenceSet);
331 query.setParameterList("referenceBase_3", referenceSet);
332 query.setParameterList("referenceBase_4", referenceSet);
333 query.setParameterList("referenceBase_5", referenceSet);
334 query.setParameterList("referenceBase_6", referenceSet);
335
336 @SuppressWarnings("unchecked")
337 List<TaxonBase> taxonBaseList = query.list();
338
339 defaultBeanInitializer.initializeAll(taxonBaseList, propertyPaths);
340
341 return taxonBaseList;
342 }
343
344 /* (non-Javadoc)
345 * @see eu.etaxonomy.cdm.persistence.dao.reference.IReferenceDao#getUuidAndAbbrevTitleCache(java.lang.Integer, java.lang.String)
346 */
347 @Override
348 public List<UuidAndTitleCache<Reference>> getUuidAndAbbrevTitleCache(Integer limit, String pattern, ReferenceType refType) {
349 Session session = getSession();
350 Reference ref = ReferenceFactory.newArticle();
351
352 Query query = null;
353 if (pattern != null){
354 if (pattern.startsWith("*")){
355 query = session.createQuery("select uuid, id, abbrevTitleCache, titleCache from " + type.getSimpleName() +" where abbrevTitleCache like :pattern OR titleCache like :pattern ");
356 }else{
357 query = session.createQuery("select uuid, id, abbrevTitleCache, titleCache from " + type.getSimpleName() +" where abbrevTitleCache like :pattern ");
358 }
359 pattern = pattern + "%";
360 pattern = pattern.replace("*", "%");
361 pattern = pattern.replace("?", "_");
362 query.setParameter("pattern", pattern);
363 } else {
364 query = session.createQuery("select uuid, id, abbrevTitleCache, titleCache from " + type.getSimpleName() );
365 }
366 if (limit != null){
367 query.setMaxResults(limit);
368 }
369
370 return getUuidAndAbbrevTitleCache(query);
371
372 }
373
374 /* (non-Javadoc)
375 * @see eu.etaxonomy.cdm.persistence.dao.reference.IReferenceDao#getUuidAndAbbrevTitleCache(java.lang.Integer, java.lang.String)
376 */
377 @Override
378 public List<UuidAndTitleCache<Reference>> getUuidAndAbbrevTitleCacheForAuthor(Integer limit, String pattern, ReferenceType refType) {
379 Session session = getSession();
380 Reference ref = ReferenceFactory.newArticle();
381
382 Query query = null;
383 if (pattern != null){
384 query = session.createQuery("SELECT uuid, id, abbrevTitleCache, titleCache from " + type.getSimpleName()
385 +" as r where r.authorship.nomenclaturalTitle like :pattern ");
386
387 query.setParameter("pattern", pattern);
388 } else {
389 query = session.createQuery("select uuid, id, abbrevTitleCache, titleCache from " + type.getSimpleName() );
390 }
391 if (limit != null){
392 query.setMaxResults(limit);
393 }
394 pattern = pattern.replace("*", "%");
395 pattern = pattern.replace("?", "_");
396 query.setParameter("pattern", pattern);
397 return getUuidAndAbbrevTitleCache(query);
398
399 }
400 }