fixing #4112 (portal/taxon/{uuid}/accepted/{uuid} takes exceedingly much time in...
[cdmlib.git] / cdmlib-persistence / src / main / java / eu / etaxonomy / cdm / persistence / dao / hibernate / description / DescriptionElementDaoImpl.java
1 package eu.etaxonomy.cdm.persistence.dao.hibernate.description;
2
3 import java.util.ArrayList;
4 import java.util.List;
5
6 import org.apache.log4j.Logger;
7 import org.apache.lucene.analysis.standard.StandardAnalyzer;
8 import org.apache.lucene.queryParser.ParseException;
9 import org.apache.lucene.queryParser.QueryParser;
10 import org.hibernate.Hibernate;
11 import org.hibernate.Query;
12 import org.hibernate.search.FullTextSession;
13 import org.hibernate.search.Search;
14 import org.hibernate.search.SearchFactory;
15 import org.springframework.stereotype.Repository;
16
17 import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
18 import eu.etaxonomy.cdm.model.description.TextData;
19 import eu.etaxonomy.cdm.model.media.Media;
20 import eu.etaxonomy.cdm.model.view.AuditEvent;
21 import eu.etaxonomy.cdm.persistence.dao.QueryParseException;
22 import eu.etaxonomy.cdm.persistence.dao.description.IDescriptionElementDao;
23 import eu.etaxonomy.cdm.persistence.dao.hibernate.common.AnnotatableDaoImpl;
24 import eu.etaxonomy.cdm.persistence.query.OrderHint;
25
26 @Repository
27 public class DescriptionElementDaoImpl extends AnnotatableDaoImpl<DescriptionElementBase> implements IDescriptionElementDao {
28 @SuppressWarnings("unused")
29 private static final Logger logger = Logger.getLogger(DescriptionElementDaoImpl.class);
30
31 private String defaultField = "multilanguageText.text";
32
33 private Class<? extends DescriptionElementBase> indexedClasses[];
34
35 public DescriptionElementDaoImpl() {
36 super(DescriptionElementBase.class);
37 indexedClasses = new Class[1];
38 indexedClasses[0] = TextData.class;
39 }
40
41 public int countMedia(DescriptionElementBase descriptionElement) {
42 AuditEvent auditEvent = getAuditEventFromContext();
43 if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
44 Query query = getSession().createQuery("select count(media) from DescriptionElementBase descriptionElement join descriptionElement.media media where descriptionElement = :descriptionElement");
45 query.setParameter("descriptionElement", descriptionElement);
46
47 return ((Long)query.uniqueResult()).intValue();
48 } else {
49 // Horribly inefficient, I know, but hard to do at the moment with envers.
50 // FIXME Improve this (by improving envers)
51 List<String> propertyPaths = new ArrayList<String>();
52 propertyPaths.add("media");
53 DescriptionElementBase d = super.load(descriptionElement.getUuid(), propertyPaths);
54 return d.getMedia().size();
55 }
56 }
57
58 public int count(Class<? extends DescriptionElementBase> clazz, String queryString) {
59 checkNotInPriorView("DescriptionElementDaoImpl.countTextData(String queryString)");
60 QueryParser queryParser = new QueryParser(version, defaultField, new StandardAnalyzer(version));
61
62 try {
63 org.apache.lucene.search.Query query = queryParser.parse(queryString);
64
65 FullTextSession fullTextSession = Search.getFullTextSession(getSession());
66 org.hibernate.search.FullTextQuery fullTextQuery = null;
67
68 if(clazz == null) {
69 fullTextQuery = fullTextSession.createFullTextQuery(query, type);
70 } else {
71 fullTextQuery = fullTextSession.createFullTextQuery(query, clazz);
72 }
73 return fullTextQuery.getResultSize();
74 } catch (ParseException e) {
75 throw new QueryParseException(e, queryString);
76 }
77 }
78
79 public List<Media> getMedia(DescriptionElementBase descriptionElement, Integer pageSize, Integer pageNumber, List<String> propertyPaths) {
80 AuditEvent auditEvent = getAuditEventFromContext();
81 if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
82 Query query = getSession().createQuery("select media from DescriptionElementBase descriptionElement join descriptionElement.media media where descriptionElement = :descriptionElement order by index(media)");
83 query.setParameter("descriptionElement", descriptionElement);
84
85 if(pageSize != null) {
86 query.setMaxResults(pageSize);
87 if(pageNumber != null) {
88 query.setFirstResult(pageNumber * pageSize);
89 } else {
90 query.setFirstResult(0);
91 }
92 }
93
94 List<Media> results = (List<Media>)query.list();
95 defaultBeanInitializer.initializeAll(results, propertyPaths);
96 return results;
97 } else {
98 // Horribly inefficient, I know, but hard to do at the moment with envers.
99 // FIXME Improve this (by improving envers)
100 List<String> pPaths = new ArrayList<String>();
101 propertyPaths.add("media");
102 DescriptionElementBase d = super.load(descriptionElement.getUuid(), pPaths);
103 List<Media> results = new ArrayList<Media>();
104 results.addAll(d.getMedia());
105 if(pageSize != null) {
106 int fromIndex = 0;
107 int toIndex = 0;
108 if(pageNumber != null) {
109 // if the page is out of scope
110 if(results.size() < (pageNumber * pageSize)) {
111 return new ArrayList<Media>();
112 }
113 fromIndex = pageNumber * pageSize;
114 }
115 toIndex = results.size() < (fromIndex + pageSize) ? results.size() : fromIndex + pageSize;
116 results = results.subList(fromIndex, toIndex);
117 }
118 defaultBeanInitializer.initializeAll(results, propertyPaths);
119 return results;
120 }
121 }
122
123 public List<DescriptionElementBase> search(Class<? extends DescriptionElementBase> clazz, String queryString, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {
124 checkNotInPriorView("DescriptionElementDaoImpl.searchTextData(String queryString, Integer pageSize, Integer pageNumber)");
125 QueryParser queryParser = new QueryParser(version, defaultField, new StandardAnalyzer(version));
126
127 try {
128 org.apache.lucene.search.Query query = queryParser.parse(queryString);
129 org.hibernate.search.FullTextQuery fullTextQuery = null;
130 FullTextSession fullTextSession = Search.getFullTextSession(getSession());
131 if(clazz == null) {
132 fullTextQuery = fullTextSession.createFullTextQuery(query, type);
133 } else {
134 fullTextQuery = fullTextSession.createFullTextQuery(query, clazz);
135 }
136 addOrder(fullTextQuery,orderHints);
137
138 if(pageSize != null) {
139 fullTextQuery.setMaxResults(pageSize);
140 if(pageNumber != null) {
141 fullTextQuery.setFirstResult(pageNumber * pageSize);
142 } else {
143 fullTextQuery.setFirstResult(0);
144 }
145 }
146
147 List<DescriptionElementBase> results = fullTextQuery.list();
148 defaultBeanInitializer.initializeAll(results, propertyPaths);
149 return results;
150
151 } catch (ParseException e) {
152 throw new QueryParseException(e, queryString);
153 }
154 }
155
156 public void purgeIndex() {
157 FullTextSession fullTextSession = Search.getFullTextSession(getSession());
158 for(Class clazz : indexedClasses) {
159 fullTextSession.purgeAll(type); // remove all description element base from indexes
160 }
161 fullTextSession.flushToIndexes();
162 }
163
164 public void rebuildIndex() {
165 FullTextSession fullTextSession = Search.getFullTextSession(getSession());
166
167 for(DescriptionElementBase descriptionElementBase : list(null,null)) { // re-index all descriptionElements
168 Hibernate.initialize(descriptionElementBase.getInDescription());
169 Hibernate.initialize(descriptionElementBase.getFeature());
170 fullTextSession.index(descriptionElementBase);
171 }
172 fullTextSession.flushToIndexes();
173 }
174
175 public void optimizeIndex() {
176 FullTextSession fullTextSession = Search.getFullTextSession(getSession());
177 SearchFactory searchFactory = fullTextSession.getSearchFactory();
178 for(Class clazz : indexedClasses) {
179 searchFactory.optimize(clazz); // optimize the indices ()
180 }
181 fullTextSession.flushToIndexes();
182 }
183
184 public int count(String queryString) {
185 checkNotInPriorView("DescriptionElementDaoImpl.count(String queryString)");
186 QueryParser queryParser = new QueryParser(version, defaultField, new StandardAnalyzer(version));
187
188 try {
189 org.apache.lucene.search.Query query = queryParser.parse(queryString);
190
191 FullTextSession fullTextSession = Search.getFullTextSession(this.getSession());
192 org.hibernate.search.FullTextQuery fullTextQuery = fullTextSession.createFullTextQuery(query, type);
193
194 return fullTextQuery.getResultSize();
195
196 } catch (ParseException e) {
197 throw new QueryParseException(e, queryString);
198 }
199 }
200
201 public String suggestQuery(String string) {
202 throw new UnsupportedOperationException("suggest query is not supported yet");
203 }
204
205 }