cdmlib related part for fixing #2931 (Free text search - hit highlighting implemented...
[cdmlib.git] / cdmlib-remote / src / main / java / eu / etaxonomy / cdm / remote / controller / TaxonPortalController.java
index a1ab0c2f283c7c0d1afa2f3ec828af003799a583..550164881e2067cbcb89ad8917f6f0f623ead88a 100644 (file)
@@ -10,6 +10,8 @@
 \r
 package eu.etaxonomy.cdm.remote.controller;\r
 \r
+import static java.net.HttpURLConnection.HTTP_BAD_REQUEST;\r
+\r
 import java.io.IOException;\r
 import java.util.ArrayList;\r
 import java.util.Arrays;\r
@@ -27,6 +29,7 @@ import javax.servlet.http.HttpServletResponse;
 import org.apache.commons.lang.ObjectUtils;\r
 import org.apache.http.HttpRequest;\r
 import org.apache.log4j.Logger;\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
@@ -37,21 +40,32 @@ import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.bind.annotation.RequestParam;\r
 import org.springframework.web.servlet.ModelAndView;\r
 \r
+\r
 import eu.etaxonomy.cdm.api.service.IDescriptionService;\r
 import eu.etaxonomy.cdm.api.service.IFeatureTreeService;\r
+import eu.etaxonomy.cdm.api.service.IMarkerService;\r
 import eu.etaxonomy.cdm.api.service.INameService;\r
 import eu.etaxonomy.cdm.api.service.IOccurrenceService;\r
+import eu.etaxonomy.cdm.api.service.IService;\r
 import eu.etaxonomy.cdm.api.service.ITaxonService;\r
 import eu.etaxonomy.cdm.api.service.IClassificationService;\r
+import eu.etaxonomy.cdm.api.service.ITermService;\r
 import eu.etaxonomy.cdm.api.service.config.ITaxonServiceConfigurator;\r
 import eu.etaxonomy.cdm.api.service.config.TaxonServiceConfiguratorImpl;\r
 import eu.etaxonomy.cdm.api.service.pager.Pager;\r
+import eu.etaxonomy.cdm.api.service.search.SearchResult;\r
 import eu.etaxonomy.cdm.database.UpdatableRoutingDataSource;\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.common.Marker;\r
+import eu.etaxonomy.cdm.model.common.MarkerType;\r
 import eu.etaxonomy.cdm.model.common.RelationshipBase.Direction;\r
 import eu.etaxonomy.cdm.model.description.DescriptionElementBase;\r
 import eu.etaxonomy.cdm.model.description.TaxonDescription;\r
 import eu.etaxonomy.cdm.model.location.NamedArea;\r
+import eu.etaxonomy.cdm.model.location.NamedAreaLevel;\r
 import eu.etaxonomy.cdm.model.media.Media;\r
 import eu.etaxonomy.cdm.model.media.MediaRepresentationPart;\r
 import eu.etaxonomy.cdm.model.media.MediaUtils;\r
@@ -65,9 +79,13 @@ import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;
 import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;\r
 import eu.etaxonomy.cdm.model.taxon.Classification;\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.CdmTypePropertyEditor;\r
 import eu.etaxonomy.cdm.remote.editor.MatchModePropertyEditor;\r
 import eu.etaxonomy.cdm.remote.editor.NamedAreaPropertyEditor;\r
