import org.apache.log4j.Logger;\r
import org.apache.lucene.index.CorruptIndexException;\r
import org.apache.lucene.queryParser.ParseException;\r
+import org.apache.lucene.search.BooleanClause.Occur;\r
+import org.apache.lucene.search.BooleanQuery;\r
import org.apache.lucene.search.Query;\r
import org.apache.lucene.search.SortField;\r
import org.apache.lucene.search.TopDocs;\r
-import org.hibernate.criterion.Criterion;\r
import org.springframework.beans.factory.annotation.Autowired;\r
import org.springframework.stereotype.Service;\r
import org.springframework.transaction.annotation.Propagation;\r
import eu.etaxonomy.cdm.api.service.pager.impl.DefaultPagerImpl;\r
import eu.etaxonomy.cdm.api.service.search.ISearchResultBuilder;\r
import eu.etaxonomy.cdm.api.service.search.LuceneSearch;\r
+import eu.etaxonomy.cdm.api.service.search.QueryFactory;\r
import eu.etaxonomy.cdm.api.service.search.SearchResult;\r
import eu.etaxonomy.cdm.api.service.search.SearchResultBuilder;\r
-import eu.etaxonomy.cdm.api.service.search.SearchResultHighligther;\r
import eu.etaxonomy.cdm.common.monitor.IProgressMonitor;\r
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;\r
import eu.etaxonomy.cdm.hibernate.search.DefinedTermBaseClassBridge;\r
+import eu.etaxonomy.cdm.hibernate.search.MultilanguageTextFieldBridge;\r
import eu.etaxonomy.cdm.model.common.CdmBase;\r
-import eu.etaxonomy.cdm.model.common.DefinedTermBase;\r
import eu.etaxonomy.cdm.model.common.IdentifiableEntity;\r
import eu.etaxonomy.cdm.model.common.IdentifiableSource;\r
import eu.etaxonomy.cdm.model.common.Language;\r
import eu.etaxonomy.cdm.model.media.MediaRepresentation;\r
import eu.etaxonomy.cdm.model.media.MediaUtils;\r
import eu.etaxonomy.cdm.model.name.HomotypicalGroup;\r
-import eu.etaxonomy.cdm.model.name.NonViralName;\r
import eu.etaxonomy.cdm.model.name.Rank;\r
import eu.etaxonomy.cdm.model.name.TaxonNameBase;\r
import eu.etaxonomy.cdm.model.name.ZoologicalName;\r
return medRep;\r
}\r
\r
+ /* (non-Javadoc)\r
+ * @see eu.etaxonomy.cdm.api.service.ITaxonService#listTaxonDescriptionMedia(eu.etaxonomy.cdm.model.taxon.Taxon, boolean)\r
+ */\r
+ public List<Media> listTaxonDescriptionMedia(Taxon taxon, boolean limitToGalleries, List<String> propertyPath){\r
+\r
+ Pager<TaxonDescription> p =\r
+ descriptionService.getTaxonDescriptions(taxon, null, null, null, null, propertyPath);\r
+\r
+ // pars the media and quality parameters\r
+\r
+\r
+ // collect all media of the given taxon\r
+ List<Media> taxonMedia = new ArrayList<Media>();\r
+ List<Media> taxonGalleryMedia = new ArrayList<Media>();\r
+ for(TaxonDescription desc : p.getRecords()){\r
+\r
+ if(desc.isImageGallery()){\r
+ for(DescriptionElementBase element : desc.getElements()){\r
+ for(Media media : element.getMedia()){\r
+ taxonGalleryMedia.add(media);\r
+ }\r
+ }\r
+ } else if(!limitToGalleries){\r
+ for(DescriptionElementBase element : desc.getElements()){\r
+ for(Media media : element.getMedia()){\r
+ taxonMedia.add(media);\r
+ }\r
+ }\r
+ }\r
+\r
+ }\r
+\r
+ taxonGalleryMedia.addAll(taxonMedia);\r
+ return taxonGalleryMedia;\r
+ }\r
+\r
/* (non-Javadoc)\r
* @see eu.etaxonomy.cdm.api.service.ITaxonService#findTaxaByID(java.util.Set)\r
*/\r
return dao.getUuidAndTitleCacheSynonym();\r
}\r
\r
+ @Override\r
+ public Pager<SearchResult<TaxonBase>> findByFullText(\r
+ Class<? extends TaxonBase> clazz, String queryString,\r
+ Classification classification, List<Language> languages,\r
+ boolean highlightFragments, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) throws CorruptIndexException, IOException, ParseException {\r
+\r
+// // -- set defaults\r
+// Class<? extends TaxonBase> directorySelectClass = TaxonBase.class;\r
+// if(clazz != null){\r
+// directorySelectClass = clazz;\r
+// }\r
+ return null;\r
+\r
+ }\r
+\r
@Override\r
public Pager<SearchResult<TaxonBase>> findByDescriptionElementFullText(\r
Class<? extends DescriptionElementBase> clazz, String queryString,\r
Classification classification, List<Feature> features, List<Language> languages,\r
boolean highlightFragments, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) throws CorruptIndexException, IOException, ParseException {\r
\r
+ // -- set defaults\r
Class<? extends DescriptionElementBase> directorySelectClass = DescriptionElementBase.class;\r
if(clazz != null){\r
directorySelectClass = clazz;\r
}\r
\r
- Set<String> freetextFields = new HashSet<String>();\r
+\r
+ BooleanQuery finalQuery = new BooleanQuery();\r
+ BooleanQuery textQuery = new BooleanQuery();\r
+\r
+ LuceneSearch luceneSearch = new LuceneSearch(getSession(), directorySelectClass);\r
+ QueryFactory queryFactory = new QueryFactory(luceneSearch);\r
+\r
// ---- search criteria\r
- freetextFields.add("titleCache");\r
- StringBuilder luceneQueryTemplate = new StringBuilder();\r
- luceneQueryTemplate.append("+(");\r
- luceneQueryTemplate.append("titleCache:%1$s ");\r
+ textQuery.add(queryFactory.newTermQuery("titleCache", queryString), Occur.SHOULD);\r
+\r
// common name\r
- freetextFields.add("name");\r
+ Query nameQuery;\r
if(languages == null || languages.size() == 0){\r
- luceneQueryTemplate.append("name:%1$s ");\r
+ nameQuery = queryFactory.newTermQuery("name", queryString);\r
} else {\r
- luceneQueryTemplate.append("(+name:%1$s ");\r
+ nameQuery = new BooleanQuery();\r
+ BooleanQuery languageSubQuery = new BooleanQuery();\r
for(Language lang : languages){\r
- luceneQueryTemplate.append(" +language.uuid:" + lang.getUuid().toString());\r
+ languageSubQuery.add(queryFactory.newTermQuery("language.uuid", lang.getUuid().toString()), Occur.SHOULD);\r
}\r
- luceneQueryTemplate.append(")");\r
+ ((BooleanQuery) nameQuery).add(queryFactory.newTermQuery("name", queryString), Occur.MUST);\r
+ ((BooleanQuery) nameQuery).add(languageSubQuery, Occur.MUST);\r
}\r
+ textQuery.add(nameQuery, Occur.SHOULD);\r
+\r
+\r
// text field from TextData\r
- freetextFields.add("text.ALL");\r
- appendLocalizedFieldQuery("text", languages, luceneQueryTemplate).append(" ");\r
+ textQuery.add(queryFactory.newLocalizedTermQuery("text", queryString, languages), Occur.SHOULD);\r
+\r
+ // --- TermBase fields - by representation ----\r
// state field from CategoricalData\r
- freetextFields.add("states.state.representation.ALL");\r
- appendLocalizedFieldQuery("states.state.representation", languages, luceneQueryTemplate).append(" ");\r
+ textQuery.add(queryFactory.newLocalizedTermQuery("states.state.representation", queryString, languages), Occur.SHOULD);\r
+\r
// state field from CategoricalData\r
- freetextFields.add("states.modifyingText.ALL");\r
- appendLocalizedFieldQuery("states.modifyingText", languages, luceneQueryTemplate).append(" ");\r
- luceneQueryTemplate.append(") ");\r
+ textQuery.add(queryFactory.newLocalizedTermQuery("states.modifyingText", queryString, languages), Occur.SHOULD);\r
+\r
+ finalQuery.add(textQuery, Occur.MUST);\r
+ // --- classification ----\r
\r
if(classification != null){\r
- luceneQueryTemplate.append("+inDescription.taxon.taxonNodes.classification.id:").append(classification.getId()).append(" ");\r
+ finalQuery.add(queryFactory.newEntityIdQuery("inDescription.taxon.taxonNodes.classification.id", classification), Occur.MUST);\r
}\r
\r
+ // --- IdentifieableEntity fields - by uuid\r
if(features != null && features.size() > 0 ){\r
- luceneQueryTemplate.append("+feature.uuid:(");\r
- for(Feature feature : features){\r
- luceneQueryTemplate.append(feature.getUuid()).append(" ");\r
- }\r
- luceneQueryTemplate.append(") ");\r
+ finalQuery.add(queryFactory.newEntityUuidQuery("feature.uuid", features), Occur.MUST);\r
}\r
\r
// the description must be associated with a taxon\r
- // TODO open range queries [0 TO *] not working in the current version of lucene (https://issues.apache.org/jira/browse/LUCENE-995)\r
- // so we are using integer maximum as workaround\r
- luceneQueryTemplate.append("+inDescription.taxon.id:[0 TO " + Integer.MAX_VALUE + "] ");\r
-\r
- String luceneQueryStr = String.format(luceneQueryTemplate.toString(), queryString);\r
+ finalQuery.add(queryFactory.newIdNotNullQuery("inDescription.taxon.id"), Occur.MUST);\r
\r
- // --- sort fields\r
SortField[] sortFields = new SortField[]{SortField.FIELD_SCORE, new SortField("inDescription.taxon.titleCache__sort", false)};\r
\r
- // ---- execute criteria\r
- LuceneSearch luceneSearch = new LuceneSearch(getSession(), directorySelectClass);\r
-\r
- Query luceneQuery = luceneSearch.parse(luceneQueryStr);\r
- TopDocs topDocsResultSet = luceneSearch.executeSearch(luceneQuery, clazz, pageSize, pageNumber, sortFields);\r
+ TopDocs topDocsResultSet = luceneSearch.executeSearch(finalQuery, clazz, pageSize, pageNumber, sortFields);\r
\r
String[] highlightFields = null;\r
if(highlightFragments){\r
- highlightFields = freetextFields.toArray(new String[freetextFields.size()]);\r
+ highlightFields = queryFactory.getTextFieldNames().toArray(new String[queryFactory.getTextFieldNames().size()]);\r
}\r
\r
// initialize taxa, thighlight matches ....\r
- ISearchResultBuilder searchResultBuilder = new SearchResultBuilder(luceneSearch, luceneQuery);\r
+ ISearchResultBuilder searchResultBuilder = new SearchResultBuilder(luceneSearch, finalQuery);\r
List<SearchResult<TaxonBase>> searchResults = searchResultBuilder.createResultSet(\r
topDocsResultSet, highlightFields, dao, "inDescription.taxon.id", propertyPaths);\r
\r
stringBuilder = new StringBuilder();\r
}\r
if(languages == null || languages.size() == 0){\r
- stringBuilder.append(name + ".ALL:%1$s ");\r
+ stringBuilder.append(name + ".ALL:(%1$s) ");\r
} else {\r
for(Language lang : languages){\r
- stringBuilder.append(name + "." + lang.getUuid().toString() + ":%1$s ");\r
+ stringBuilder.append(name + "." + lang.getUuid().toString() + ":(%1$s) ");\r
}\r
}\r
return stringBuilder;\r