removing init strategies which are replaces by MediaAutoInitializer
[cdmlib.git] / cdmlib-remote / src / main / java / eu / etaxonomy / cdm / remote / controller / TaxonPortalController.java
index 5ca0cba071435098f74f638a8f5ad5e419f0f5bd..926fadfaaf141d40e5381c890076cf79723fa5e0 100644 (file)
 // $Id: TaxonController.java 5473 2009-03-25 13:42:07Z a.kohlbecker $\r
 /**\r
 * Copyright (C) 2007 EDIT\r
-* European Distributed Institute of Taxonomy \r
+* European Distributed Institute of Taxonomy\r
 * http://www.e-taxonomy.eu\r
-* \r
+*\r
 * The contents of this file are subject to the Mozilla Public License Version 1.1\r
 * See LICENSE.TXT at the top of this package for the full license terms.\r
 */\r
 \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
+import java.util.HashSet;\r
 import java.util.Hashtable;\r
+import java.util.Iterator;\r
 import java.util.List;\r
 import java.util.Map;\r
+import java.util.Set;\r
 import java.util.UUID;\r
 \r
 import javax.servlet.http.HttpServletRequest;\r
 import javax.servlet.http.HttpServletResponse;\r
 \r
+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
 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 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.IReferenceService;\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.config.ITaxonServiceConfigurator;\r
-import eu.etaxonomy.cdm.api.service.config.impl.TaxonServiceConfiguratorImpl;\r
+import eu.etaxonomy.cdm.api.service.IClassificationService;\r
+import eu.etaxonomy.cdm.api.service.ITermService;\r
+import eu.etaxonomy.cdm.api.service.config.IFindTaxaAndNamesConfigurator;\r
+import eu.etaxonomy.cdm.api.service.config.FindTaxaAndNamesConfiguratorImpl;\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.Feature;\r
 import eu.etaxonomy.cdm.model.description.TaxonDescription;\r
-import eu.etaxonomy.cdm.model.description.TaxonNameDescription;\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.MediaRepresentation;\r
+import eu.etaxonomy.cdm.model.media.MediaRepresentationPart;\r
+import eu.etaxonomy.cdm.model.media.MediaUtils;\r
 import eu.etaxonomy.cdm.model.name.NameRelationship;\r
-import eu.etaxonomy.cdm.model.name.TaxonNameBase;\r
 import eu.etaxonomy.cdm.model.name.TypeDesignationBase;\r
-import eu.etaxonomy.cdm.model.reference.ReferenceBase;\r
+import eu.etaxonomy.cdm.model.taxon.Synonym;\r
 import eu.etaxonomy.cdm.model.taxon.Taxon;\r
 import eu.etaxonomy.cdm.model.taxon.TaxonBase;\r
+import eu.etaxonomy.cdm.model.taxon.TaxonNode;\r
 import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;\r
 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.remote.editor.UUIDPropertyEditor;\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
