1 // $Id: TaxonController.java 5473 2009-03-25 13:42:07Z a.kohlbecker $
3 * Copyright (C) 2007 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
7 * The contents of this file are subject to the Mozilla Public License Version 1.1
8 * See LICENSE.TXT at the top of this package for the full license terms.
11 package eu
.etaxonomy
.cdm
.remote
.controller
;
13 import java
.io
.IOException
;
14 import java
.util
.ArrayList
;
15 import java
.util
.Arrays
;
16 import java
.util
.HashSet
;
17 import java
.util
.Hashtable
;
18 import java
.util
.Iterator
;
19 import java
.util
.List
;
22 import java
.util
.UUID
;
24 import javax
.servlet
.http
.HttpServletRequest
;
25 import javax
.servlet
.http
.HttpServletResponse
;
27 import org
.apache
.commons
.lang
.ObjectUtils
;
28 import org
.apache
.log4j
.Logger
;
29 import org
.springframework
.beans
.factory
.annotation
.Autowired
;
30 import org
.springframework
.stereotype
.Controller
;
31 import org
.springframework
.web
.bind
.WebDataBinder
;
32 import org
.springframework
.web
.bind
.annotation
.InitBinder
;
33 import org
.springframework
.web
.bind
.annotation
.PathVariable
;
34 import org
.springframework
.web
.bind
.annotation
.RequestMapping
;
35 import org
.springframework
.web
.bind
.annotation
.RequestMethod
;
36 import org
.springframework
.web
.bind
.annotation
.RequestParam
;
37 import org
.springframework
.web
.servlet
.ModelAndView
;
39 import eu
.etaxonomy
.cdm
.api
.service
.IDescriptionService
;
40 import eu
.etaxonomy
.cdm
.api
.service
.IFeatureTreeService
;
41 import eu
.etaxonomy
.cdm
.api
.service
.INameService
;
42 import eu
.etaxonomy
.cdm
.api
.service
.IOccurrenceService
;
43 import eu
.etaxonomy
.cdm
.api
.service
.ITaxonService
;
44 import eu
.etaxonomy
.cdm
.api
.service
.IClassificationService
;
45 import eu
.etaxonomy
.cdm
.api
.service
.config
.ITaxonServiceConfigurator
;
46 import eu
.etaxonomy
.cdm
.api
.service
.config
.impl
.TaxonServiceConfiguratorImpl
;
47 import eu
.etaxonomy
.cdm
.api
.service
.pager
.Pager
;
48 import eu
.etaxonomy
.cdm
.database
.UpdatableRoutingDataSource
;
49 import eu
.etaxonomy
.cdm
.model
.common
.IdentifiableEntity
;
50 import eu
.etaxonomy
.cdm
.model
.common
.RelationshipBase
.Direction
;
51 import eu
.etaxonomy
.cdm
.model
.description
.DescriptionElementBase
;
52 import eu
.etaxonomy
.cdm
.model
.description
.TaxonDescription
;
53 import eu
.etaxonomy
.cdm
.model
.location
.NamedArea
;
54 import eu
.etaxonomy
.cdm
.model
.media
.Media
;
55 import eu
.etaxonomy
.cdm
.model
.media
.MediaUtils
;
56 import eu
.etaxonomy
.cdm
.model
.name
.NameRelationship
;
57 import eu
.etaxonomy
.cdm
.model
.name
.TypeDesignationBase
;
58 import eu
.etaxonomy
.cdm
.model
.taxon
.Synonym
;
59 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
60 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonBase
;
61 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonNode
;
62 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonRelationship
;
63 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonRelationshipType
;
64 import eu
.etaxonomy
.cdm
.model
.taxon
.Classification
;
65 import eu
.etaxonomy
.cdm
.persistence
.query
.MatchMode
;
66 import eu
.etaxonomy
.cdm
.remote
.editor
.MatchModePropertyEditor
;
67 import eu
.etaxonomy
.cdm
.remote
.editor
.NamedAreaPropertyEditor
;
70 * The TaxonPortalController class is a Spring MVC Controller.
72 * The syntax of the mapped service URIs contains the the {datasource-name} path element.
73 * The available {datasource-name}s are defined in a configuration file which
74 * is loaded by the {@link UpdatableRoutingDataSource}. If the
75 * UpdatableRoutingDataSource is not being used in the actual application
76 * context any arbitrary {datasource-name} may be used.
78 * Methods mapped at type level, inherited from super classes ({@link BaseController}):
80 * URI: <b>/{datasource-name}/portal/taxon/{taxon-uuid}</b>
82 * Get the {@link TaxonBase} instance identified by the <code>{taxon-uuid}</code>.
83 * The returned Taxon is initialized by
84 * the following strategy {@link #TAXON_INIT_STRATEGY}
87 * @author a.kohlbecker
92 @RequestMapping(value
= {"/portal/taxon/{uuid}"})
93 public class TaxonPortalController
extends BaseController
<TaxonBase
, ITaxonService
>
95 public static final Logger logger
= Logger
.getLogger(TaxonPortalController
.class);
98 private INameService nameService
;
101 private IDescriptionService descriptionService
;
104 private IOccurrenceService occurrenceService
;
107 private IClassificationService classificationService
;
110 private ITaxonService taxonService
;
113 private IFeatureTreeService featureTreeService
;
115 private static final List
<String
> TAXON_INIT_STRATEGY
= Arrays
.asList(new String
[]{
118 "relationsToThisName.fromTaxon.name",
121 "name.rank.representations",
122 "name.status.type.representations",
124 // taxon descriptions
125 "descriptions.elements.area.$",
126 "descriptions.elements.multilanguageText",
127 "descriptions.elements.media.representations.parts",
128 "descriptions.elements.media.title",
132 private static final List
<String
> TAXON_WITH_NODES_INIT_STRATEGY
= Arrays
.asList(new String
[]{
134 "taxonNodes.classification.$",
135 "taxonNodes.childNodes.$"
138 private static final List
<String
> SIMPLE_TAXON_INIT_STRATEGY
= Arrays
.asList(new String
[]{
141 "relationsToThisName.fromTaxon.name",
144 "name.rank.representations",
145 "name.status.type.representations",
146 "name.nomenclaturalReference"
149 private static final List
<String
> SYNONYMY_INIT_STRATEGY
= Arrays
.asList(new String
[]{
150 // initialize homotypical and heterotypical groups; needs synonyms
151 "synonymRelations.$",
152 "synonymRelations.synonym.$",
153 "synonymRelations.synonym.name.status.type.representation",
154 "synonymRelations.synonym.name.nomenclaturalReference.inReference",
155 "synonymRelations.synonym.name.homotypicalGroup.typifiedNames.$",
156 "synonymRelations.synonym.name.homotypicalGroup.typifiedNames.taxonBases.$",
157 "synonymRelations.synonym.name.combinationAuthorTeam.$",
159 "name.homotypicalGroup.$",
160 "name.homotypicalGroup.typifiedNames.$",
161 "name.homotypicalGroup.typifiedNames.nomenclaturalReference.authorTeam",
163 "name.homotypicalGroup.typifiedNames.taxonBases.$"
166 private static final List
<String
> SYNONYMY_WITH_NODES_INIT_STRATEGY
= Arrays
.asList(new String
[]{
167 // initialize homotypical and heterotypical groups; needs synonyms
168 "synonymRelations.$",
169 "synonymRelations.synonym.$",
170 "synonymRelations.synonym.name.status.type.representation",
171 "synonymRelations.synonym.name.nomenclaturalReference.inReference",
172 "synonymRelations.synonym.name.homotypicalGroup.typifiedNames.$",
173 "synonymRelations.synonym.name.homotypicalGroup.typifiedNames.taxonBases.$",
174 "synonymRelations.synonym.name.combinationAuthorTeam.$",
176 "name.homotypicalGroup.$",
177 "name.homotypicalGroup.typifiedNames.$",
178 "name.homotypicalGroup.typifiedNames.nomenclaturalReference.authorTeam",
180 "name.homotypicalGroup.typifiedNames.taxonBases.$",
183 "taxonNodes.classification.$",
184 "taxonNodes.childNodes.$"
186 private static final List
<String
> SIMPLE_TAXON_WITH_NODES_INIT_STRATEGY
= Arrays
.asList(new String
[]{
189 "relationsToThisName.fromTaxon.name",
192 "name.rank.representations",
193 "name.status.type.representations",
194 "name.nomenclaturalReference",
197 "taxonNodes.classification.$",
198 "taxonNodes.childNodes.$"
202 private static final List
<String
> TAXONRELATIONSHIP_INIT_STRATEGY
= Arrays
.asList(new String
[]{
204 "type.inverseRepresentations",
209 private static final List
<String
> NAMERELATIONSHIP_INIT_STRATEGY
= Arrays
.asList(new String
[]{
211 "type.inverseRepresentations",
217 protected static final List
<String
> TAXONDESCRIPTION_INIT_STRATEGY
= Arrays
.asList(new String
[]{
220 "elements.sources.citation.authorTeam",
221 "elements.sources.nameUsedInSource.originalNameString",
222 "elements.multilanguageText",
223 "elements.media.representations.parts",
224 "elements.media.title",
227 protected static final List
<String
> DESCRIPTION_ELEMENT_INIT_STRATEGY
= Arrays
.asList(new String
[]{
229 "sources.citation.authorTeam",
230 "sources.nameUsedInSource.originalNameString",
232 "media.representations.parts",
237 // private static final List<String> NAMEDESCRIPTION_INIT_STRATEGY = Arrays.asList(new String []{
241 // "elements.multilanguageText",
242 // "elements.media.representations.parts",
243 // "elements.media.title",
246 protected static final List
<String
> TAXONDESCRIPTION_MEDIA_INIT_STRATEGY
= Arrays
.asList(new String
[]{
247 "elements.media.representations.parts",
248 "elements.media.title"
252 private static final List
<String
> TYPEDESIGNATION_INIT_STRATEGY
= Arrays
.asList(new String
[]{
255 "citation.authorTeam.$",
259 protected static final List
<String
> TAXONNODE_WITHTAXON_INIT_STRATEGY
= Arrays
.asList(new String
[]{
263 protected static final List
<String
> TAXONNODE_INIT_STRATEGY
= Arrays
.asList(new String
[]{
264 "taxonNodes.classification"
269 private static final String featureTreeUuidPattern
= "^/taxon(?:(?:/)([^/?#&\\.]+))+.*";
271 public TaxonPortalController(){
273 setInitializationStrategy(TAXON_INIT_STRATEGY
);
277 * @see eu.etaxonomy.cdm.remote.controller.GenericController#setService(eu.etaxonomy.cdm.api.service.IService)
281 public void setService(ITaxonService service
) {
282 this.service
= service
;
287 public void initBinder(WebDataBinder binder
) {
288 super.initBinder(binder
);
289 binder
.registerCustomEditor(NamedArea
.class, new NamedAreaPropertyEditor());
290 binder
.registerCustomEditor(MatchMode
.class, new MatchModePropertyEditor());
295 * @see eu.etaxonomy.cdm.remote.controller.BaseController#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
298 @RequestMapping(method = RequestMethod.GET)
299 public TaxonBase doGet(HttpServletRequest request, HttpServletResponse response)throws IOException {
300 logger.info("doGet()");
301 TaxonBase tb = getCdmBase(request, response, TAXON_INIT_STRATEGY, TaxonBase.class);
306 * Find Taxa, Synonyms, Common Names by name, either globally or in a specific geographic area.
308 * URI: <b>/{datasource-name}/portal/taxon/find</b>
311 * the string to query for. Since the wildcard character '*'
312 * internally always is appended to the query string, a search
313 * always compares the query string with the beginning of a name.
314 * - <i>required parameter</i>
316 * the {@link UUID} of a {@link Classification} to which the
317 * search is to be restricted. - <i>optional parameter</i>
319 * restrict the search to a set of geographic {@link NamedArea}s.
320 * The parameter currently takes a list of TDWG area labels.
321 * - <i>optional parameter</i>
323 * the number of the page to be returned, the first page has the
324 * pageNumber = 1 - <i>optional parameter</i>
326 * the maximum number of entities returned per page (can be -1
327 * to return all entities in a single page) - <i>optional parameter</i>
329 * weather to search for instances of {@link Taxon} - <i>optional parameter</i>
331 * weather to search for instances of {@link Synonym} - <i>optional parameter</i>
332 * @param doTaxaByCommonNames
333 * for instances of {@link Taxon} by a common name used - <i>optional parameter</i>
335 * valid values are "EXACT", "BEGINNING", "ANYWHERE", "END" (case sensitive !!!)
336 * @return a Pager on a list of {@link IdentifiableEntity}s initialized by
337 * the following strategy {@link #SIMPLE_TAXON_INIT_STRATEGY}
338 * @throws IOException
340 @RequestMapping(method
= RequestMethod
.GET
,
341 value
= {"/portal/taxon/find"}) //TODO map to path /*/portal/taxon/
342 public Pager
<IdentifiableEntity
> doFind(
343 @RequestParam(value
= "query", required
= false) String query
,
344 @RequestParam(value
= "tree", required
= false) UUID treeUuid
,
345 @RequestParam(value
= "area", required
= false) Set
<NamedArea
> areas
,
346 @RequestParam(value
= "page", required
= false) Integer page
,
347 @RequestParam(value
= "pageSize", required
= false) Integer pageSize
,
348 @RequestParam(value
= "doTaxa", required
= false) Boolean doTaxa
,
349 @RequestParam(value
= "doSynonyms", required
= false) Boolean doSynonyms
,
350 @RequestParam(value
= "doTaxaByCommonNames", required
= false) Boolean doTaxaByCommonNames
,
351 @RequestParam(value
= "matchMode", required
= false) MatchMode matchMode
355 logger
.info("doFind( " +
356 "query=\"" + ObjectUtils
.toString(query
) + "\", treeUuid=" + ObjectUtils
.toString(treeUuid
) +
357 ", area=" + ObjectUtils
.toString(areas
) +
358 ", pageSize=" + ObjectUtils
.toString(pageSize
) + ", page=" + ObjectUtils
.toString(page
) +
359 ", doTaxa=" + ObjectUtils
.toString(doTaxa
) + ", doSynonyms=" + ObjectUtils
.toString(doSynonyms
)
360 +", doTaxaByCommonNames=" + ObjectUtils
.toString(doTaxaByCommonNames
) +")" );
362 if(page
== null){ page
= BaseListController
.DEFAULT_PAGE_NUMBER
;}
363 if(pageSize
== null){ pageSize
= BaseListController
.DEFAULT_PAGESIZE
;}
368 ITaxonServiceConfigurator config
= new TaxonServiceConfiguratorImpl();
369 config
.setPageNumber(page
);
370 config
.setPageSize(pageSize
);
371 config
.setSearchString(query
);
372 config
.setDoTaxa(doTaxa
!= null ? doTaxa
: Boolean
.FALSE
);
373 config
.setDoSynonyms(doSynonyms
!= null ? doSynonyms
: Boolean
.FALSE
);
374 config
.setDoTaxaByCommonNames(doTaxaByCommonNames
!= null ? doTaxaByCommonNames
: Boolean
.FALSE
);
375 config
.setMatchMode(matchMode
!= null ? matchMode
: MatchMode
.BEGINNING
);
376 config
.setTaxonPropertyPath(SIMPLE_TAXON_INIT_STRATEGY
);
377 config
.setNamedAreas(areas
);
378 if(treeUuid
!= null){
379 Classification classification
= classificationService
.find(treeUuid
);
380 config
.setClassification(classification
);
383 return (Pager
<IdentifiableEntity
>) service
.findTaxaAndNames(config
);
387 * Get the synonymy for a taxon identified by the <code>{taxon-uuid}</code>.
388 * The synonymy consists
389 * of two parts: The group of homotypic synonyms of the taxon and the
390 * heterotypic synonymy groups of the taxon. The synonymy is ordered
391 * historically by the type designations and by the publication date of the
392 * nomenclatural reference
395 * <b>/{datasource-name}/portal/taxon/{taxon-uuid}/synonymy</b>
400 * @return a Map with to entries which are mapped by the following keys:
401 * "homotypicSynonymsByHomotypicGroup", "heterotypicSynonymyGroups",
402 * containing lists of {@link Synonym}s which are initialized using the
403 * following initialization strategy: {@link #SYNONYMY_INIT_STRATEGY}
405 * @throws IOException
408 value
= {"synonymy"},
409 method
= RequestMethod
.GET
)
410 public ModelAndView
doGetSynonymy(@PathVariable("uuid") UUID uuid
,
411 HttpServletRequest request
, HttpServletResponse response
)throws IOException
{
414 logger
.info("doGetSynonymy() " + request
.getServletPath());
416 ModelAndView mv
= new ModelAndView();
417 Taxon taxon
= getCdmBaseInstance(Taxon
.class, uuid
, response
, (List
<String
>)null);
418 Map
<String
, List
<?
>> synonymy
= new Hashtable
<String
, List
<?
>>();
419 synonymy
.put("homotypicSynonymsByHomotypicGroup", service
.getHomotypicSynonymsByHomotypicGroup(taxon
, SYNONYMY_INIT_STRATEGY
));
420 synonymy
.put("heterotypicSynonymyGroups", service
.getHeterotypicSynonymyGroups(taxon
, SYNONYMY_INIT_STRATEGY
));
421 mv
.addObject(synonymy
);
426 * Get the set of accepted {@link Taxon} entities for a given
427 * {@link TaxonBase} entity identified by the <code>{taxon-uuid}</code>.
429 * URI: <b>/{datasource-name}/portal/taxon/{taxon-uuid}/accepted</b>
433 * @return a Set of {@link Taxon} entities which are initialized
434 * using the following initialization strategy:
435 * {@link #SYNONYMY_INIT_STRATEGY}
436 * @throws IOException
438 @RequestMapping(value
= "accepted/{classification_uuid}", method
= RequestMethod
.GET
)
439 public Set
<TaxonBase
> getAccepted(
440 @PathVariable("uuid") UUID uuid
,
441 @PathVariable("classification_uuid") UUID classification_uuid
,
442 HttpServletRequest request
,
443 HttpServletResponse response
)
447 logger
.info("getAccepted() " + request
.getServletPath());
450 TaxonBase tb
= service
.load(uuid
, SYNONYMY_WITH_NODES_INIT_STRATEGY
);
452 response
.sendError(HttpServletResponse
.SC_NOT_FOUND
, "A taxon with the uuid " + uuid
+ " does not exist");
456 HashSet
<TaxonBase
> resultset
= new HashSet
<TaxonBase
>();
458 if (tb
instanceof Taxon
){
459 Taxon taxon
= (Taxon
) tb
;
460 Set
<TaxonNode
> nodes
= taxon
.getTaxonNodes();
461 for (TaxonNode taxonNode
: nodes
) {
462 if (taxonNode
.getClassification().compareTo(classification_uuid
) == 0){
463 resultset
.add((Taxon
) tb
);
466 if (resultset
.size() > 1){
467 //error!! A taxon is not allow to have more taxonnodes for a given classification
468 response
.sendError(HttpServletResponse
.SC_INTERNAL_SERVER_ERROR
,
469 "A taxon with the uuid " + uuid
+ " has more than one taxon node for the given classification" + classification_uuid
);
472 Synonym syn
= (Synonym
) tb
;
473 for(TaxonBase accepted
: syn
.getAcceptedTaxa()){
474 tb
= service
.load(accepted
.getUuid(), SIMPLE_TAXON_WITH_NODES_INIT_STRATEGY
);
475 if (tb
instanceof Taxon
){
476 Taxon taxon
= (Taxon
) tb
;
477 Set
<TaxonNode
> nodes
= taxon
.getTaxonNodes();
478 for (TaxonNode taxonNode
: nodes
) {
479 if (taxonNode
.getClassification().compareTo(classification_uuid
) == 0){
480 resultset
.add((Taxon
) tb
);
483 if (resultset
.size() > 1){
484 //error!! A taxon is not allow to have more taxonnodes for a given classification
485 response
.sendError(HttpServletResponse
.SC_INTERNAL_SERVER_ERROR
,
486 "A taxon with the uuid " + uuid
+ " has more than one taxon node for the given classification" + classification_uuid
);
489 //ERROR!! perhaps missapplied name????
490 //syn.getRelationType((Taxon)accepted);
496 if(tb instanceof Taxon){
497 //the taxon already is accepted
498 //FIXME take the current view into account once views are implemented!!!
499 resultset.add((Taxon)tb);
501 Synonym syn = (Synonym)tb;
502 for(TaxonBase accepted : syn.getAcceptedTaxa()){
503 accepted = service.load(accepted.getUuid(), SIMPLE_TAXON_INIT_STRATEGY);
504 resultset.add(accepted);
512 * Get the list of {@link TaxonRelationship}s for the given
513 * {@link TaxonBase} instance identified by the <code>{taxon-uuid}</code>.
515 * URI: <b>/{datasource-name}/portal/taxon/{taxon-uuid}/taxonRelationships</b>
519 * @return a List of {@link TaxonRelationship} entities which are initialized
520 * using the following initialization strategy:
521 * {@link #TAXONRELATIONSHIP_INIT_STRATEGY}
522 * @throws IOException
525 value
= {"taxonRelationships"},
526 method
= RequestMethod
.GET
)
527 public List
<TaxonRelationship
> doGetTaxonRelations(@PathVariable("uuid") UUID uuid
,
528 HttpServletRequest request
, HttpServletResponse response
)throws IOException
{
530 logger
.info("doGetTaxonRelations()" + request
.getServletPath());
531 Taxon taxon
= getCdmBaseInstance(Taxon
.class, uuid
, response
, (List
<String
>)null);
532 List
<TaxonRelationship
> relations
= new ArrayList
<TaxonRelationship
>();
533 List
<TaxonRelationship
> results
= service
.listToTaxonRelationships(taxon
, TaxonRelationshipType
.MISAPPLIED_NAME_FOR(), null, null, null, TAXONRELATIONSHIP_INIT_STRATEGY
);
534 relations
.addAll(results
);
535 results
= service
.listToTaxonRelationships(taxon
, TaxonRelationshipType
.INVALID_DESIGNATION_FOR(), null, null, null, TAXONRELATIONSHIP_INIT_STRATEGY
);
536 relations
.addAll(results
);
542 * Get the list of {@link NameRelationship}s of the Name associated with the
543 * {@link TaxonBase} instance identified by the <code>{taxon-uuid}</code>.
545 * URI: <b>/{datasource-name}/portal/taxon/{taxon-uuid}/nameRelationships</b>
549 * @return a List of {@link NameRelationship} entities which are initialized
550 * using the following initialization strategy:
551 * {@link #NAMERELATIONSHIP_INIT_STRATEGY}
552 * @throws IOException
555 value
= {"toNameRelationships"},
556 method
= RequestMethod
.GET
)
557 public List
<NameRelationship
> doGetToNameRelations(@PathVariable("uuid") UUID uuid
,
558 HttpServletRequest request
, HttpServletResponse response
)throws IOException
{
559 logger
.info("doGetNameRelations()" + request
.getServletPath());
560 TaxonBase taxonBase
= getCdmBaseInstance(TaxonBase
.class, uuid
, response
, (List
<String
>)null);
561 List
<NameRelationship
> list
= nameService
.listNameRelationships(taxonBase
.getName(), Direction
.relatedTo
, null, null, 0, null, NAMERELATIONSHIP_INIT_STRATEGY
);
562 //List<NameRelationship> list = nameService.listToNameRelationships(taxonBase.getName(), null, null, null, null, NAMERELATIONSHIP_INIT_STRATEGY);
567 * Get the list of {@link NameRelationship}s of the Name associated with the
568 * {@link TaxonBase} instance identified by the <code>{taxon-uuid}</code>.
570 * URI: <b>/{datasource-name}/portal/taxon/{taxon-uuid}/nameRelationships</b>
574 * @return a List of {@link NameRelationship} entities which are initialized
575 * using the following initialization strategy:
576 * {@link #NAMERELATIONSHIP_INIT_STRATEGY}
577 * @throws IOException
580 value
= {"fromNameRelationships"},
581 method
= RequestMethod
.GET
)
582 public List
<NameRelationship
> doGetFromNameRelations(@PathVariable("uuid") UUID uuid
,
583 HttpServletRequest request
, HttpServletResponse response
)throws IOException
{
584 logger
.info("doGetNameFromNameRelations()" + request
.getServletPath());
586 TaxonBase taxonbase
= getCdmBaseInstance(TaxonBase
.class, uuid
, response
, SIMPLE_TAXON_INIT_STRATEGY
);
587 List
<NameRelationship
> list
= nameService
.listNameRelationships(taxonbase
.getName(), Direction
.relatedFrom
, null, null, 0, null, NAMERELATIONSHIP_INIT_STRATEGY
);
588 //List<NameRelationship> list = nameService.listFromNameRelationships(taxonbase.getName(), null, null, null, null, NAMERELATIONSHIP_INIT_STRATEGY);
593 * Get the list of {@link TypeDesignationBase}s of the
594 * {@link TaxonBase} instance identified by the <code>{taxon-uuid}</code>.
596 * URI: <b>/{datasource-name}/portal/taxon/{taxon-uuid}/nameTypeDesignations</b>
600 * @return a List of {@link TypeDesignationBase} entities which are initialized
601 * using the following initialization strategy:
602 * {@link #TYPEDESIGNATION_INIT_STRATEGY}
603 * @throws IOException
604 * @Deprecated use /name/{uuid}/typeDesignations & /derivedunitfacade/{uuid} instead
605 * also see http://dev.e-taxonomy.eu/trac/ticket/2280
609 value
= {"nameTypeDesignations"},
610 method
= RequestMethod
.GET
)
611 public List
<TypeDesignationBase
> doGetNameTypeDesignations(@PathVariable("uuid") UUID uuid
,
612 HttpServletRequest request
, HttpServletResponse response
)throws IOException
{
613 logger
.info("doGetNameTypeDesignations()" + request
.getServletPath());
614 Taxon taxon
= getCdmBaseInstance(Taxon
.class, uuid
, response
, SIMPLE_TAXON_INIT_STRATEGY
);
615 Pager
<TypeDesignationBase
> p
= nameService
.getTypeDesignations(taxon
.getName(), null, null, null, TYPEDESIGNATION_INIT_STRATEGY
);
616 return p
.getRecords();
619 @RequestMapping(value
= "taxonNodes", method
= RequestMethod
.GET
)
620 public Set
<TaxonNode
> doGetTaxonNodes(
621 @PathVariable("uuid") UUID uuid
,
622 HttpServletRequest request
,
623 HttpServletResponse response
) throws IOException
{
624 TaxonBase tb
= service
.load(uuid
, TAXONNODE_INIT_STRATEGY
);
625 if(tb
instanceof Taxon
){
626 return ((Taxon
)tb
).getTaxonNodes();
628 HttpStatusMessage
.UUID_REFERENCES_WRONG_TYPE
.send(response
);
634 * Get the list of {@link TaxonDescription}s of the
635 * {@link Taxon} instance identified by the <code>{taxon-uuid}</code>.
637 * URI: <b>/{datasource-name}/portal/taxon/{taxon-uuid}/descriptions</b>
641 * @return a List of {@link TaxonDescription} entities which are initialized
642 * using the following initialization strategy:
643 * {@link #TAXONDESCRIPTION_INIT_STRATEGY}
644 * @throws IOException
647 value
= {"descriptions"},
648 method
= RequestMethod
.GET
)
649 public List
<TaxonDescription
> doGetDescriptions(
650 @PathVariable("uuid") UUID uuid
,
651 HttpServletRequest request
,
652 HttpServletResponse response
)throws IOException
{
654 logger
.info("doGetDescriptions()" + request
.getServletPath());
656 Taxon t
= getCdmBaseInstance(Taxon
.class, uuid
, response
, (List
<String
>)null);
657 Pager
<TaxonDescription
> p
= descriptionService
.getTaxonDescriptions(t
, null, null, null, null, TAXONDESCRIPTION_INIT_STRATEGY
);
658 return p
.getRecords();
661 @RequestMapping(value
= "descriptions/elementsByType/{classSimpleName}", method
= RequestMethod
.GET
)
662 public ModelAndView
doGetDescriptionElementsByType(
663 @PathVariable("uuid") UUID uuid
,
664 @PathVariable("classSimpleName") String classSimpleName
,
665 @RequestParam(value
= "count", required
= false, defaultValue
= "false") Boolean doCount
,
666 HttpServletRequest request
,
667 HttpServletResponse response
) throws IOException
{
668 logger
.info("doGetDescriptionElementsByType() - " + request
.getServletPath());
670 ModelAndView mv
= new ModelAndView();
672 List
<DescriptionElementBase
> allElements
= new ArrayList
<DescriptionElementBase
>();
673 List
<DescriptionElementBase
> elements
;
676 List
<String
> initStrategy
= doCount ?
null : DESCRIPTION_ELEMENT_INIT_STRATEGY
;
678 List
<TaxonDescription
> taxonDescriptions
= doGetDescriptions(uuid
, request
, response
);
681 type
= Class
.forName("eu.etaxonomy.cdm.model.description."
683 if (taxonDescriptions
!= null) {
684 for (TaxonDescription description
: taxonDescriptions
) {
685 elements
= descriptionService
.listDescriptionElements(description
, null, type
, null, 0, initStrategy
);
686 allElements
.addAll(elements
);
687 count
+= elements
.size();
691 } catch (ClassNotFoundException e
) {
692 HttpStatusMessage
.fromString(e
.getLocalizedMessage()).send(response
);
697 mv
.addObject(allElements
);
702 // @RequestMapping(value = "specimens", method = RequestMethod.GET)
703 // public ModelAndView doGetSpecimens(
704 // @PathVariable("uuid") UUID uuid,
705 // HttpServletRequest request,
706 // HttpServletResponse response) throws IOException, ClassNotFoundException {
707 // logger.info("doGetSpecimens() - " + request.getServletPath());
709 // ModelAndView mv = new ModelAndView();
711 // List<DerivedUnitFacade> derivedUnitFacadeList = new ArrayList<DerivedUnitFacade>();
713 // // find speciemens in the TaxonDescriptions
714 // List<TaxonDescription> taxonDescriptions = doGetDescriptions(uuid, request, response);
715 // if (taxonDescriptions != null) {
717 // for (TaxonDescription description : taxonDescriptions) {
718 // derivedUnitFacadeList.addAll( occurrenceService.listDerivedUnitFacades(description, null) );
721 // // TODO find speciemens in the NameDescriptions ??
723 // // TODO also find type specimens
725 // mv.addObject(derivedUnitFacadeList);
731 * Get the {@link Media} attached to the {@link Taxon} instance
732 * identified by the <code>{taxon-uuid}</code>.
734 * Usage /{datasource-name}/portal/taxon/{taxon-
735 * uuid}/media/{mime type
736 * list}/{size}[,[widthOrDuration}][,{height}]/
740 * <li><b>{mime type list}</b>: a comma separated list of mime types, in the
741 * order of preference. The forward slashes contained in the mime types must
742 * be replaced by a colon. Regular expressions can be used. Each media
743 * associated with this given taxon is being searched whereas the first
744 * matching mime type matching a representation always rules.</li>
745 * <li><b>{size},{widthOrDuration},{height}</b>: <i>not jet implemented</i>
746 * valid values are an integer or the asterisk '*' as a wildcard</li>
751 * @return a List of {@link Media} entities which are initialized
752 * using the following initialization strategy:
753 * {@link #TAXONDESCRIPTION_INIT_STRATEGY}
754 * @throws IOException
757 value
= {"media/*/*"},
758 method
= RequestMethod
.GET
)
759 public List
<Media
> doGetMedia(@PathVariable("uuid") UUID uuid
,
760 HttpServletRequest request
, HttpServletResponse response
) throws IOException
{
761 logger
.info("doGetMedia()" + request
.getServletPath());
762 Taxon t
= getCdmBaseInstance(Taxon
.class, uuid
, response
, (List
<String
>)null);
763 String path
= request
.getServletPath();
764 List
<Media
> returnMedia
= getMediaForTaxon(t
, path
, 5);
769 value
= {"subtree/media/*/*"},
770 method
= RequestMethod
.GET
)
771 public List
<Media
> doGetSubtreeMedia(@PathVariable("uuid") UUID uuid
,
772 HttpServletRequest request
, HttpServletResponse response
)throws IOException
{
773 logger
.info("doGetMedia()" + request
.getServletPath());
774 Taxon t
= getCdmBaseInstance(Taxon
.class, uuid
, response
, TAXON_WITH_NODES_INIT_STRATEGY
);
775 String path
= request
.getServletPath();
776 List
<Media
> returnMedia
= getMediaForTaxon(t
, path
, 6);
778 //looking for all medias of genus
779 if (t
.getTaxonNodes().size()>0){
780 Set
<TaxonNode
> nodes
= t
.getTaxonNodes();
781 Iterator
<TaxonNode
> iterator
= nodes
.iterator();
783 node
= iterator
.next();
784 //�berpr�fen, ob der TaxonNode zum aktuellen Baum geh�rt.
786 node
= classificationService
.loadTaxonNode(node
, TAXONNODE_WITHTAXON_INIT_STRATEGY
);
787 Set
<TaxonNode
> children
= node
.getChildNodes();
789 for (TaxonNode child
: children
){
790 childTaxon
= child
.getTaxon();
791 childTaxon
= (Taxon
)taxonService
.load(childTaxon
.getUuid(), null);
792 returnMedia
.addAll(getMediaForTaxon(childTaxon
, path
, 6));
799 private List
<Media
> getMediaForTaxon(Taxon taxon
, String path
, int mimeTypeTokenPosition
){
801 Pager
<TaxonDescription
> p
=
802 descriptionService
.getTaxonDescriptions(taxon
, null, null, null, null, TAXONDESCRIPTION_MEDIA_INIT_STRATEGY
);
804 // pars the media and quality parameters
807 // collect all media of the given taxon
808 boolean limitToGalleries
= false;
809 List
<Media
> taxonMedia
= new ArrayList
<Media
>();
810 for(TaxonDescription desc
: p
.getRecords()){
811 if(!limitToGalleries
|| desc
.isImageGallery()){
812 for(DescriptionElementBase element
: desc
.getElements()){
813 for(Media media
: element
.getMedia()){
814 taxonMedia
.add(media
);
820 String
[] pathTokens
= path
.split("/");
822 String
[] mimeTypes
= pathTokens
[mimeTypeTokenPosition
].split(",");
823 String
[] sizeTokens
= pathTokens
[mimeTypeTokenPosition
+ 1].split(",");
824 Integer widthOrDuration
= null;
825 Integer height
= null;
828 List
<Media
> returnMedia
= MediaUtils
.findPreferredMedia(taxonMedia
, mimeTypes
,
829 sizeTokens
, widthOrDuration
, height
, size
);
835 // ---------------------- code snippet preserved for possible later use --------------------
837 // value = {"/*/portal/taxon/*/descriptions"},
838 // method = RequestMethod.GET)
839 // public List<TaxonDescription> doGetDescriptionsbyFeatureTree(HttpServletRequest request, HttpServletResponse response)throws IOException {
840 // TaxonBase tb = getCdmBase(request, response, null, Taxon.class);
841 // if(tb instanceof Taxon){
842 // //T O D O this is a quick and dirty implementation -> generalize
843 // UUID featureTreeUuid = readValueUuid(request, featureTreeUuidPattern);
845 // FeatureTree featureTree = descriptionService.getFeatureTreeByUuid(featureTreeUuid);
846 // Pager<TaxonDescription> p = descriptionService.getTaxonDescriptions((Taxon)tb, null, null, null, null, TAXONDESCRIPTION_INIT_STRATEGY);
847 // List<TaxonDescription> descriptions = p.getRecords();
849 // if(!featureTree.isDescriptionSeparated()){
851 // TaxonDescription superDescription = TaxonDescription.NewInstance();
852 // //put all descriptionElements in superDescription and make it invisible
853 // for(TaxonDescription description: descriptions){
854 // for(DescriptionElementBase element: description.getElements()){
855 // superDescription.addElement(element);
858 // List<TaxonDescription> separatedDescriptions = new ArrayList<TaxonDescription>(descriptions.size());
859 // separatedDescriptions.add(superDescription);
860 // return separatedDescriptions;
862 // return descriptions;
865 // response.sendError(HttpServletResponse.SC_NOT_FOUND, "invalid type; Taxon expected but " + tb.getClass().getSimpleName() + " found.");