+import eu.etaxonomy.cdm.remote.editor.UUIDListPropertyEditor;\r
+import eu.etaxonomy.cdm.remote.editor.UuidList;\r
 \r
 /**\r
  * The TaxonPortalController class is a Spring MVC Controller.\r
@@ -112,6 +130,13 @@ public class TaxonPortalController extends BaseController<TaxonBase, ITaxonServi
     @Autowired\r
     private ITaxonService taxonService;\r
 \r
+    @Autowired\r
+    private ITermService markerTypeService;\r
+\r
+    @Autowired\r
+    private IMarkerService markerService;\r
+    //private IService<MarkerType> markerTypeService;\r
+\r
     @Autowired\r
     private IFeatureTreeService featureTreeService;\r
 \r
@@ -208,7 +233,9 @@ public class TaxonPortalController extends BaseController<TaxonBase, ITaxonServi
             "$",\r
             "type.inverseRepresentations",\r
             "fromTaxon.sec",\r
-            "fromTaxon.name"\r
+            "fromTaxon.name",\r
+            "toTaxon.sec",\r
+            "toTaxon.name"\r
     });\r
 \r
     private static final List<String> NAMERELATIONSHIP_INIT_STRATEGY = Arrays.asList(new String []{\r
@@ -229,6 +256,21 @@ public class TaxonPortalController extends BaseController<TaxonBase, ITaxonServi
             "elements.media.title",\r
     });\r
 \r
+    protected static final List<String> TAXONUSEDESCRIPTION_INIT_STRATEGY = Arrays.asList(new String []{\r
+            "$",\r
+            "name.$",\r
+            "name.rank.representations",\r
+            "name.status.type.representations",\r
+            "sources.$",\r
+            "elements.$",\r
+            "elements.states.$",\r
+            "elements.sources.citation.authorTeam",\r
+            "elements.sources.nameUsedInSource.originalNameString",\r
+            /*//"elements.multilanguageText",\r
+            "elements.media.representations.parts",*/\r
+            "elements.media.title",\r
+    });\r
+\r
     protected static final List<String> DESCRIPTION_ELEMENT_INIT_STRATEGY = Arrays.asList(new String []{\r
             "$",\r
             "sources.citation.authorTeam",\r
@@ -294,6 +336,8 @@ public class TaxonPortalController extends BaseController<TaxonBase, ITaxonServi
         binder.registerCustomEditor(NamedArea.class, new NamedAreaPropertyEditor());\r
         binder.registerCustomEditor(MatchMode.class, new MatchModePropertyEditor());\r
         binder.registerCustomEditor(Class.class, new CdmTypePropertyEditor());\r
+        binder.registerCustomEditor(UuidList.class, new UUIDListPropertyEditor());\r
+\r
     }\r
 \r
 \r
@@ -353,6 +397,7 @@ public class TaxonPortalController extends BaseController<TaxonBase, ITaxonServi
             @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
             @RequestParam(value = "matchMode", required = false) MatchMode matchMode,\r
             HttpServletRequest request,\r
@@ -360,16 +405,18 @@ public class TaxonPortalController extends BaseController<TaxonBase, ITaxonServi
             )\r
              throws IOException {\r
 \r
-        logger.info("doFind : " + request.getRequestURI() + request.getQueryString() );\r
+        logger.info("doFind : " + request.getRequestURI() + "?" + request.getQueryString() );\r
 \r
-        BaseListController.normalizeAndValidatePagerParameters(pageNumber, pageSize, response);\r
+        PagerParameters pagerParams = new PagerParameters(pageSize, pageNumber);\r
+        pagerParams.normalizeAndValidate(response);\r
 \r
         ITaxonServiceConfigurator config = new TaxonServiceConfiguratorImpl();\r
-        config.setPageNumber(pageNumber);\r
-        config.setPageSize(pageSize);\r
+        config.setPageNumber(pagerParams.getPageIndex());\r
+        config.setPageSize(pagerParams.getPageSize());\r
         config.setTitleSearchString(query);\r
         config.setDoTaxa(doTaxa!= null ? doTaxa : Boolean.FALSE );\r
         config.setDoSynonyms(doSynonyms != null ? doSynonyms : Boolean.FALSE );\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
@@ -382,6 +429,50 @@ public class TaxonPortalController extends BaseController<TaxonBase, ITaxonServi
         return (Pager<IdentifiableEntity>) service.findTaxaAndNames(config);\r
     }\r
 \r