+ * <p>\r
+ * The syntax of the mapped service URIs contains the the {datasource-name} path element.\r
+ * The available {datasource-name}s are defined in a configuration file which\r
+ * is loaded by the {@link UpdatableRoutingDataSource}. If the\r
+ * UpdatableRoutingDataSource is not being used in the actual application\r
+ * context any arbitrary {datasource-name} may be used.\r
+ * <p>\r
+ * Methods mapped at type level, inherited from super classes ({@link BaseController}):\r
+ * <blockquote>\r
+ * URI: <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}</b>\r
+ *\r
+ * Get the {@link TaxonBase} instance identified by the <code>{taxon-uuid}</code>.\r
+ * The returned Taxon is initialized by\r
+ * the following strategy {@link #TAXON_INIT_STRATEGY}\r
+ * </blockquote>\r
+ *\r
  * @author a.kohlbecker\r
+ * @date 20.07.2009\r
  *\r
  */\r
-\r
 @Controller\r
-@RequestMapping(value = {"/*/portal/taxon/*", "/*/portal/taxon/*/*", "/*/portal/name/*/*"})\r
+@RequestMapping(value = {"/portal/taxon/{uuid}"})\r
 public class TaxonPortalController extends BaseController<TaxonBase, ITaxonService>\r
 {\r
-       public static final Logger logger = Logger.getLogger(TaxonPortalController.class);\r
-       \r
-       @Autowired\r
-       private INameService nameService;\r
-       @Autowired\r
-       private IDescriptionService descriptionService;\r
-       @Autowired\r
-       private IReferenceService referenceService;\r
-       \r
-       \r
-       private static final List<String> TAXON_INIT_STRATEGY = Arrays.asList(new String []{\r
-                       "*",\r
-                       // taxon relations \r
-                       "relationsToThisName.fromTaxon.name.taggedName",\r
-                       // the name\r
-                       "name.$",\r
-                       "name.taggedName",\r
-                       "name.rank.representations",\r
-                       "name.status.type.representations",\r
-                       \r
-                       // taxon descriptions\r
-                       "descriptions.elements.$",\r
-                       "descriptions.elements.area",\r
-                       "descriptions.elements.area.$",\r
-                       "descriptions.elements.multilanguageText",\r
-                       "descriptions.elements.media.representations.parts",\r
-                       \r
-//                     // typeDesignations\r
-//                     "name.typeDesignations.$",\r
-//                     "name.typeDesignations.citation.authorTeam",\r
-//                     "name.typeDesignations.typeName.$",\r
-//                     "name.typeDesignations.typeStatus.representations",\r
-//                     "name.typeDesignations.typeSpecimen.media.representations.parts"\r
-                       \r
-                       });\r
-       \r
-       private static final List<String> SIMPLE_TAXON_INIT_STRATEGY = Arrays.asList(new String []{\r
-                       "*",\r
-                       // taxon relations \r
-                       "relationsToThisName.fromTaxon.name.taggedName",\r
-                       // the name\r
-                       "name.$",\r
-                       "name.taggedName",\r
-                       "name.rank.representations",\r
-                       "name.status.type.representations"\r
-                       });\r
-       \r
-       private static final List<String> SYNONYMY_INIT_STRATEGY = Arrays.asList(new String []{\r
-                       // initialize homotypical and heterotypical groups; needs synonyms\r
-                       "synonymRelations.$",\r
-                       "synonymRelations.synonym.$",\r
-                       "synonymRelations.synonym.name.taggedName",\r
-                       "synonymRelations.synonym.name.homotypicalGroup.typifiedNames.$",\r
-                       "synonymRelations.synonym.name.homotypicalGroup.typifiedNames.name.taggedName",\r
-                       "synonymRelations.synonym.name.homotypicalGroup.typifiedNames.taxonBases.$",\r
-                       "synonymRelations.synonym.name.homotypicalGroup.typifiedNames.taxonBases.name.taggedName",\r
-                       \r
-                       "name.homotypicalGroup.$",\r
-                       "name.homotypicalGroup.typifiedNames.$",\r
-                       "name.homotypicalGroup.typifiedNames.name.taggedName",\r
-                       "name.homotypicalGroup.typifiedNames.taxonBases.$",\r
-                       "name.homotypicalGroup.typifiedNames.taxonBases.name.taggedName"\r
-       });\r
-       \r
-       private static final List<String> TAXONRELATIONSHIP_INIT_STRATEGY = Arrays.asList(new String []{\r
-                       "$",\r
-                       "type.inverseRepresentations",\r
-                       "fromTaxon.sec.authorTeam",\r
-                       "fromTaxon.name.taggedName"\r
-       });\r
-       \r
-       private static final List<String> NAMERELATIONSHIP_INIT_STRATEGY = Arrays.asList(new String []{\r
-                       "$",\r
-                       "type.inverseRepresentations",\r
-                       "fromName.taggedName",\r
-       });\r
-       \r
-       \r
-       protected static final List<String> TAXONDESCRIPTION_INIT_STRATEGY = Arrays.asList(new String []{\r
-                       "$",\r
-                       "elements.$",\r
-                       "elements.citation.authorTeam",\r
-                       "elements.multilanguageText",\r
-                       "elements.media.representations.parts",\r
-       });\r
-       \r
-       private static final List<String> NAMEDESCRIPTION_INIT_STRATEGY = Arrays.asList(new String []{\r
-                       "uuid",\r
-                       "feature",\r
-                       \r
-                       "elements.$",\r
-                       "elements.multilanguageText",\r
-                       "elements.media.representations.parts",\r
-       });\r
-       \r
-       private static final List<String> TYPEDESIGNATION_INIT_STRATEGY = Arrays.asList(new String []{\r
-                       //"$",\r
-                       "typeSpecimen.$",\r
-                       "typeStatus.representations",\r
-                       "citation.authorTeam",\r
-                       "typeName.taggedName"\r
-       });\r
-       \r
-       \r
-       \r
-       private static final String featureTreeUuidPattern = "^/(?:[^/]+)/taxon(?:(?:/)([^/?#&\\.]+))+.*";\r
-       \r
-       public TaxonPortalController(){\r
-               super();\r
-               setUuidParameterPattern("^/(?:[^/]+)/portal/(?:[^/]+)/([^/?#&\\.]+).*");\r
-       }\r
-       \r
-       /* (non-Javadoc)\r
-        * @see eu.etaxonomy.cdm.remote.controller.GenericController#setService(eu.etaxonomy.cdm.api.service.IService)\r
-        */\r
-       @Autowired\r
-       @Override\r
-       public void setService(ITaxonService service) {\r
-               this.service = service;\r
-       }\r
-       \r
-       @InitBinder\r
+    public static final Logger logger = Logger.getLogger(TaxonPortalController.class);\r
+\r
+    @Autowired\r
+    private INameService nameService;\r
+\r
+    @Autowired\r
+    private IDescriptionService descriptionService;\r
+\r
+    @Autowired\r
+    private IOccurrenceService occurrenceService;\r
+\r
+    @Autowired\r
+    private IClassificationService classificationService;\r
+\r
+    @Autowired\r
+    private ITaxonService taxonService;\r
+\r
+    @Autowired\r
+    private ITermService termService;\r
+\r
+    @Autowired\r
+    private IFeatureTreeService featureTreeService;\r
+\r
+    private static final List<String> TAXON_INIT_STRATEGY = Arrays.asList(new String []{\r
+            "*",\r
+            // taxon relations\r
+            "relationsToThisName.fromTaxon.name",\r
+            // the name\r
+            "name.$",\r
+            "name.rank.representations",\r
+            "name.status.type.representations",\r
+\r
+            // taxon descriptions\r
+            "descriptions.elements.area.$",\r
+            "descriptions.elements.multilanguageText",\r
+            "descriptions.elements.media",\r
+\r
+            });\r
+\r
+    private static final List<String> TAXON_WITH_NODES_INIT_STRATEGY = Arrays.asList(new String []{\r
+            "taxonNodes.$",\r
+            "taxonNodes.classification.$",\r
+            "taxonNodes.childNodes.$"\r
+            });\r
+\r
+    private static final List<String> SIMPLE_TAXON_INIT_STRATEGY = Arrays.asList(new String []{\r
+            "*",\r
+            // taxon relations\r
+            "relationsToThisName.fromTaxon.name",\r
+            // the name\r
+            "name.$",\r
+            "name.rank.representations",\r
+            "name.status.type.representations",\r
+            "name.nomenclaturalReference"\r
+            });\r
+\r
+    private static final List<String> SYNONYMY_INIT_STRATEGY = Arrays.asList(new String []{\r
+            // initialize homotypical and heterotypical groups; needs synonyms\r
+            "synonymRelations.$",\r
+            "synonymRelations.synonym.$",\r
+            "synonymRelations.synonym.name.status.type.representation",\r
+            "synonymRelations.synonym.name.nomenclaturalReference.inReference",\r
+            "synonymRelations.synonym.name.homotypicalGroup.typifiedNames.$",\r
+            "synonymRelations.synonym.name.homotypicalGroup.typifiedNames.taxonBases.$",\r
+            "synonymRelations.synonym.name.combinationAuthorTeam.$",\r
+\r
+            "name.typeDesignations",\r
+\r
+            "name.homotypicalGroup.$",\r
+            "name.homotypicalGroup.typifiedNames.$",\r
+            "name.homotypicalGroup.typifiedNames.nomenclaturalReference.authorTeam",\r
+\r
+            "name.homotypicalGroup.typifiedNames.taxonBases.$"\r
+    });\r
+\r
+    private static final List<String> SYNONYMY_WITH_NODES_INIT_STRATEGY = Arrays.asList(new String []{\r
+            // initialize homotypical and heterotypical groups; needs synonyms\r
+            "synonymRelations.$",\r
+            "synonymRelations.synonym.$",\r
+            "synonymRelations.synonym.name.status.type.representation",\r
+            "synonymRelations.synonym.name.nomenclaturalReference.inReference",\r
+            "synonymRelations.synonym.name.homotypicalGroup.typifiedNames.$",\r
+            "synonymRelations.synonym.name.homotypicalGroup.typifiedNames.taxonBases.$",\r
+            "synonymRelations.synonym.name.combinationAuthorTeam.$",\r
+\r
+            "name.homotypicalGroup.$",\r
+            "name.homotypicalGroup.typifiedNames.$",\r
+            "name.homotypicalGroup.typifiedNames.nomenclaturalReference.authorTeam",\r
+\r
+            "name.homotypicalGroup.typifiedNames.taxonBases.$",\r
+\r
+            "taxonNodes.$",\r
+            "taxonNodes.classification.$",\r
+            "taxonNodes.childNodes.$"\r
+    });\r
+    private static final List<String> SIMPLE_TAXON_WITH_NODES_INIT_STRATEGY = Arrays.asList(new String []{\r
+            "*",\r
+            // taxon relations\r
+            "relationsToThisName.fromTaxon.name",\r
+            // the name\r
+            "name.$",\r
+            "name.rank.representations",\r
+            "name.status.type.representations",\r
+            "name.nomenclaturalReference",\r
+\r
+            "taxonNodes.$",\r
+            "taxonNodes.classification.$",\r
+            "taxonNodes.childNodes.$"\r
+            });\r
+\r
+\r
+    private static final List<String> TAXONRELATIONSHIP_INIT_STRATEGY = Arrays.asList(new String []{\r
+            "$",\r
+            "type.inverseRepresentations",\r
+            "fromTaxon.sec",\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
+            "$",\r
+            "type.inverseRepresentations",\r
+            "fromName",\r
+            "toName.$",\r
+    });\r
+\r
+\r
+    protected static final List<String> TAXONDESCRIPTION_INIT_STRATEGY = Arrays.asList(new String []{\r
+            "$",\r
+            "elements.$",\r
+            "elements.sources.citation.authorTeam",\r
+            "elements.sources.nameUsedInSource.originalNameString",\r
+            "elements.multilanguageText",\r
+            "elements.media",\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",\r
+    });\r
+\r
+    protected static final List<String> DESCRIPTION_ELEMENT_INIT_STRATEGY = Arrays.asList(new String []{\r
+            "$",\r
+            "sources.citation.authorTeam",\r
+            "sources.nameUsedInSource.originalNameString",\r
+            "multilanguageText",\r
+            "media",\r
+    });\r
+\r
+\r
+//     private static final List<String> NAMEDESCRIPTION_INIT_STRATEGY = Arrays.asList(new String []{\r
+//                     "uuid",\r
+//                     "feature",\r
+//                     "elements.$",\r
+//                     "elements.multilanguageText",\r
+//                     "elements.media",\r
+//     });\r
+\r
+    protected static final List<String> TAXONDESCRIPTION_MEDIA_INIT_STRATEGY = Arrays.asList(new String []{\r
+            "elements.media"\r
+\r
+    });\r
+\r
+    private static final List<String> TYPEDESIGNATION_INIT_STRATEGY = Arrays.asList(new String []{\r
+            "typeSpecimen.$",\r
+            "citation.authorTeam.$",\r
+            "typeName",\r
+            "typeStatus"\r
+    });\r
+\r
+    protected static final List<String> TAXONNODE_WITHTAXON_INIT_STRATEGY = Arrays.asList(new String []{\r
+            "childNodes.taxon",\r
+    });\r
+\r
+    protected static final List<String> TAXONNODE_INIT_STRATEGY = Arrays.asList(new String []{\r
+            "taxonNodes.classification"\r
+    });\r
+\r
+\r
+\r
+    private static final String featureTreeUuidPattern = "^/taxon(?:(?:/)([^/?#&\\.]+))+.*";\r
+\r
+    public TaxonPortalController(){\r
+        super();\r
+        setInitializationStrategy(TAXON_INIT_STRATEGY);\r
+    }\r
+\r
+    /* (non-Javadoc)\r
+     * @see eu.etaxonomy.cdm.remote.controller.GenericController#setService(eu.etaxonomy.cdm.api.service.IService)\r
+     */\r
+    @Autowired\r
+    @Override\r
+    public void setService(ITaxonService service) {\r
+        this.service = service;\r
+    }\r
+\r
+    @InitBinder\r
+    @Override\r
     public void initBinder(WebDataBinder binder) {\r
-               binder.registerCustomEditor(UUID.class, new UUIDPropertyEditor());\r
-       }\r
-       \r
-       \r
-       @Override\r
-       @RequestMapping(method = RequestMethod.GET)\r
-       public TaxonBase doGet(HttpServletRequest request, HttpServletResponse response)throws IOException {\r
-               TaxonBase tb = getCdmBase(request, response, TAXON_INIT_STRATEGY, TaxonBase.class);\r
-               return tb;\r
-       }\r
-       \r
-       @RequestMapping(method = RequestMethod.GET,\r
-                       value = {"/*/portal/taxon/find"}) //TODO map to path /*/portal/taxon/ \r
-       public Pager<IdentifiableEntity> doFind(\r
-                       @RequestParam(value = "q", required = false) String query,\r
-                       @RequestParam(value = "page", required = false) Integer page,\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 = "doTaxaByCommonNames", required = false) Boolean doTaxaByCommonNames,\r
-                       @RequestParam(value = "secUuid", required = false) UUID secUuid) throws IOException {\r
-               \r
-               if(page == null){ page = BaseListController.DEFAULT_PAGE;}\r
-               if(pageSize == null){ pageSize = BaseListController.DEFAULT_PAGESIZE;}\r
-                       \r
-               ITaxonServiceConfigurator config = new TaxonServiceConfiguratorImpl();\r
-               config.setPageNumber(page);\r
-               config.setPageSize(pageSize);\r
-               config.setSearchString(query);\r
-               config.setDoTaxa(doTaxa!= null ? doTaxa : Boolean.FALSE );\r
-               config.setDoSynonyms(doSynonyms != null ? doSynonyms : Boolean.FALSE );\r
-               config.setDoTaxaByCommonNames(doTaxaByCommonNames != null ? doTaxaByCommonNames : Boolean.FALSE );\r
-               config.setMatchMode(MatchMode.BEGINNING);\r
-               config.setTaxonPropertyPath(SIMPLE_TAXON_INIT_STRATEGY);\r
-               if(secUuid != null){\r
-                       ReferenceBase sec = referenceService.findByUuid(secUuid);\r
-                       config.setSec(sec);\r
-               }\r
-                       \r
-               return (Pager<IdentifiableEntity>) service.findTaxaAndNames(config);\r
-       }\r
-\r
-       \r
-       @RequestMapping(\r
-                       value = {"/*/portal/taxon/*/synonymy"},\r
-                       method = RequestMethod.GET)\r
-       public ModelAndView doGetSynonymy(HttpServletRequest request, HttpServletResponse response)throws IOException {\r
-               ModelAndView mv = new ModelAndView();\r
-               TaxonBase tb = getCdmBase(request, response, null, Taxon.class);\r
-               Taxon taxon = (Taxon)tb;\r
-               Map<String, List<?>> synonymy = new Hashtable<String, List<?>>();\r
-               synonymy.put("homotypicSynonymsByHomotypicGroup", service.getHomotypicSynonymsByHomotypicGroup(taxon, SYNONYMY_INIT_STRATEGY));\r
-               synonymy.put("heterotypicSynonymyGroups", service.getHeterotypicSynonymyGroups(taxon, SYNONYMY_INIT_STRATEGY));\r
-               mv.addObject(synonymy);\r
-               return mv;\r
-       }\r
-       \r
-       @RequestMapping(\r
-                       value = {"/*/portal/taxon/*/taxonRelationships"},\r
-                       method = RequestMethod.GET)\r
-       public List<TaxonRelationship> doGetTaxonRelations(HttpServletRequest request, HttpServletResponse response)throws IOException {\r
-\r
-               TaxonBase tb = getCdmBase(request, response, null, Taxon.class);\r
-               Taxon taxon = (Taxon)tb;\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
-\r
-               return relations;\r
-       }\r
-       \r
-       @RequestMapping(\r
-                       value = {"/*/portal/taxon/*/nameRelationships"},\r
-                       method = RequestMethod.GET)\r
-       public List<NameRelationship> doGetNameRelations(HttpServletRequest request, HttpServletResponse response)throws IOException {\r
-               TaxonBase tb = getCdmBase(request, response, SIMPLE_TAXON_INIT_STRATEGY, Taxon.class);\r
-               List<NameRelationship> list = nameService.listToNameRelationships(tb.getName(), null, null, null, null, NAMERELATIONSHIP_INIT_STRATEGY);\r
-               return list;\r
-       }\r
-       \r
-       @RequestMapping(\r
-                       value = {"/*/portal/name/*/descriptions"},\r
-                       method = RequestMethod.GET)\r
-       public List<TaxonNameDescription> doGetNameDescriptions(HttpServletRequest request, HttpServletResponse response)throws IOException {\r
-               UUID nameUuuid = readValueUuid(request, null);\r
-               TaxonNameBase tnb = nameService.load(nameUuuid, null);\r
-               Pager<TaxonNameDescription> p = descriptionService.getTaxonNameDescriptions(tnb, null, null, NAMEDESCRIPTION_INIT_STRATEGY);\r
-               return p.getRecords();\r
-       }\r
-       \r
-       @RequestMapping(\r
-                       value = {"/*/portal/taxon/*/nameTypeDesignations"},\r
-                       method = RequestMethod.GET)\r
-       public List<TypeDesignationBase> doGetNameTypeDesignations(HttpServletRequest request, HttpServletResponse response)throws IOException {\r
-               TaxonBase tb = getCdmBase(request, response, SIMPLE_TAXON_INIT_STRATEGY, Taxon.class);\r
-               Pager<TypeDesignationBase> p = nameService.getTypeDesignations(tb.getName(), null, null, null, TYPEDESIGNATION_INIT_STRATEGY);\r
-               return p.getRecords();\r
-       }\r
-       \r
-       @RequestMapping(\r
-                       value = {"/*/portal/taxon/*/descriptions"},\r
-                       method = RequestMethod.GET)\r
-       public List<TaxonDescription> doGetDescriptions(HttpServletRequest request, HttpServletResponse response)throws IOException {\r
-               TaxonBase tb = getCdmBase(request, response, null, Taxon.class);\r
-               if(tb instanceof Taxon){\r
-               Pager<TaxonDescription> p = descriptionService.getTaxonDescriptions((Taxon)tb, null, null, null, null, TAXONDESCRIPTION_INIT_STRATEGY);\r
-                       return p.getRecords();\r
-               } else {\r
-                       response.sendError(HttpServletResponse.SC_NOT_FOUND, "invalid type; Taxon expected but " + tb.getClass().getSimpleName() + " found.");\r
-                       return null;\r
-               }\r
-       }\r
-       \r
+        super.initBinder(binder);\r
+        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
+    /* (non-Javadoc)\r
+     * @see eu.etaxonomy.cdm.remote.controller.BaseController#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)\r
+\r
+    @Override\r
+    @RequestMapping(method = RequestMethod.GET)\r
+    public TaxonBase doGet(HttpServletRequest request, HttpServletResponse response)throws IOException {\r
+        logger.info("doGet()");\r
+        TaxonBase tb = getCdmBase(request, response, TAXON_INIT_STRATEGY, TaxonBase.class);\r
+        return tb;\r
+    }\r
+     */\r
+    /**\r
+     * Find Taxa, Synonyms, Common Names by name, either globally or in a specific geographic area.\r
+     * <p>\r
+     * URI: <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;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
+     * @param matchMode\r
+     *           valid values are "EXACT", "BEGINNING", "ANYWHERE", "END" (case sensitive !!!)\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
+     */\r
+    @RequestMapping(method = RequestMethod.GET,\r
+            value = {"/portal/taxon/find"}) //TODO map to path /*/portal/taxon/\r
+    public Pager<IdentifiableEntity> doFind(\r
+            @RequestParam(value = "query", required = false) String query,\r
+            @RequestParam(value = "tree", required = false) UUID treeUuid,\r
+            @RequestParam(value = "area", required = false) Set<NamedArea> areas,\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
+            @RequestParam(value = "matchMode", required = false) MatchMode matchMode,\r
+            HttpServletRequest request,\r
+            HttpServletResponse response\r
+            )\r
+             throws IOException {\r
+\r
+        logger.info("doFind : " + request.getRequestURI() + "?" + request.getQueryString() );\r
+\r
+        PagerParameters pagerParams = new PagerParameters(pageSize, pageNumber);\r
+        pagerParams.normalizeAndValidate(response);\r
+\r
+        IFindTaxaAndNamesConfigurator config = new FindTaxaAndNamesConfiguratorImpl();\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
+        config.setNamedAreas(areas);\r
+        if(treeUuid != null){\r
+            Classification classification = classificationService.find(treeUuid);\r
+            config.setClassification(classification);\r
+        }\r
+\r
+        return (Pager<IdentifiableEntity>) service.findTaxaAndNames(config);\r
+    }\r
+\r
+    /**\r
+     * @param clazz\r
+     * @param queryString\r
+     * @param treeUuid\r
+     * @param languages\r
+     * @param features one or more feature uuids\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 = "features", required = false) UuidList featureUuids,\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
+\r
+        List<Feature> features = null;\r
+        if(featureUuids != null){\r
+            features = new ArrayList<Feature>(featureUuids.size());\r
+            for(UUID uuid : featureUuids){\r
+                features.add((Feature) termService.find(uuid));\r
+            }\r
+        }\r
+\r
+        Pager<SearchResult<TaxonBase>> pager = service.findByDescriptionElementFullText(clazz, queryString, classification, features, 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
+     * of two parts: The group of homotypic synonyms of the taxon and the\r
+     * heterotypic synonymy groups of the taxon. The synonymy is ordered\r
+     * historically by the type designations and by the publication date of the\r
+     * nomenclatural reference\r
+     * <p>\r
+     * URI:\r
+     * <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}&#x002F;synonymy</b>\r
+     *\r
+     *\r
+     * @param request\r
+     * @param response\r
+     * @return a Map with to entries which are mapped by the following keys:\r
+     *         "homotypicSynonymsByHomotypicGroup", "heterotypicSynonymyGroups",\r
+     *         containing lists of {@link Synonym}s which are initialized using the\r
+     *         following initialization strategy: {@link #SYNONYMY_INIT_STRATEGY}\r
+     *\r
+     * @throws IOException\r
+     */\r
+    @RequestMapping(\r
+            value = {"synonymy"},\r
+            method = RequestMethod.GET)\r
+    public ModelAndView doGetSynonymy(@PathVariable("uuid") UUID uuid,\r
+            HttpServletRequest request, HttpServletResponse response)throws IOException {\r
+\r
+        if(request != null){\r
+            logger.info("doGetSynonymy() " + request.getServletPath());\r
+        }\r
+        ModelAndView mv = new ModelAndView();\r
+        Taxon taxon = getCdmBaseInstance(Taxon.class, uuid, response, (List<String>)null);\r
+        Map<String, List<?>> synonymy = new Hashtable<String, List<?>>();\r
+        synonymy.put("homotypicSynonymsByHomotypicGroup", service.getHomotypicSynonymsByHomotypicGroup(taxon, SYNONYMY_INIT_STRATEGY));\r
+        synonymy.put("heterotypicSynonymyGroups", service.getHeterotypicSynonymyGroups(taxon, SYNONYMY_INIT_STRATEGY));\r
+        mv.addObject(synonymy);\r
+        return mv;\r
+    }\r
+\r
+    /**\r
+     * Get the set of accepted {@link Taxon} entities for a given\r
+     * {@link TaxonBase} entity identified by the <code>{taxon-uuid}</code>.\r
+     * <p>\r
+     * URI: <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}&#x002F;accepted</b>\r
+     *\r
+     * @param request\r
+     * @param response\r
+     * @return a Set of {@link Taxon} entities which are initialized\r
+     *         using the following initialization strategy:\r
+     *         {@link #SYNONYMY_INIT_STRATEGY}\r
+     * @throws IOException\r
+     */\r
+    @RequestMapping(value = "accepted/{classification_uuid}", method = RequestMethod.GET)\r
+    public Set<TaxonBase> getAccepted(\r
+                @PathVariable("uuid") UUID uuid,\r
+                @PathVariable("classification_uuid") UUID classification_uuid,\r
+                HttpServletRequest request,\r
+                HttpServletResponse response)\r
+                throws IOException {\r
+\r
+        if(request != null){\r
+            logger.info("getAccepted() " + request.getServletPath());\r
+        }\r
+\r
+        TaxonBase tb = service.load(uuid, SYNONYMY_WITH_NODES_INIT_STRATEGY);\r
+        if(tb == null){\r
+            response.sendError(HttpServletResponse.SC_NOT_FOUND, "A taxon with the uuid " + uuid + " does not exist");\r
+            return null;\r
+        }\r
+\r
+        HashSet<TaxonBase> resultset = new HashSet<TaxonBase>();\r
+\r
+        if (tb instanceof Taxon){\r
+            Taxon taxon = (Taxon) tb;\r
+            Set<TaxonNode> nodes = taxon.getTaxonNodes();\r
+            for (TaxonNode taxonNode : nodes) {\r
+                if (taxonNode.getClassification().compareTo(classification_uuid) == 0){\r
+                    resultset.add((Taxon) tb);\r
+                }\r
+            }\r
+            if (resultset.size() > 1){\r
+                //error!! A taxon is not allow to have more taxonnodes for a given classification\r
+                response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,\r
+                "A taxon with the uuid " + uuid + " has more than one taxon node for the given classification" + classification_uuid);\r
+            }\r
+        }else{\r
+            Synonym syn = (Synonym) tb;\r
+            for(TaxonBase accepted : syn.getAcceptedTaxa()){\r
+                tb = service.load(accepted.getUuid(), SIMPLE_TAXON_WITH_NODES_INIT_STRATEGY);\r
+                if (tb instanceof Taxon){\r
+                    Taxon taxon = (Taxon) tb;\r
+                    Set<TaxonNode> nodes = taxon.getTaxonNodes();\r
+                    for (TaxonNode taxonNode : nodes) {\r
+                        if (taxonNode.getClassification().compareTo(classification_uuid) == 0){\r
+                            resultset.add((Taxon) tb);\r
+                        }\r
+                    }\r
+                    if (resultset.size() > 1){\r
+                        //error!! A taxon is not allow to have more taxonnodes for a given classification\r
+                        response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,\r
+                        "A taxon with the uuid " + uuid + " has more than one taxon node for the given classification" + classification_uuid);\r
+                    }\r
+                }else{\r
+                    //ERROR!! perhaps missapplied name????\r
+                    //syn.getRelationType((Taxon)accepted);\r
+                }\r
+            }\r
+        }\r
+/**\r
+ * OLD CODE!!\r
+        if(tb instanceof Taxon){\r
+            //the taxon already is accepted\r
+            //FIXME take the current view into account once views are implemented!!!\r
+            resultset.add((Taxon)tb);\r
+        } else {\r
+            Synonym syn = (Synonym)tb;\r
+            for(TaxonBase accepted : syn.getAcceptedTaxa()){\r
+                accepted = service.load(accepted.getUuid(), SIMPLE_TAXON_INIT_STRATEGY);\r
+                resultset.add(accepted);\r
+            }\r
+        }\r
+*/\r
+        return resultset;\r
+    }\r
+\r
+    /**\r
+     * Get the list of {@link TaxonRelationship}s for the given\r
+     * {@link TaxonBase} instance identified by the <code>{taxon-uuid}</code>.\r
+     * <p>\r
+     * URI: <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}&#x002F;taxonRelationships</b>\r
+     *\r
+     * @param request\r
+     * @param response\r
+     * @return a List of {@link TaxonRelationship} entities which are initialized\r
+     *         using the following initialization strategy:\r
+     *         {@link #TAXONRELATIONSHIP_INIT_STRATEGY}\r
+     * @throws IOException\r
+     */\r
+    @RequestMapping(\r
+            value = {"taxonRelationships"},\r
+            method = RequestMethod.GET)\r
+    public List<TaxonRelationship> doGetTaxonRelations(@PathVariable("uuid") UUID uuid,\r
+            HttpServletRequest request, HttpServletResponse response)throws IOException {\r
+\r
+        logger.info("doGetTaxonRelations()" + request.getServletPath());\r
+        Taxon taxon = getCdmBaseInstance(Taxon.class, uuid, response, (List<String>)null);\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
+        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
+     * Get the list of {@link NameRelationship}s of the Name associated with the\r
+     * {@link TaxonBase} instance identified by the <code>{taxon-uuid}</code>.\r
+     * <p>\r
+     * URI: <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}&#x002F;nameRelationships</b>\r
+     *\r
+     * @param request\r
+     * @param response\r
+     * @return a List of {@link NameRelationship} entities which are initialized\r
+     *         using the following initialization strategy:\r
+     *         {@link #NAMERELATIONSHIP_INIT_STRATEGY}\r
+     * @throws IOException\r
+     */\r
+    @RequestMapping(\r
+            value = {"toNameRelationships"},\r
+            method = RequestMethod.GET)\r
+    public List<NameRelationship> doGetToNameRelations(@PathVariable("uuid") UUID uuid,\r
+            HttpServletRequest request, HttpServletResponse response)throws IOException {\r
+        logger.info("doGetNameRelations()" + request.getServletPath());\r
+        TaxonBase taxonBase = getCdmBaseInstance(TaxonBase.class, uuid, response, (List<String>)null);\r
+        List<NameRelationship> list = nameService.listNameRelationships(taxonBase.getName(), Direction.relatedTo, null, null, 0, null, NAMERELATIONSHIP_INIT_STRATEGY);\r
+        //List<NameRelationship> list = nameService.listToNameRelationships(taxonBase.getName(), null, null, null, null, NAMERELATIONSHIP_INIT_STRATEGY);\r
+        return list;\r
+    }\r
+\r
+    /**\r
+     * Get the list of {@link NameRelationship}s of the Name associated with the\r
+     * {@link TaxonBase} instance identified by the <code>{taxon-uuid}</code>.\r
+     * <p>\r
+     * URI: <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}&#x002F;nameRelationships</b>\r
+     *\r
+     * @param request\r
+     * @param response\r
+     * @return a List of {@link NameRelationship} entities which are initialized\r
+     *         using the following initialization strategy:\r
+     *         {@link #NAMERELATIONSHIP_INIT_STRATEGY}\r
+     * @throws IOException\r
+     */\r
+    @RequestMapping(\r
+            value = {"fromNameRelationships"},\r
+            method = RequestMethod.GET)\r
+    public List<NameRelationship> doGetFromNameRelations(@PathVariable("uuid") UUID uuid,\r
+            HttpServletRequest request, HttpServletResponse response)throws IOException {\r
+        logger.info("doGetNameFromNameRelations()" + request.getServletPath());\r
+\r
+        TaxonBase taxonbase = getCdmBaseInstance(TaxonBase.class, uuid, response, SIMPLE_TAXON_INIT_STRATEGY);\r
+        List<NameRelationship> list = nameService.listNameRelationships(taxonbase.getName(), Direction.relatedFrom, null, null, 0, null, NAMERELATIONSHIP_INIT_STRATEGY);\r
+        //List<NameRelationship> list = nameService.listFromNameRelationships(taxonbase.getName(), null, null, null, null, NAMERELATIONSHIP_INIT_STRATEGY);\r
+        return list;\r
+    }\r
+\r
+    /**\r
+     * Get the list of {@link TypeDesignationBase}s of the\r
+     * {@link TaxonBase} instance identified by the <code>{taxon-uuid}</code>.\r
+     * <p>\r
+     * URI: <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}&#x002F;nameTypeDesignations</b>\r
+     *\r
+     * @param request\r
+     * @param response\r
+     * @return a List of {@link TypeDesignationBase} entities which are initialized\r
+     *         using the following initialization strategy:\r
+     *         {@link #TYPEDESIGNATION_INIT_STRATEGY}\r
+     * @throws IOException\r
+     * @Deprecated use &#x002F;name&#x002F;{uuid}&#x002F;typeDesignations & &#x002F;derivedunitfacade&#x002F;{uuid} instead\r
+     * also see http://dev.e-taxonomy.eu/trac/ticket/2280\r
+     */\r
+    @Deprecated\r
+    @RequestMapping(\r
+            value = {"nameTypeDesignations"},\r
+            method = RequestMethod.GET)\r
+    public List<TypeDesignationBase> doGetNameTypeDesignations(@PathVariable("uuid") UUID uuid,\r
+            HttpServletRequest request, HttpServletResponse response)throws IOException {\r
+        logger.info("doGetNameTypeDesignations()" + request.getServletPath());\r
+        Taxon taxon = getCdmBaseInstance(Taxon.class, uuid, response, SIMPLE_TAXON_INIT_STRATEGY);\r
+        Pager<TypeDesignationBase> p = nameService.getTypeDesignations(taxon.getName(), null, null, null, TYPEDESIGNATION_INIT_STRATEGY);\r
+        return p.getRecords();\r
+    }\r
+\r
+    @RequestMapping(value = "taxonNodes", method = RequestMethod.GET)\r
+    public Set<TaxonNode>  doGetTaxonNodes(\r
+            @PathVariable("uuid") UUID uuid,\r
+            HttpServletRequest request,\r
+            HttpServletResponse response) throws IOException {\r
+        TaxonBase tb = service.load(uuid, TAXONNODE_INIT_STRATEGY);\r
+        if(tb instanceof Taxon){\r
+            return ((Taxon)tb).getTaxonNodes();\r
+        } else {\r
+            HttpStatusMessage.UUID_REFERENCES_WRONG_TYPE.send(response);\r
+            return null;\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Get the list of {@link TaxonDescription}s of the\r
+     * {@link Taxon} instance identified by the <code>{taxon-uuid}</code>.\r
+     * <p>\r
+     * URI: <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}&#x002F;descriptions</b>\r
+     *\r
+     * @param request\r
+     * @param response\r
+     * @return a List of {@link TaxonDescription} entities which are initialized\r
+     *         using the following initialization strategy:\r
+     *         {@link #TAXONDESCRIPTION_INIT_STRATEGY}\r
+     * @throws IOException\r
+     */\r
+    @RequestMapping(\r
+            value = {"descriptions"},\r
+            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 = termService.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
+        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) termService.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
+        logger.info("doGetDescriptionElementsByType() - " + request.getServletPath());\r
+\r
+        ModelAndView mv = new ModelAndView();\r
+\r
+        List<DescriptionElementBase> allElements = new ArrayList<DescriptionElementBase>();\r
+        List<DescriptionElementBase> elements;\r
+        int count = 0;\r
+\r
+        List<String> initStrategy = doCount ? null : DESCRIPTION_ELEMENT_INIT_STRATEGY;\r
+\r
+        List<TaxonDescription> taxonDescriptions = doGetDescriptions(uuid, markerTypeUUIDs, request, response);\r
+        try {\r
+            Class type;\r
+            type = Class.forName("eu.etaxonomy.cdm.model.description."\r
+                    + classSimpleName);\r
+            if (taxonDescriptions != null) {\r
+                for (TaxonDescription description : taxonDescriptions) {\r
+                    elements = descriptionService.listDescriptionElements(description, null, type, null, 0, initStrategy);\r
+                    allElements.addAll(elements);\r
+                    count += elements.size();\r
+                }\r
+\r
+            }\r
+        } catch (ClassNotFoundException e) {\r
+            HttpStatusMessage.fromString(e.getLocalizedMessage()).send(response);\r
+        }\r
+        if(doCount){\r
+            mv.addObject(count);\r
+        } else {\r
+            mv.addObject(allElements);\r
+        }\r
+        return mv;\r
+    }\r
+\r
+//     @RequestMapping(value = "specimens", method = RequestMethod.GET)\r
+//     public ModelAndView doGetSpecimens(\r
+//                     @PathVariable("uuid") UUID uuid,\r
+//                     HttpServletRequest request,\r
+//                     HttpServletResponse response) throws IOException, ClassNotFoundException {\r
+//             logger.info("doGetSpecimens() - " + request.getServletPath());\r
+//\r
+//             ModelAndView mv = new ModelAndView();\r
+//\r
+//             List<DerivedUnitFacade> derivedUnitFacadeList = new ArrayList<DerivedUnitFacade>();\r
+//\r
+//             // find speciemens in the TaxonDescriptions\r
+//             List<TaxonDescription> taxonDescriptions = doGetDescriptions(uuid, request, response);\r
+//             if (taxonDescriptions != null) {\r
+//\r
+//                     for (TaxonDescription description : taxonDescriptions) {\r
+//                             derivedUnitFacadeList.addAll( occurrenceService.listDerivedUnitFacades(description, null) );\r
+//                     }\r
+//             }\r
+//             // TODO find speciemens in the NameDescriptions ??\r
+//\r
+//             // TODO also find type specimens\r
+//\r
+//             mv.addObject(derivedUnitFacadeList);\r
+//\r
+//             return mv;\r
+//     }\r
+\r
+    /**\r
+     * Get the {@link Media} attached to the {@link Taxon} instance\r
+     * identified by the <code>{taxon-uuid}</code>.\r
+     *\r
+     * Usage &#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-\r
+     * uuid}&#x002F;media&#x002F;{mime type\r
+     * list}&#x002F;{size}[,[widthOrDuration}][,{height}]&#x002F;\r
+     *\r
+     * Whereas\r
+     * <ul>\r
+     * <li><b>{mime type list}</b>: a comma separated list of mime types, in the\r
+     * order of preference. The forward slashes contained in the mime types must\r
+     * be replaced by a colon. Regular expressions can be used. Each media\r
+     * associated with this given taxon is being searched whereas the first\r
+     * matching mime type matching a representation always rules.</li>\r
+     * <li><b>{size},{widthOrDuration},{height}</b>: <i>not jet implemented</i>\r
+     * valid values are an integer or the asterisk '*' as a wildcard</li>\r
+     * </ul>\r
+     *\r
+     * @param request\r
+     * @param response\r
+     * @return a List of {@link Media} entities which are initialized\r
+     *         using the following initialization strategy:\r
+     *         {@link #TAXONDESCRIPTION_INIT_STRATEGY}\r
+     * @throws IOException\r
+     */\r
+    @RequestMapping(\r
+        value = {"media"},\r
+        method = RequestMethod.GET)\r
+    public List<Media> doGetMedia(\r
+            @PathVariable("uuid") UUID uuid,\r
+            @RequestParam(value = "type", required = false) Class<? extends MediaRepresentationPart> type,\r
+            @RequestParam(value = "mimeTypes", required = false) String[] mimeTypes,\r
+            @RequestParam(value = "widthOrDuration", required = false) Integer  widthOrDuration,\r
+            @RequestParam(value = "height", required = false) Integer height,\r
+            @RequestParam(value = "size", required = false) Integer size,\r
+            HttpServletRequest request, HttpServletResponse response) throws IOException {\r
+\r
+        logger.info("doGetMedia()" + request.getServletPath());\r
+        Taxon t = getCdmBaseInstance(Taxon.class, uuid, response, (List<String>)null);\r
+        String path = request.getServletPath();\r
+        List<Media> returnMedia = getMediaForTaxon(t, type, mimeTypes, widthOrDuration, height, size);\r
+        return returnMedia;\r
+    }\r
+\r
+    @RequestMapping(\r
+            value = {"subtree/media"},\r
+            method = RequestMethod.GET)\r
+        public List<Media> doGetSubtreeMedia(\r
+                @PathVariable("uuid") UUID uuid,\r
+                @RequestParam(value = "type", required = false) Class<? extends MediaRepresentationPart> type,\r
+                @RequestParam(value = "mimeTypes", required = false) String[] mimeTypes,\r
+                @RequestParam(value = "widthOrDuration", required = false) Integer  widthOrDuration,\r
+                @RequestParam(value = "height", required = false) Integer height,\r
+                @RequestParam(value = "size", required = false) Integer size,\r
+                HttpServletRequest request, HttpServletResponse response)throws IOException {\r
+        logger.info("doGetMedia()" + request.getServletPath());\r
+        Taxon taxon = getCdmBaseInstance(Taxon.class, uuid, response, TAXON_WITH_NODES_INIT_STRATEGY);\r
+        String requestPath = request.getServletPath();\r
+        List<Media> returnMedia = getMediaForTaxon(taxon, type, mimeTypes, widthOrDuration, height, size);\r
+        TaxonNode node;\r
+        //looking for all medias of genus\r
+        if (taxon.getTaxonNodes().size()>0){\r
+            Set<TaxonNode> nodes = taxon.getTaxonNodes();\r
+            Iterator<TaxonNode> iterator = nodes.iterator();\r
+            //TaxonNode holen\r
+            node = iterator.next();\r
+            //Check if TaxonNode belongs to the current tree\r
+\r
+            node = classificationService.loadTaxonNode(node, TAXONNODE_WITHTAXON_INIT_STRATEGY);\r
+            Set<TaxonNode> children = node.getChildNodes();\r
+            Taxon childTaxon;\r
+            for (TaxonNode child : children){\r
+                childTaxon = child.getTaxon();\r
+                childTaxon = (Taxon)taxonService.load(childTaxon.getUuid(), null);\r
+                returnMedia.addAll(getMediaForTaxon(childTaxon, type, mimeTypes, widthOrDuration, height, size));\r
+            }\r
+        }\r
+        return returnMedia;\r
+    }\r
+\r
+\r
+    private List<Media> getMediaForTaxon(Taxon taxon, Class<? extends MediaRepresentationPart> type, String[] mimeTypes,\r
+            Integer widthOrDuration, Integer height, Integer size){\r
+\r
+        List<Media> taxonGalleryMedia = service.listTaxonDescriptionMedia(taxon, false, TAXONDESCRIPTION_MEDIA_INIT_STRATEGY);\r
+\r
+        Map<Media, MediaRepresentation> mediaRepresentationMap = MediaUtils.findPreferredMedia(taxonGalleryMedia, type,\r
+                mimeTypes, null, widthOrDuration, height, size);\r
+\r
+        List<Media> filteredMedia = new ArrayList<Media>(mediaRepresentationMap.size());\r
+        for(Media media : mediaRepresentationMap.keySet()){\r
+            media.getRepresentations().clear();\r
+            media.addRepresentation(mediaRepresentationMap.get(media));\r
+            filteredMedia.add(media);\r
+        }\r
+\r
+        return filteredMedia;\r
+    }\r
+\r
+\r
+// ---------------------- code snippet preserved for possible later use --------------------\r
 //     @RequestMapping(\r
 //                     value = {"/*/portal/taxon/*/descriptions"},\r
 //                     method = RequestMethod.GET)\r
 //     public List<TaxonDescription> doGetDescriptionsbyFeatureTree(HttpServletRequest request, HttpServletResponse response)throws IOException {\r
 //             TaxonBase tb = getCdmBase(request, response, null, Taxon.class);\r
 //             if(tb instanceof Taxon){\r
-//                     //TODO this is a quick and dirty implementation -> generalize\r
+//                     //T O D O this is a quick and dirty implementation -> generalize\r
 //                     UUID featureTreeUuid = readValueUuid(request, featureTreeUuidPattern);\r
-//                     \r
+//\r
 //                     FeatureTree featureTree = descriptionService.getFeatureTreeByUuid(featureTreeUuid);\r
 //                     Pager<TaxonDescription> p = descriptionService.getTaxonDescriptions((Taxon)tb, null, null, null, null, TAXONDESCRIPTION_INIT_STRATEGY);\r
 //                     List<TaxonDescription> descriptions = p.getRecords();\r
-//                     \r
+//\r
 //                     if(!featureTree.isDescriptionSeparated()){\r
-//                             \r
+//\r
 //                             TaxonDescription superDescription = TaxonDescription.NewInstance();\r
 //                             //put all descriptionElements in superDescription and make it invisible\r
 //                             for(TaxonDescription description: descriptions){\r