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 io
.swagger
.annotations
.Api
;
15 import java
.io
.IOException
;
16 import java
.util
.ArrayList
;
17 import java
.util
.Arrays
;
18 import java
.util
.HashSet
;
19 import java
.util
.Hashtable
;
20 import java
.util
.Iterator
;
21 import java
.util
.List
;
24 import java
.util
.UUID
;
26 import javax
.servlet
.http
.HttpServletRequest
;
27 import javax
.servlet
.http
.HttpServletResponse
;
29 import org
.apache
.log4j
.Logger
;
30 import org
.springframework
.beans
.factory
.annotation
.Autowired
;
31 import org
.springframework
.stereotype
.Controller
;
32 import org
.springframework
.web
.bind
.WebDataBinder
;
33 import org
.springframework
.web
.bind
.annotation
.InitBinder
;
34 import org
.springframework
.web
.bind
.annotation
.PathVariable
;
35 import org
.springframework
.web
.bind
.annotation
.RequestMapping
;
36 import org
.springframework
.web
.bind
.annotation
.RequestMethod
;
37 import org
.springframework
.web
.bind
.annotation
.RequestParam
;
38 import org
.springframework
.web
.servlet
.ModelAndView
;
40 import eu
.etaxonomy
.cdm
.api
.service
.IClassificationService
;
41 import eu
.etaxonomy
.cdm
.api
.service
.IDescriptionService
;
42 import eu
.etaxonomy
.cdm
.api
.service
.IFeatureTreeService
;
43 import eu
.etaxonomy
.cdm
.api
.service
.INameService
;
44 import eu
.etaxonomy
.cdm
.api
.service
.IOccurrenceService
;
45 import eu
.etaxonomy
.cdm
.api
.service
.ITaxonService
;
46 import eu
.etaxonomy
.cdm
.api
.service
.ITermService
;
47 import eu
.etaxonomy
.cdm
.api
.service
.pager
.Pager
;
48 import eu
.etaxonomy
.cdm
.api
.service
.util
.TaxonRelationshipEdge
;
49 import eu
.etaxonomy
.cdm
.database
.UpdatableRoutingDataSource
;
50 import eu
.etaxonomy
.cdm
.model
.common
.DefinedTermBase
;
51 import eu
.etaxonomy
.cdm
.model
.common
.MarkerType
;
52 import eu
.etaxonomy
.cdm
.model
.common
.RelationshipBase
.Direction
;
53 import eu
.etaxonomy
.cdm
.model
.description
.DescriptionElementBase
;
54 import eu
.etaxonomy
.cdm
.model
.description
.TaxonDescription
;
55 import eu
.etaxonomy
.cdm
.model
.location
.NamedArea
;
56 import eu
.etaxonomy
.cdm
.model
.media
.Media
;
57 import eu
.etaxonomy
.cdm
.model
.media
.MediaRepresentation
;
58 import eu
.etaxonomy
.cdm
.model
.media
.MediaRepresentationPart
;
59 import eu
.etaxonomy
.cdm
.model
.media
.MediaUtils
;
60 import eu
.etaxonomy
.cdm
.model
.name
.NameRelationship
;
61 import eu
.etaxonomy
.cdm
.model
.taxon
.Synonym
;
62 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
63 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonBase
;
64 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonNode
;
65 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonRelationship
;
66 import eu
.etaxonomy
.cdm
.persistence
.query
.MatchMode
;
67 import eu
.etaxonomy
.cdm
.remote
.controller
.util
.ControllerUtils
;
68 import eu
.etaxonomy
.cdm
.remote
.editor
.CdmTypePropertyEditor
;
69 import eu
.etaxonomy
.cdm
.remote
.editor
.DefinedTermBaseList
;
70 import eu
.etaxonomy
.cdm
.remote
.editor
.MatchModePropertyEditor
;
71 import eu
.etaxonomy
.cdm
.remote
.editor
.NamedAreaPropertyEditor
;
72 import eu
.etaxonomy
.cdm
.remote
.editor
.TermBaseListPropertyEditor
;
73 import eu
.etaxonomy
.cdm
.remote
.editor
.UUIDListPropertyEditor
;
74 import eu
.etaxonomy
.cdm
.remote
.editor
.UuidList
;
77 * The TaxonPortalController class is a Spring MVC Controller.
79 * The syntax of the mapped service URIs contains the the {datasource-name} path element.
80 * The available {datasource-name}s are defined in a configuration file which
81 * is loaded by the {@link UpdatableRoutingDataSource}. If the
82 * UpdatableRoutingDataSource is not being used in the actual application
83 * context any arbitrary {datasource-name} may be used.
85 * Methods mapped at type level, inherited from super classes ({@link BaseController}):
87 * URI: <b>/{datasource-name}/portal/taxon/{taxon-uuid}</b>
89 * Get the {@link TaxonBase} instance identified by the <code>{taxon-uuid}</code>.
90 * The returned Taxon is initialized by
91 * the following strategy {@link #TAXON_INIT_STRATEGY}
94 * @author a.kohlbecker
100 @RequestMapping(value
= {"/portal/taxon/{uuid}"})
101 public class TaxonPortalController
extends TaxonController
104 public static final Logger logger
= Logger
.getLogger(TaxonPortalController
.class);
107 private INameService nameService
;
110 private IDescriptionService descriptionService
;
113 private IOccurrenceService occurrenceService
;
116 private IClassificationService classificationService
;
119 private ITaxonService taxonService
;
122 private ITermService termService
;
125 private IFeatureTreeService featureTreeService
;
127 private static final List
<String
> TAXON_INIT_STRATEGY
= Arrays
.asList(new String
[]{
131 // "relationsToThisName.fromTaxon.name",
134 "name.nomenclaturalReference.authorship",
135 "name.nomenclaturalReference.inReference",
136 "name.rank.representations",
137 "name.status.type.representations",
139 // "descriptions" // TODO remove
143 private static final List
<String
> TAXON_WITH_NODES_INIT_STRATEGY
= Arrays
.asList(new String
[]{
145 "taxonNodes.classification.$",
146 "taxonNodes.childNodes.$"
149 private static final List
<String
> SIMPLE_TAXON_INIT_STRATEGY
= Arrays
.asList(new String
[]{
153 "name.rank.representations",
154 "name.status.type.representations",
155 "name.nomenclaturalReference.authorship",
156 "name.nomenclaturalReference.inReference",
157 "taxonNodes.classification",
160 private static final List
<String
> SYNONYMY_INIT_STRATEGY
= Arrays
.asList(new String
[]{
161 // initialize homotypical and heterotypical groups; needs synonyms
162 "synonymRelations.$",
163 "synonymRelations.synonym.$",
164 "synonymRelations.synonym.name.status.type.representations",
165 "synonymRelations.synonym.name.nomenclaturalReference.authorship",
166 "synonymRelations.synonym.name.nomenclaturalReference.inReference",
167 "synonymRelations.synonym.name.homotypicalGroup.typifiedNames.$",
168 "synonymRelations.synonym.name.homotypicalGroup.typifiedNames.taxonBases.$",
169 "synonymRelations.synonym.name.combinationAuthorship.$",
171 "name.typeDesignations",
173 "name.homotypicalGroup.$",
174 "name.homotypicalGroup.typifiedNames.$",
175 "name.homotypicalGroup.typifiedNames.nomenclaturalReference.authorship",
176 "name.homotypicalGroup.typifiedNames.nomenclaturalReference.inReference",
177 "name.homotypicalGroup.typifiedNames.taxonBases.$"
180 private static final List
<String
> SYNONYMY_WITH_NODES_INIT_STRATEGY
= Arrays
.asList(new String
[]{
181 // initialize homotypical and heterotypical groups; needs synonyms
182 "synonymRelations.$",
183 "synonymRelations.synonym.$",
184 "synonymRelations.synonym.name.status.type.representation",
185 "synonymRelations.synonym.name.nomenclaturalReference.authorship",
186 "synonymRelations.synonym.name.nomenclaturalReference.inReference",
187 "synonymRelations.synonym.name.homotypicalGroup.typifiedNames.$",
188 "synonymRelations.synonym.name.homotypicalGroup.typifiedNames.taxonBases.$",
189 "synonymRelations.synonym.name.combinationAuthorship.$",
191 "name.homotypicalGroup.$",
192 "name.homotypicalGroup.typifiedNames.$",
193 "name.homotypicalGroup.typifiedNames.nomenclaturalReference.authorship",
194 "name.homotypicalGroup.typifiedNames.nomenclaturalReference.inReference",
196 "name.homotypicalGroup.typifiedNames.taxonBases.$",
199 "taxonNodes.classification.$",
200 "taxonNodes.childNodes.$"
202 private static final List
<String
> SIMPLE_TAXON_WITH_NODES_INIT_STRATEGY
= Arrays
.asList(new String
[]{
205 "relationsToThisName.fromTaxon.name",
208 "name.rank.representations",
209 "name.status.type.representations",
210 "name.nomenclaturalReference.authorship",
211 "name.nomenclaturalReference.inReference",
214 "taxonNodes.classification.$",
215 "taxonNodes.childNodes.$"
219 private static final List
<String
> TAXONRELATIONSHIP_INIT_STRATEGY
= Arrays
.asList(new String
[]{
221 "type.inverseRepresentations",
228 private static final List
<String
> NAMERELATIONSHIP_INIT_STRATEGY
= Arrays
.asList(new String
[]{
230 "type.inverseRepresentations",
232 "toName.nomenclaturalReference.authorship",
233 "toName.nomenclaturalReference.inReference",
235 "fromName.nomenclaturalReference.authorship",
236 "fromName.nomenclaturalReference.inReference",
241 protected static final List
<String
> TAXONDESCRIPTION_INIT_STRATEGY
= Arrays
.asList(new String
[] {
244 "elements.stateData.$",
245 "elements.sources.citation.authorship",
246 "elements.sources.nameUsedInSource",
247 "elements.multilanguageText",
249 "elements.modifyingText",
250 "elements.modifiers",
251 "elements.kindOfUnit",
253 "name.rank.representations",
254 "name.status.type.representations",
258 protected static final List
<String
> DESCRIPTION_ELEMENT_INIT_STRATEGY
= Arrays
.asList(new String
[]{
260 "sources.citation.authorship",
261 "sources.nameUsedInSource",
267 // private static final List<String> NAMEDESCRIPTION_INIT_STRATEGY = Arrays.asList(new String []{
271 // "elements.multilanguageText",
275 protected static final List
<String
> TAXONDESCRIPTION_MEDIA_INIT_STRATEGY
= Arrays
.asList(new String
[]{
280 private static final List
<String
> TYPEDESIGNATION_INIT_STRATEGY
= Arrays
.asList(new String
[]{
282 "citation.authorship.$",
287 protected static final List
<String
> TAXONNODE_WITHTAXON_INIT_STRATEGY
= Arrays
.asList(new String
[]{
291 protected static final List
<String
> TAXONNODE_INIT_STRATEGY
= Arrays
.asList(new String
[]{
292 "taxonNodes.classification"
297 private static final String featureTreeUuidPattern
= "^/taxon(?:(?:/)([^/?#&\\.]+))+.*";
299 public TaxonPortalController(){
301 setInitializationStrategy(TAXON_INIT_STRATEGY
);
305 * @see eu.etaxonomy.cdm.remote.controller.GenericController#setService(eu.etaxonomy.cdm.api.service.IService)
309 public void setService(ITaxonService service
) {
310 this.service
= service
;
315 public void initBinder(WebDataBinder binder
) {
316 super.initBinder(binder
);
317 binder
.registerCustomEditor(NamedArea
.class, new NamedAreaPropertyEditor());
318 binder
.registerCustomEditor(MatchMode
.class, new MatchModePropertyEditor());
319 binder
.registerCustomEditor(Class
.class, new CdmTypePropertyEditor());
320 binder
.registerCustomEditor(UuidList
.class, new UUIDListPropertyEditor());
321 binder
.registerCustomEditor(DefinedTermBaseList
.class, new TermBaseListPropertyEditor
<NamedArea
>(termService
));
327 * @see eu.etaxonomy.cdm.remote.controller.BaseController#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
330 @RequestMapping(method = RequestMethod.GET)
331 public TaxonBase doGet(HttpServletRequest request, HttpServletResponse response)throws IOException {
332 logger.info("doGet()");
333 TaxonBase tb = getCdmBase(request, response, TAXON_INIT_STRATEGY, TaxonBase.class);
339 * Get the synonymy for a taxon identified by the <code>{taxon-uuid}</code>.
340 * The synonymy consists
341 * of two parts: The group of homotypic synonyms of the taxon and the
342 * heterotypic synonymy groups of the taxon. The synonymy is ordered
343 * historically by the type designations and by the publication date of the
344 * nomenclatural reference
347 * <b>/{datasource-name}/portal/taxon/{taxon-uuid}/synonymy</b>
352 * @return a Map with to entries which are mapped by the following keys:
353 * "homotypicSynonymsByHomotypicGroup", "heterotypicSynonymyGroups",
354 * containing lists of {@link Synonym}s which are initialized using the
355 * following initialization strategy: {@link #SYNONYMY_INIT_STRATEGY}
357 * @throws IOException
360 value
= {"synonymy"},
361 method
= RequestMethod
.GET
)
362 public ModelAndView
doGetSynonymy(@PathVariable("uuid") UUID uuid
,
363 HttpServletRequest request
, HttpServletResponse response
)throws IOException
{
366 logger
.info("doGetSynonymy() " + requestPathAndQuery(request
));
368 ModelAndView mv
= new ModelAndView();
369 Taxon taxon
= getCdmBaseInstance(Taxon
.class, uuid
, response
, (List
<String
>)null);
370 Map
<String
, List
<?
>> synonymy
= new Hashtable
<String
, List
<?
>>();
373 List
<List
<Synonym
>> synonymyGroups
= service
.getSynonymsByHomotypicGroup(taxon
, SYNONYMY_INIT_STRATEGY
);
374 synonymy
.put("homotypicSynonymsByHomotypicGroup", synonymyGroups
.get(0));
375 synonymyGroups
.remove(0);
376 synonymy
.put("heterotypicSynonymyGroups", synonymyGroups
);
379 // synonymy.put("homotypicSynonymsByHomotypicGroup", service.getHomotypicSynonymsByHomotypicGroup(taxon, SYNONYMY_INIT_STRATEGY));
380 // synonymy.put("heterotypicSynonymyGroups", service.getHeterotypicSynonymyGroups(taxon, SYNONYMY_INIT_STRATEGY));
383 mv
.addObject(synonymy
);
389 * Get the list of {@link TaxonRelationship}s for the given
390 * {@link TaxonBase} instance identified by the <code>{taxon-uuid}</code>.
392 * URI: <b>/{datasource-name}/portal/taxon/{taxon-uuid}/taxonRelationships</b>
396 * @return a List of {@link TaxonRelationship} entities which are initialized
397 * using the following initialization strategy:
398 * {@link #TAXONRELATIONSHIP_INIT_STRATEGY}
399 * @throws IOException
402 value
= {"taxonRelationships"},
403 method
= RequestMethod
.GET
)
404 public List
<TaxonRelationship
> doGetTaxonRelations(@PathVariable("uuid") UUID uuid
,
405 HttpServletRequest request
, HttpServletResponse response
)throws IOException
{
407 logger
.info("doGetTaxonRelations()" + requestPathAndQuery(request
));
408 Taxon taxon
= getCdmBaseInstance(Taxon
.class, uuid
, response
, (List
<String
>)null);
409 List
<TaxonRelationship
> toRelationships
= service
.listToTaxonRelationships(taxon
, null, null, null, null, TAXONRELATIONSHIP_INIT_STRATEGY
);
410 List
<TaxonRelationship
> fromRelationships
= service
.listFromTaxonRelationships(taxon
, null, null, null, null, TAXONRELATIONSHIP_INIT_STRATEGY
);
412 List
<TaxonRelationship
> allRelationships
= new ArrayList
<TaxonRelationship
>(toRelationships
.size() + fromRelationships
.size());
413 allRelationships
.addAll(toRelationships
);
414 allRelationships
.addAll(fromRelationships
);
416 return allRelationships
;
420 * Get the list of {@link NameRelationship}s of the Name associated with the
421 * {@link TaxonBase} instance identified by the <code>{taxon-uuid}</code>.
423 * URI: <b>/{datasource-name}/portal/taxon/{taxon-uuid}/nameRelationships</b>
427 * @return a List of {@link NameRelationship} entities which are initialized
428 * using the following initialization strategy:
429 * {@link #NAMERELATIONSHIP_INIT_STRATEGY}
430 * @throws IOException
433 value
= {"toNameRelationships"},
434 method
= RequestMethod
.GET
)
435 public List
<NameRelationship
> doGetToNameRelations(@PathVariable("uuid") UUID uuid
,
436 HttpServletRequest request
, HttpServletResponse response
)throws IOException
{
437 logger
.info("doGetNameRelations()" + request
.getRequestURI());
438 TaxonBase taxonBase
= getCdmBaseInstance(TaxonBase
.class, uuid
, response
, (List
<String
>)null);
439 List
<NameRelationship
> list
= nameService
.listNameRelationships(taxonBase
.getName(), Direction
.relatedTo
, null, null, 0, null, NAMERELATIONSHIP_INIT_STRATEGY
);
440 //List<NameRelationship> list = nameService.listToNameRelationships(taxonBase.getName(), null, null, null, null, NAMERELATIONSHIP_INIT_STRATEGY);
445 * Get the list of {@link NameRelationship}s of the Name associated with the
446 * {@link TaxonBase} instance identified by the <code>{taxon-uuid}</code>.
448 * URI: <b>/{datasource-name}/portal/taxon/{taxon-uuid}/nameRelationships</b>
452 * @return a List of {@link NameRelationship} entities which are initialized
453 * using the following initialization strategy:
454 * {@link #NAMERELATIONSHIP_INIT_STRATEGY}
455 * @throws IOException
458 value
= {"fromNameRelationships"},
459 method
= RequestMethod
.GET
)
460 public List
<NameRelationship
> doGetFromNameRelations(@PathVariable("uuid") UUID uuid
,
461 HttpServletRequest request
, HttpServletResponse response
)throws IOException
{
462 logger
.info("doGetNameFromNameRelations()" + requestPathAndQuery(request
));
464 TaxonBase taxonbase
= getCdmBaseInstance(TaxonBase
.class, uuid
, response
, SIMPLE_TAXON_INIT_STRATEGY
);
465 List
<NameRelationship
> list
= nameService
.listNameRelationships(taxonbase
.getName(), Direction
.relatedFrom
, null, null, 0, null, NAMERELATIONSHIP_INIT_STRATEGY
);
466 //List<NameRelationship> list = nameService.listFromNameRelationships(taxonbase.getName(), null, null, null, null, NAMERELATIONSHIP_INIT_STRATEGY);
471 @RequestMapping(value
= "taxonNodes", method
= RequestMethod
.GET
)
472 public Set
<TaxonNode
> doGetTaxonNodes(
473 @PathVariable("uuid") UUID uuid
,
474 HttpServletRequest request
,
475 HttpServletResponse response
) throws IOException
{
476 logger
.info("doGetTaxonNodes" + requestPathAndQuery(request
));
477 TaxonBase taxon
= service
.load(uuid
, TAXONNODE_INIT_STRATEGY
);
478 if(taxon
instanceof Taxon
){
479 return ((Taxon
)taxon
).getTaxonNodes();
481 HttpStatusMessage
.UUID_REFERENCES_WRONG_TYPE
.send(response
);
487 * Get the list of {@link TaxonDescription}s of the
488 * {@link Taxon} instance identified by the <code>{taxon-uuid}</code>.
490 * URI: <b>/{datasource-name}/portal/taxon/{taxon-uuid}/descriptions</b>
494 * @return a List of {@link TaxonDescription} entities which are initialized
495 * using the following initialization strategy:
496 * {@link #TAXONDESCRIPTION_INIT_STRATEGY}
497 * @throws IOException
500 value
= {"descriptions"},
501 method
= RequestMethod
.GET
)
502 public List
<TaxonDescription
> doGetDescriptions(
503 @PathVariable("uuid") UUID uuid
,
504 @RequestParam(value
= "markerTypes", required
= false) UuidList markerTypeUUIDs
,
505 HttpServletRequest request
,
506 HttpServletResponse response
)throws IOException
{
508 logger
.info("doGetDescriptions()" + requestPathAndQuery(request
));
510 List
<DefinedTermBase
> markerTypeTerms
= null;
511 Set
<UUID
> sMarkerTypeUUIDs
= null;
513 if(markerTypeUUIDs
!= null && !markerTypeUUIDs
.isEmpty()){
514 sMarkerTypeUUIDs
= new HashSet
<UUID
>(markerTypeUUIDs
);
515 markerTypeTerms
= termService
.find(sMarkerTypeUUIDs
);
516 } else if(markerTypeUUIDs
!= null && markerTypeUUIDs
.isEmpty()){
517 markerTypeTerms
= new ArrayList
<DefinedTermBase
>();
519 Set
<MarkerType
> markerTypes
= new HashSet
<MarkerType
>();
520 List
<TaxonDescription
> descriptions
= new ArrayList
<TaxonDescription
>();
521 if (markerTypeTerms
!= null) {
522 for (DefinedTermBase markerTypeTerm
: markerTypeTerms
) {
523 markerTypes
.add((MarkerType
)markerTypeTerm
);
526 Taxon t
= getCdmBaseInstance(Taxon
.class, uuid
, response
, (List
<String
>)null);
527 if (markerTypeTerms
== null) {
529 Pager
<TaxonDescription
> p
= descriptionService
.pageTaxonDescriptions(t
, null, null, null, null, TAXONDESCRIPTION_INIT_STRATEGY
);
530 descriptions
= p
.getRecords();
533 else if (markerTypeTerms
!= null && markerTypeTerms
.isEmpty()) {
534 descriptions
= descriptionService
.listTaxonDescriptions(t
, null, null, markerTypes
, null, null, TAXONDESCRIPTION_INIT_STRATEGY
);
538 descriptions
= descriptionService
.listTaxonDescriptions(t
, null, null, markerTypes
, null, null, TAXONDESCRIPTION_INIT_STRATEGY
);
539 /*for (TaxonDescription description: descriptions) {
540 for (IdentifiableSource source :description.getSources()) {
541 if (source.getOriginalNameString() != null) {
553 @RequestMapping(value
= "useDescriptions", method
= RequestMethod
.GET
)
554 public List
<TaxonDescription
> doGetUseDescriptions(
555 @PathVariable("uuid") UUID uuid
,
556 HttpServletRequest request
,
557 HttpServletResponse response
) throws IOException
{
558 logger
.info("doGetDescriptionElements() - " + requestPathAndQuery(request
));
560 //ModelAndView mv = new ModelAndView();
561 Taxon t
= getCdmBaseInstance(Taxon
.class, uuid
, response
, (List
<String
>)null);
563 //MarkerType useMarkerType = (MarkerType) markerTypeService.find(UUID.fromString("2e6e42d9-e92a-41f4-899b-03c0ac64f059"));
564 MarkerType useMarkerType
= (MarkerType
) termService
.find(UUID
.fromString("2e6e42d9-e92a-41f4-899b-03c0ac64f039"));
566 //find(UUID.fromString("2e6e42d9-e92a-41f4-899b-03c0ac64f059"));
567 Set
<MarkerType
> markerTypes
= new HashSet
<MarkerType
>();
568 markerTypes
.add(useMarkerType
);
569 List
<TaxonDescription
> descriptionElements
= descriptionService
.listTaxonDescriptions(t
, null, null, markerTypes
, null, null, TAXONDESCRIPTION_INIT_STRATEGY
);
570 //getDescriptionElements(description, features, type, pageSize, pageNumber, propertyPaths) load(uuid);
572 /*if(!(description instanceof TaxonDescription)){
573 HttpStatusMessage.UUID_REFERENCES_WRONG_TYPE.send(response);
574 // will terminate thread
577 //boolean hasStructuredData = service. hasStructuredData(description);
579 //mv.addObject(hasStructuredData);
581 return descriptionElements
;
584 @RequestMapping(value
= "descriptions/elementsByType/{classSimpleName}", method
= RequestMethod
.GET
)
585 public ModelAndView
doGetDescriptionElementsByType(
586 @PathVariable("uuid") UUID uuid
,
587 @PathVariable("classSimpleName") String classSimpleName
,
588 @RequestParam(value
= "markerTypes", required
= false) UuidList markerTypeUUIDs
,
589 @RequestParam(value
= "count", required
= false, defaultValue
= "false") Boolean doCount
,
590 HttpServletRequest request
,
591 HttpServletResponse response
) throws IOException
{
592 logger
.info("doGetDescriptionElementsByType() - " + requestPathAndQuery(request
));
594 ModelAndView mv
= new ModelAndView();
596 List
<DescriptionElementBase
> allElements
= new ArrayList
<DescriptionElementBase
>();
597 List
<DescriptionElementBase
> elements
;
600 List
<String
> initStrategy
= doCount ?
null : DESCRIPTION_ELEMENT_INIT_STRATEGY
;
602 List
<TaxonDescription
> taxonDescriptions
= doGetDescriptions(uuid
, markerTypeUUIDs
, request
, response
);
605 type
= Class
.forName("eu.etaxonomy.cdm.model.description."
607 if (taxonDescriptions
!= null) {
608 for (TaxonDescription description
: taxonDescriptions
) {
609 elements
= descriptionService
.listDescriptionElements(description
, null, type
, null, 0, initStrategy
);
610 allElements
.addAll(elements
);
611 count
+= elements
.size();
615 } catch (ClassNotFoundException e
) {
616 HttpStatusMessage
.create(e
.getLocalizedMessage(), 400).send(response
);
621 mv
.addObject(allElements
);
626 // @RequestMapping(value = "specimens", method = RequestMethod.GET)
627 // public ModelAndView doGetSpecimens(
628 // @PathVariable("uuid") UUID uuid,
629 // HttpServletRequest request,
630 // HttpServletResponse response) throws IOException, ClassNotFoundException {
631 // logger.info("doGetSpecimens() - " + request.getRequestURI());
633 // ModelAndView mv = new ModelAndView();
635 // List<DerivedUnitFacade> derivedUnitFacadeList = new ArrayList<DerivedUnitFacade>();
637 // // find speciemens in the TaxonDescriptions
638 // List<TaxonDescription> taxonDescriptions = doGetDescriptions(uuid, request, response);
639 // if (taxonDescriptions != null) {
641 // for (TaxonDescription description : taxonDescriptions) {
642 // derivedUnitFacadeList.addAll( occurrenceService.listDerivedUnitFacades(description, null) );
645 // // TODO find speciemens in the NameDescriptions ??
647 // // TODO also find type specimens
649 // mv.addObject(derivedUnitFacadeList);
655 * Get the {@link Media} attached to the {@link Taxon} instance
656 * identified by the <code>{taxon-uuid}</code>.
658 * Usage /{datasource-name}/portal/taxon/{taxon-
659 * uuid}/media/{mime type
660 * list}/{size}[,[widthOrDuration}][,{height}]/
664 * <li><b>{mime type list}</b>: a comma separated list of mime types, in the
665 * order of preference. The forward slashes contained in the mime types must
666 * be replaced by a colon. Regular expressions can be used. Each media
667 * associated with this given taxon is being searched whereas the first
668 * matching mime type matching a representation always rules.</li>
669 * <li><b>{size},{widthOrDuration},{height}</b>: <i>not jet implemented</i>
670 * valid values are an integer or the asterisk '*' as a wildcard</li>
675 * @return a List of {@link Media} entities which are initialized
676 * using the following initialization strategy:
677 * {@link #TAXONDESCRIPTION_INIT_STRATEGY}
678 * @throws IOException
682 method
= RequestMethod
.GET
)
683 public List
<Media
> doGetMedia(
684 @PathVariable("uuid") UUID uuid
,
685 @RequestParam(value
= "type", required
= false) Class
<?
extends MediaRepresentationPart
> type
,
686 @RequestParam(value
= "mimeTypes", required
= false) String
[] mimeTypes
,
687 @RequestParam(value
= "relationships", required
= false) UuidList relationshipUuids
,
688 @RequestParam(value
= "relationshipsInvers", required
= false) UuidList relationshipInversUuids
,
689 @RequestParam(value
= "includeTaxonDescriptions", required
= true) Boolean includeTaxonDescriptions
,
690 @RequestParam(value
= "includeOccurrences", required
= true) Boolean includeOccurrences
,
691 @RequestParam(value
= "includeTaxonNameDescriptions", required
= true) Boolean includeTaxonNameDescriptions
,
692 @RequestParam(value
= "widthOrDuration", required
= false) Integer widthOrDuration
,
693 @RequestParam(value
= "height", required
= false) Integer height
,
694 @RequestParam(value
= "size", required
= false) Integer size
,
695 HttpServletRequest request
, HttpServletResponse response
) throws IOException
{
697 logger
.info("doGetMedia() " + requestPathAndQuery(request
));
699 Taxon taxon
= getCdmBaseInstance(Taxon
.class, uuid
, response
, (List
<String
>)null);
701 Set
<TaxonRelationshipEdge
> includeRelationships
= ControllerUtils
.loadIncludeRelationships(relationshipUuids
, relationshipInversUuids
, termService
);
703 List
<Media
> returnMedia
= getMediaForTaxon(taxon
, includeRelationships
,
704 includeTaxonDescriptions
, includeOccurrences
, includeTaxonNameDescriptions
,
705 type
, mimeTypes
, widthOrDuration
, height
, size
);
710 value
= {"subtree/media"},
711 method
= RequestMethod
.GET
)
712 public List
<Media
> doGetSubtreeMedia(
713 @PathVariable("uuid") UUID uuid
,
714 @RequestParam(value
= "type", required
= false) Class
<?
extends MediaRepresentationPart
> type
,
715 @RequestParam(value
= "mimeTypes", required
= false) String
[] mimeTypes
,
716 @RequestParam(value
= "relationships", required
= false) UuidList relationshipUuids
,
717 @RequestParam(value
= "relationshipsInvers", required
= false) UuidList relationshipInversUuids
,
718 @RequestParam(value
= "includeTaxonDescriptions", required
= true) Boolean includeTaxonDescriptions
,
719 @RequestParam(value
= "includeOccurrences", required
= true) Boolean includeOccurrences
,
720 @RequestParam(value
= "includeTaxonNameDescriptions", required
= true) Boolean includeTaxonNameDescriptions
,
721 @RequestParam(value
= "widthOrDuration", required
= false) Integer widthOrDuration
,
722 @RequestParam(value
= "height", required
= false) Integer height
,
723 @RequestParam(value
= "size", required
= false) Integer size
,
724 HttpServletRequest request
, HttpServletResponse response
)throws IOException
{
726 logger
.info("doGetSubtreeMedia() " + requestPathAndQuery(request
));
728 Taxon taxon
= getCdmBaseInstance(Taxon
.class, uuid
, response
, TAXON_WITH_NODES_INIT_STRATEGY
);
730 Set
<TaxonRelationshipEdge
> includeRelationships
= ControllerUtils
.loadIncludeRelationships(relationshipUuids
, relationshipInversUuids
, termService
);
732 List
<Media
> returnMedia
= getMediaForTaxon(taxon
, includeRelationships
,
733 includeTaxonDescriptions
, includeOccurrences
, includeTaxonNameDescriptions
,
734 type
, mimeTypes
, widthOrDuration
, height
, size
);
736 //looking for all medias of genus
737 if (taxon
.getTaxonNodes().size()>0){
738 Set
<TaxonNode
> nodes
= taxon
.getTaxonNodes();
739 Iterator
<TaxonNode
> iterator
= nodes
.iterator();
741 node
= iterator
.next();
742 //Check if TaxonNode belongs to the current tree
744 node
= classificationService
.loadTaxonNode(node
, TAXONNODE_WITHTAXON_INIT_STRATEGY
);
745 List
<TaxonNode
> children
= node
.getChildNodes();
747 for (TaxonNode child
: children
){
748 childTaxon
= child
.getTaxon();
749 if(childTaxon
!= null) {
750 childTaxon
= (Taxon
)taxonService
.load(childTaxon
.getUuid(), null);
751 returnMedia
.addAll(getMediaForTaxon(childTaxon
, includeRelationships
,
752 includeTaxonDescriptions
, includeOccurrences
, includeTaxonNameDescriptions
,
753 type
, mimeTypes
, widthOrDuration
, height
, size
));
763 * @param includeRelationships
766 * @param widthOrDuration
771 private List
<Media
> getMediaForTaxon(Taxon taxon
, Set
<TaxonRelationshipEdge
> includeRelationships
,
772 Boolean includeTaxonDescriptions
, Boolean includeOccurrences
, Boolean includeTaxonNameDescriptions
,
773 Class
<?
extends MediaRepresentationPart
> type
, String
[] mimeTypes
, Integer widthOrDuration
,
774 Integer height
, Integer size
) {
777 logger
.trace("getMediaForTaxon() - list the media");
778 List
<Media
> taxonGalleryMedia
= service
.listMedia(taxon
, includeRelationships
,
779 false, includeTaxonDescriptions
, includeOccurrences
, includeTaxonNameDescriptions
, null);
781 // filter by preferred size and type
783 logger
.trace("getMediaForTaxon() - filter the media");
784 Map
<Media
, MediaRepresentation
> mediaRepresentationMap
= MediaUtils
.findPreferredMedia(
785 taxonGalleryMedia
, type
, mimeTypes
, null, widthOrDuration
, height
, size
);
787 List
<Media
> filteredMedia
= new ArrayList
<Media
>(mediaRepresentationMap
.size());
788 for (Media media
: mediaRepresentationMap
.keySet()) {
789 media
.getRepresentations().clear();
790 media
.addRepresentation(mediaRepresentationMap
.get(media
));
791 filteredMedia
.add(media
);
794 logger
.trace("getMediaForTaxon() - END ");
796 return filteredMedia
;
799 // ---------------------- code snippet preserved for possible later use --------------------
801 // value = {"//*/portal/taxon/*/descriptions"}, // mapped as absolute path, see CdmAntPathMatcher
802 // method = RequestMethod.GET)
803 // public List<TaxonDescription> doGetDescriptionsbyFeatureTree(HttpServletRequest request, HttpServletResponse response)throws IOException {
804 // TaxonBase tb = getCdmBase(request, response, null, Taxon.class);
805 // if(tb instanceof Taxon){
806 // //T O D O this is a quick and dirty implementation -> generalize
807 // UUID featureTreeUuid = readValueUuid(request, featureTreeUuidPattern);
809 // FeatureTree featureTree = descriptionService.getFeatureTreeByUuid(featureTreeUuid);
810 // Pager<TaxonDescription> p = descriptionService.getTaxonDescriptions((Taxon)tb, null, null, null, null, TAXONDESCRIPTION_INIT_STRATEGY);
811 // List<TaxonDescription> descriptions = p.getRecords();
813 // if(!featureTree.isDescriptionSeparated()){
815 // TaxonDescription superDescription = TaxonDescription.NewInstance();
816 // //put all descriptionElements in superDescription and make it invisible
817 // for(TaxonDescription description: descriptions){
818 // for(DescriptionElementBase element: description.getElements()){
819 // superDescription.addElement(element);
822 // List<TaxonDescription> separatedDescriptions = new ArrayList<TaxonDescription>(descriptions.size());
823 // separatedDescriptions.add(superDescription);
824 // return separatedDescriptions;
826 // return descriptions;
829 // response.sendError(HttpServletResponse.SC_NOT_FOUND, "invalid type; Taxon expected but " + tb.getClass().getSimpleName() + " found.");