+    /**\r
+     * @param clazz\r
+     * @param queryString\r
+     * @param treeUuid TODO unimplemented in TaxonServiceImpl !!!!\r
+     * @param languages\r
+     * @param pageNumber\r
+     * @param pageSize\r
+     * @param request\r
+     * @param response\r
+     * @return\r
+     * @throws IOException\r
+     * @throws ParseException\r
+     */\r
+    @RequestMapping(method = RequestMethod.GET, value={"/portal/taxon/findByDescriptionElementFullText"})\r
+    public Pager<SearchResult<TaxonBase>> dofindByDescriptionElementFullText(\r
+            @RequestParam(value = "clazz", required = false) Class clazz,\r
+            @RequestParam(value = "query", required = true) String queryString,\r
+            @RequestParam(value = "tree", required = false) UUID treeUuid,\r
+            @RequestParam(value = "languages", required = false) List<Language> languages,\r
+            @RequestParam(value = "hl", required = false) Boolean highlighting,\r
+            @RequestParam(value = "pageNumber", required = false) Integer pageNumber,\r
+            @RequestParam(value = "pageSize", required = false) Integer pageSize,\r
+            HttpServletRequest request,\r
+            HttpServletResponse response\r
+            )\r
+             throws IOException, ParseException {\r
+\r
+         logger.info("findByDescriptionElementFullText : " + request.getRequestURI() + "?" + request.getQueryString() );\r
+\r
+         PagerParameters pagerParams = new PagerParameters(pageSize, pageNumber);\r
+         pagerParams.normalizeAndValidate(response);\r
+\r
+         if(highlighting == null){\r
+             highlighting = false;\r
+         }\r
+\r
+         Classification classification = null;\r
+        if(treeUuid != null){\r
+            classification = classificationService.find(treeUuid);\r
+        }\r
+        Pager<SearchResult<TaxonBase>> pager = service.findByDescriptionElementFullText(clazz, queryString, classification, languages, highlighting, pagerParams.getPageSize(), pagerParams.getPageIndex(), ((List<OrderHint>)null), SIMPLE_TAXON_INIT_STRATEGY);\r
+        return pager;\r
+    }\r
+\r
     /**\r
      * Get the synonymy for a taxon identified by the <code>{taxon-uuid}</code>.\r
      * The synonymy consists\r
@@ -528,13 +619,14 @@ public class TaxonPortalController extends BaseController<TaxonBase, ITaxonServi
 \r
         logger.info("doGetTaxonRelations()" + request.getServletPath());\r
         Taxon taxon = getCdmBaseInstance(Taxon.class, uuid, response, (List<String>)null);\r
-        List<TaxonRelationship> relations = new ArrayList<TaxonRelationship>();\r
-        List<TaxonRelationship> results = service.listToTaxonRelationships(taxon, TaxonRelationshipType.MISAPPLIED_NAME_FOR(), null, null, null, TAXONRELATIONSHIP_INIT_STRATEGY);\r
-        relations.addAll(results);\r
-        results = service.listToTaxonRelationships(taxon, TaxonRelationshipType.INVALID_DESIGNATION_FOR(), null, null, null, TAXONRELATIONSHIP_INIT_STRATEGY);\r
-        relations.addAll(results);\r
+        List<TaxonRelationship> toRelationships = service.listToTaxonRelationships(taxon, null, null, null, null, TAXONRELATIONSHIP_INIT_STRATEGY);\r
+        List<TaxonRelationship> fromRelationships = service.listFromTaxonRelationships(taxon, null, null, null, null, TAXONRELATIONSHIP_INIT_STRATEGY);\r
 \r
-        return relations;\r
+        List<TaxonRelationship> allRelationships = new ArrayList<TaxonRelationship>(toRelationships.size() + fromRelationships.size());\r
+        allRelationships.addAll(toRelationships);\r
+        allRelationships.addAll(fromRelationships);\r
+\r
+        return allRelationships;\r
     }\r
 \r
     /**\r
@@ -647,20 +739,91 @@ public class TaxonPortalController extends BaseController<TaxonBase, ITaxonServi
             method = RequestMethod.GET)\r
     public List<TaxonDescription> doGetDescriptions(\r
             @PathVariable("uuid") UUID uuid,\r
+            @RequestParam(value = "markerTypes", required = false) UuidList markerTypeUUIDs,\r
             HttpServletRequest request,\r
             HttpServletResponse response)throws IOException {\r
         if(request != null){\r
             logger.info("doGetDescriptions()" + request.getServletPath());\r
         }\r
+        List<DefinedTermBase> markerTypeTerms = null;\r
+        Set<UUID> sMarkerTypeUUIDs = null;\r
+\r
+        if(markerTypeUUIDs != null && !markerTypeUUIDs.isEmpty()){\r
+            sMarkerTypeUUIDs = new HashSet<UUID>(markerTypeUUIDs);\r
+            markerTypeTerms = markerTypeService.find(sMarkerTypeUUIDs);\r
+        } else if(markerTypeUUIDs != null && markerTypeUUIDs.isEmpty()){\r
+            markerTypeTerms = new ArrayList<DefinedTermBase>();\r
+        }\r
+        Set<MarkerType> markerTypes = new HashSet<MarkerType>();\r
+        List<TaxonDescription> descriptions = new ArrayList<TaxonDescription>();\r
+        if (markerTypeTerms != null) {\r
+            for (DefinedTermBase markerTypeTerm : markerTypeTerms) {\r
+                markerTypes.add((MarkerType)markerTypeTerm);\r
+            }\r
+        }\r
         Taxon t = getCdmBaseInstance(Taxon.class, uuid, response, (List<String>)null);\r
-        Pager<TaxonDescription> p = descriptionService.getTaxonDescriptions(t, null, null, null, null, TAXONDESCRIPTION_INIT_STRATEGY);\r
-        return p.getRecords();\r
+        if (markerTypeTerms == null) {\r
+\r
+            Pager<TaxonDescription> p = descriptionService.getTaxonDescriptions(t, null, null, null, null, TAXONDESCRIPTION_INIT_STRATEGY);\r
+            descriptions = p.getRecords();\r
+        }\r
+\r
+        else if (markerTypeTerms != null && markerTypeTerms.isEmpty()) {\r
+            descriptions = descriptionService.listTaxonDescriptions(t, null, null, markerTypes, null, null, TAXONUSEDESCRIPTION_INIT_STRATEGY);\r
+\r
+        }\r
+        else {\r
+            descriptions = descriptionService.listTaxonDescriptions(t, null, null, markerTypes, null, null, TAXONUSEDESCRIPTION_INIT_STRATEGY);\r
+            /*for (TaxonDescription description: descriptions) {\r
+                for (IdentifiableSource source :description.getSources()) {\r
+                    if (source.getOriginalNameString() != null) {\r
+                        description.\r
+                    }\r
+\r
+                }\r
+\r
+\r
+            }*/\r
+        }\r
+        return descriptions;\r
+    }\r
+\r
+    @RequestMapping(value = "useDescriptions", method = RequestMethod.GET)\r
+    public List<TaxonDescription> doGetUseDescriptions(\r
+            @PathVariable("uuid") UUID uuid,\r
+            HttpServletRequest request,\r
+            HttpServletResponse response) throws IOException {\r
+        logger.info("doGetDescriptionElements() - " + request.getServletPath());\r
+\r
+        //ModelAndView mv = new ModelAndView();\r
+        Taxon t = getCdmBaseInstance(Taxon.class, uuid, response, (List<String>)null);\r
+\r
+       //MarkerType useMarkerType = (MarkerType) markerTypeService.find(UUID.fromString("2e6e42d9-e92a-41f4-899b-03c0ac64f059"));\r
+        MarkerType useMarkerType = (MarkerType) markerTypeService.find(UUID.fromString("2e6e42d9-e92a-41f4-899b-03c0ac64f039"));\r
+\r
+       //find(UUID.fromString("2e6e42d9-e92a-41f4-899b-03c0ac64f059"));\r
+       Set<MarkerType> markerTypes =  new HashSet<MarkerType>();\r
+       markerTypes.add(useMarkerType);\r
+       List<TaxonDescription> descriptionElements = descriptionService.listTaxonDescriptions(t, null, null, markerTypes, null, null, TAXONUSEDESCRIPTION_INIT_STRATEGY);\r
+        //getDescriptionElements(description, features, type, pageSize, pageNumber, propertyPaths)  load(uuid);\r
+\r
+        /*if(!(description instanceof TaxonDescription)){\r
+            HttpStatusMessage.UUID_REFERENCES_WRONG_TYPE.send(response);\r
+            // will terminate thread\r
+        }*/\r
+\r
+        //boolean hasStructuredData = service.        hasStructuredData(description);\r
+\r
+        //mv.addObject(hasStructuredData);\r
+\r
+        return descriptionElements;\r
     }\r
 \r
     @RequestMapping(value = "descriptions/elementsByType/{classSimpleName}", method = RequestMethod.GET)\r
     public ModelAndView doGetDescriptionElementsByType(\r
             @PathVariable("uuid") UUID uuid,\r
             @PathVariable("classSimpleName") String classSimpleName,\r
+            @RequestParam(value = "markerTypes", required = false) UuidList markerTypeUUIDs,\r
             @RequestParam(value = "count", required = false, defaultValue = "false") Boolean doCount,\r
             HttpServletRequest request,\r
             HttpServletResponse response) throws IOException {\r
@@ -674,7 +837,7 @@ public class TaxonPortalController extends BaseController<TaxonBase, ITaxonServi
 \r
         List<String> initStrategy = doCount ? null : DESCRIPTION_ELEMENT_INIT_STRATEGY;\r
 \r
-        List<TaxonDescription> taxonDescriptions = doGetDescriptions(uuid, request, response);\r
+        List<TaxonDescription> taxonDescriptions = doGetDescriptions(uuid, markerTypeUUIDs, request, response);\r
         try {\r
             Class type;\r
             type = Class.forName("eu.etaxonomy.cdm.model.description."\r
@@ -820,17 +983,28 @@ public class TaxonPortalController extends BaseController<TaxonBase, ITaxonServi
         // collect all media of the given taxon\r
         boolean limitToGalleries = false;\r
         List<Media> taxonMedia = new ArrayList<Media>();\r
+        List<Media> taxonGalleryMedia = new ArrayList<Media>();\r
         for(TaxonDescription desc : p.getRecords()){\r
-            if(!limitToGalleries || desc.isImageGallery()){\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
-        List<Media> returnMedia = MediaUtils.findPreferredMedia(taxonMedia, type,\r
+        taxonGalleryMedia.addAll(taxonMedia);\r
+\r
+        List<Media> returnMedia = MediaUtils.findPreferredMedia(taxonGalleryMedia, type,\r
                 mimeTypes, null, widthOrDuration, height, size);\r
 \r
         return returnMedia;\r