import java.io.IOException;\r
import java.util.ArrayList;\r
import java.util.Arrays;\r
+import java.util.Collection;\r
+import java.util.EnumSet;\r
+import java.util.HashSet;\r
import java.util.List;\r
import java.util.Set;\r
import java.util.UUID;\r
import javax.servlet.http.HttpServletRequest;\r
import javax.servlet.http.HttpServletResponse;\r
\r
+import org.apache.commons.lang.BooleanUtils;\r
import org.apache.lucene.queryParser.ParseException;\r
import org.springframework.beans.factory.annotation.Autowired;\r
import org.springframework.stereotype.Controller;\r
+import org.springframework.web.bind.WebDataBinder;\r
+import org.springframework.web.bind.annotation.InitBinder;\r
+import org.springframework.web.bind.annotation.PathVariable;\r
import org.springframework.web.bind.annotation.RequestMapping;\r
import org.springframework.web.bind.annotation.RequestMethod;\r
import org.springframework.web.bind.annotation.RequestParam;\r
import eu.etaxonomy.cdm.api.service.IClassificationService;\r
import eu.etaxonomy.cdm.api.service.ITaxonService;\r
import eu.etaxonomy.cdm.api.service.ITermService;\r
+import eu.etaxonomy.cdm.api.service.TaxaAndNamesSearchMode;\r
import eu.etaxonomy.cdm.api.service.config.FindTaxaAndNamesConfiguratorImpl;\r
import eu.etaxonomy.cdm.api.service.config.IFindTaxaAndNamesConfigurator;\r
import eu.etaxonomy.cdm.api.service.pager.Pager;\r
import eu.etaxonomy.cdm.model.common.Language;\r
import eu.etaxonomy.cdm.model.description.DescriptionElementBase;\r
import eu.etaxonomy.cdm.model.description.Feature;\r
+import eu.etaxonomy.cdm.model.description.PresenceAbsenceTermBase;\r
import eu.etaxonomy.cdm.model.location.NamedArea;\r
import eu.etaxonomy.cdm.model.taxon.Classification;\r
import eu.etaxonomy.cdm.model.taxon.Synonym;\r
import eu.etaxonomy.cdm.persistence.query.MatchMode;\r
import eu.etaxonomy.cdm.persistence.query.OrderHint;\r
import eu.etaxonomy.cdm.remote.controller.util.PagerParameters;\r
+import eu.etaxonomy.cdm.remote.editor.DefinedTermBaseList;\r
+import eu.etaxonomy.cdm.remote.editor.TermBaseListPropertyEditor;\r
import eu.etaxonomy.cdm.remote.editor.UuidList;\r
\r
/**\r
public class TaxonListController extends IdentifiableListController<TaxonBase, ITaxonService> {\r
\r
\r
+ private static final List<String> SIMPLE_TAXON_INIT_STRATEGY = DEFAULT_INIT_STRATEGY;\r
+ protected List<String> getSimpleTaxonInitStrategy() {\r
+ // TODO Auto-generated method stub\r
+ return SIMPLE_TAXON_INIT_STRATEGY;\r
+ }\r
\r
/**\r
*\r
@Autowired\r
private ITermService termService;\r
\r
+ @InitBinder\r
+ @Override\r
+ public void initBinder(WebDataBinder binder) {\r
+ super.initBinder(binder);\r
+ binder.registerCustomEditor(DefinedTermBaseList.class, new TermBaseListPropertyEditor<NamedArea>(termService));\r
+ }\r
+\r
+ /**\r
+ * Find Taxa, Synonyms, Common Names by name, either globally or in a specific geographic area.\r
+ * <p>\r
+ * URI: <b>/{datasource-name}/portal/taxon/find</b>\r
+ *\r
+ * @param query\r
+ * the string to query for. Since the wildcard character '*'\r
+ * internally always is appended to the query string, a search\r
+ * always compares the query string with the beginning of a name.\r
+ * - <i>required parameter</i>\r
+ * @param treeUuid\r
+ * the {@link UUID} of a {@link Classification} to which the\r
+ * search is to be restricted. - <i>optional parameter</i>\r
+ * @param areas\r
+ * restrict the search to a set of geographic {@link NamedArea}s.\r
+ * The parameter currently takes a list of TDWG area labels.\r
+ * - <i>optional parameter</i>\r
+ * @param pageNumber\r
+ * the number of the page to be returned, the first page has the\r
+ * pageNumber = 1 - <i>optional parameter</i>\r
+ * @param pageSize\r
+ * the maximum number of entities returned per page (can be -1\r
+ * to return all entities in a single page) - <i>optional parameter</i>\r
+ * @param doTaxa\r
+ * weather to search for instances of {@link Taxon} - <i>optional parameter</i>\r
+ * @param doSynonyms\r
+ * weather to search for instances of {@link Synonym} - <i>optional parameter</i>\r
+ * @param doTaxaByCommonNames\r
+ * for instances of {@link Taxon} by a common name used - <i>optional parameter</i>\r
+ * @return a Pager on a list of {@link IdentifiableEntity}s initialized by\r
+ * the following strategy {@link #SIMPLE_TAXON_INIT_STRATEGY}\r
+ * @throws IOException\r
+ * @throws LuceneMultiSearchException\r
+ * @throws ParseException\r
+ */\r
+ @RequestMapping(method = RequestMethod.GET, value={"search"})\r
+ public Pager<SearchResult<TaxonBase>> doSearch(\r
+ @RequestParam(value = "query", required = true) String query,\r
+ @RequestParam(value = "tree", required = false) UUID treeUuid,\r
+ @RequestParam(value = "area", required = false) DefinedTermBaseList<NamedArea> areaList,\r
+ @RequestParam(value = "status", required = false) Set<PresenceAbsenceTermBase<?>> status,\r
+ @RequestParam(value = "pageNumber", required = false) Integer pageNumber,\r
+ @RequestParam(value = "pageSize", required = false) Integer pageSize,\r
+ @RequestParam(value = "doTaxa", required = false) Boolean doTaxa,\r
+ @RequestParam(value = "doSynonyms", required = false) Boolean doSynonyms,\r
+ @RequestParam(value = "doMisappliedNames", required = false) Boolean doMisappliedNames,\r
+ @RequestParam(value = "doTaxaByCommonNames", required = false) Boolean doTaxaByCommonNames,\r
+ HttpServletRequest request,\r
+ HttpServletResponse response\r
+ )\r
+ throws IOException, ParseException, LuceneMultiSearchException {\r
+\r
+\r
+ logger.info("search : " + requestPathAndQuery(request) );\r
+\r
+ Set<NamedArea> areaSet = null;\r
+ if(areaList != null){\r
+ areaSet = new HashSet<NamedArea>(areaList.size());\r
+ areaSet.addAll(areaList);\r
+ TaxonListController.includeAllSubAreas(areaSet, termService);\r
+ }\r
+\r
+ PagerParameters pagerParams = new PagerParameters(pageSize, pageNumber);\r
+ pagerParams.normalizeAndValidate(response);\r
+\r
+ // TODO change type of do* parameters to TaxaAndNamesSearchMode\r
+ EnumSet<TaxaAndNamesSearchMode> searchModes = EnumSet.noneOf(TaxaAndNamesSearchMode.class);\r
+ if(BooleanUtils.toBoolean(doTaxa)) {\r
+ searchModes.add(TaxaAndNamesSearchMode.doTaxa);\r
+ }\r
+ if(BooleanUtils.toBoolean(doSynonyms)) {\r
+ searchModes.add(TaxaAndNamesSearchMode.doSynonyms);\r
+ }\r
+ if(BooleanUtils.toBoolean(doMisappliedNames)) {\r
+ searchModes.add(TaxaAndNamesSearchMode.doMisappliedNames);\r
+ }\r
+ if(BooleanUtils.toBoolean(doTaxaByCommonNames)) {\r
+ searchModes.add(TaxaAndNamesSearchMode.doTaxaByCommonNames);\r
+ }\r
+\r
+ Classification classification = null;\r
+ if(treeUuid != null){\r
+ classification = classificationService.find(treeUuid);\r
+ }\r
+\r
+ return service.findTaxaAndNamesByFullText(searchModes, query,\r
+ classification, areaSet, status, null,\r
+ false, pagerParams.getPageSize(), pagerParams.getPageIndex(),\r
+ OrderHint.NOMENCLATURAL_SORT_ORDER, getSimpleTaxonInitStrategy());\r
+ }\r
\r
/**\r
* Find Taxa, Synonyms, Common Names by name, either globally or in a specific geographic area.\r
* the following strategy {@link #SIMPLE_TAXON_INIT_STRATEGY}\r
* @throws IOException\r
*/\r
- @RequestMapping(method = RequestMethod.GET, value={"findTaxaAndNames"})\r
- public Pager<IdentifiableEntity> doFindTaxaAndNames(\r
+ @RequestMapping(method = RequestMethod.GET, value={"find"})\r
+ public Pager<IdentifiableEntity> doFind(\r
@RequestParam(value = "query", required = true) String query,\r
@RequestParam(value = "tree", required = false) UUID treeUuid,\r
@RequestParam(value = "area", required = false) Set<NamedArea> areas,\r
throws IOException {\r
\r
\r
- logger.info("findTaxaAndNames : " + request.getRequestURI() + "?" + request.getQueryString() );\r
+ logger.info("find : " + request.getRequestURI() + "?" + request.getQueryString() );\r
\r
PagerParameters pagerParams = new PagerParameters(pageSize, pageNumber);\r
pagerParams.normalizeAndValidate(response);\r
\r
IFindTaxaAndNamesConfigurator config = new FindTaxaAndNamesConfiguratorImpl();\r
-\r
- config.setTaxonPropertyPath(initializationStrategy);\r
-\r
config.setPageNumber(pagerParams.getPageIndex());\r
config.setPageSize(pagerParams.getPageSize());\r
config.setTitleSearchString(query);\r
config.setDoMisappliedNames(doMisappliedNames != null ? doMisappliedNames : Boolean.FALSE);\r
config.setDoTaxaByCommonNames(doTaxaByCommonNames != null ? doTaxaByCommonNames : Boolean.FALSE );\r
config.setMatchMode(matchMode != null ? matchMode : MatchMode.BEGINNING);\r
-// config.setTaxonPropertyPath(SIMPLE_TAXON_INIT_STRATEGY);\r
+ config.setTaxonPropertyPath(getSimpleTaxonInitStrategy());\r
config.setNamedAreas(areas);\r
if(treeUuid != null){\r
Classification classification = classificationService.find(treeUuid);\r
\r
}\r
\r
+\r
/**\r
* @param clazz\r
* @param queryString\r
)\r
throws IOException, ParseException {\r
\r
- logger.info("findByDescriptionElementFullText : " + request.getRequestURI() + "?" + request.getQueryString() );\r
+ logger.info("findByDescriptionElementFullText : " + requestPathAndQuery(request) );\r
\r
PagerParameters pagerParams = new PagerParameters(pageSize, pageNumber);\r
pagerParams.normalizeAndValidate(response);\r
\r
Pager<SearchResult<TaxonBase>> pager = service.findByDescriptionElementFullText(\r
clazz, queryString, classification, features, languages, highlighting,\r
- pagerParams.getPageSize(), pagerParams.getPageIndex(), ((List<OrderHint>)null),\r
- initializationStrategy);\r
+ pagerParams.getPageSize(), pagerParams.getPageIndex(),\r
+ ((List<OrderHint>)null), getSimpleTaxonInitStrategy());\r
return pager;\r
}\r
\r
)\r
throws IOException, ParseException {\r
\r
- logger.info("findByFullText : " + request.getRequestURI() + "?" + request.getQueryString() );\r
+ logger.info("findByFullText : " + requestPathAndQuery(request) );\r
\r
PagerParameters pagerParams = new PagerParameters(pageSize, pageNumber);\r
pagerParams.normalizeAndValidate(response);\r
}\r
\r
Pager<SearchResult<TaxonBase>> pager = service.findByFullText(clazz, queryString, classification, languages,\r
- highlighting, pagerParams.getPageSize(), pagerParams.getPageIndex(), ((List<OrderHint>)null),\r
+ highlighting, pagerParams.getPageSize(), pagerParams.getPageIndex(), ((List<OrderHint>) null),\r
initializationStrategy);\r
return pager;\r
}\r
)\r
throws IOException, ParseException, LuceneMultiSearchException {\r
\r
- logger.info("findByEverythingFullText : " + request.getRequestURI() + "?" + request.getQueryString() );\r
+ logger.info("findByEverythingFullText : " + requestPathAndQuery(request) );\r
\r
PagerParameters pagerParams = new PagerParameters(pageSize, pageNumber);\r
pagerParams.normalizeAndValidate(response);\r
((List<OrderHint>)null), initializationStrategy);\r
return pager;\r
}\r
+\r
+ /**\r
+ * @param areaSet\r
+ */\r
+ static public void includeAllSubAreas(Set<NamedArea> areaSet, ITermService termService) {\r
+ Collection<NamedArea> tmpAreas = new HashSet<NamedArea>(areaSet);\r
+ // expand all areas to include also the sub areas\r
+ Pager<NamedArea> pager = null;\r
+ while(true){\r
+ pager = termService.getIncludes(tmpAreas, 1000, null, null);\r
+ if(pager.getCount() == 0){\r
+ break;\r
+ }\r
+ tmpAreas = pager.getRecords();\r
+ tmpAreas.removeAll(areaSet);\r
+ areaSet.addAll(tmpAreas);\r
+ }\r
+ }\r
+\r
+ @RequestMapping(value = "bestMatchingTaxon/{taxonName}", method = RequestMethod.GET)\r
+ public TaxonBase doFindBestMatchingTaxon(\r
+ @PathVariable("taxonName") String taxonName,\r
+ HttpServletRequest request,\r
+ HttpServletResponse response)throws IOException {\r
+\r
+ Taxon bestMatchingTaxon = service.findBestMatchingTaxon(taxonName);\r
+\r
+ return bestMatchingTaxon;\r
+ }\r
+\r
}
\ No newline at end of file