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 static java
.net
.HttpURLConnection
.HTTP_BAD_REQUEST
;
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
.commons
.lang
.ObjectUtils
;
30 import org
.apache
.http
.HttpRequest
;
31 import org
.apache
.log4j
.Logger
;
32 import org
.springframework
.beans
.factory
.annotation
.Autowired
;
33 import org
.springframework
.stereotype
.Controller
;
34 import org
.springframework
.web
.bind
.WebDataBinder
;
35 import org
.springframework
.web
.bind
.annotation
.InitBinder
;
36 import org
.springframework
.web
.bind
.annotation
.PathVariable
;
37 import org
.springframework
.web
.bind
.annotation
.RequestMapping
;
38 import org
.springframework
.web
.bind
.annotation
.RequestMethod
;
39 import org
.springframework
.web
.bind
.annotation
.RequestParam
;
40 import org
.springframework
.web
.servlet
.ModelAndView
;
42 import eu
.etaxonomy
.cdm
.api
.service
.IDescriptionService
;
43 import eu
.etaxonomy
.cdm
.api
.service
.IFeatureTreeService
;
44 import eu
.etaxonomy
.cdm
.api
.service
.INameService
;
45 import eu
.etaxonomy
.cdm
.api
.service
.IOccurrenceService
;
46 import eu
.etaxonomy
.cdm
.api
.service
.ITaxonService
;
47 import eu
.etaxonomy
.cdm
.api
.service
.IClassificationService
;
48 import eu
.etaxonomy
.cdm
.api
.service
.config
.ITaxonServiceConfigurator
;
49 import eu
.etaxonomy
.cdm
.api
.service
.config
.TaxonServiceConfiguratorImpl
;
50 import eu
.etaxonomy
.cdm
.api
.service
.pager
.Pager
;
51 import eu
.etaxonomy
.cdm
.database
.UpdatableRoutingDataSource
;
52 import eu
.etaxonomy
.cdm
.model
.common
.IdentifiableEntity
;
53 import eu
.etaxonomy
.cdm
.model
.common
.RelationshipBase
.Direction
;
54 import eu
.etaxonomy
.cdm
.model
.description
.DescriptionElementBase
;
55 import eu
.etaxonomy
.cdm
.model
.description
.TaxonDescription
;
56 import eu
.etaxonomy
.cdm
.model
.location
.NamedArea
;
57 import eu
.etaxonomy
.cdm
.model
.media
.Media
;
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
.name
.TypeDesignationBase
;
62 import eu
.etaxonomy
.cdm
.model
.taxon
.Synonym
;
63 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
64 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonBase
;
65 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonNode
;
66 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonRelationship
;
67 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonRelationshipType
;
68 import eu
.etaxonomy
.cdm
.model
.taxon
.Classification
;
69 import eu
.etaxonomy
.cdm
.persistence
.query
.MatchMode
;
70 import eu
.etaxonomy
.cdm
.remote
.controller
.util
.PagerParameters
;
71 import eu
.etaxonomy
.cdm
.remote
.editor
.CdmTypePropertyEditor
;
72 import eu
.etaxonomy
.cdm
.remote
.editor
.MatchModePropertyEditor
;
73 import eu
.etaxonomy
.cdm
.remote
.editor
.NamedAreaPropertyEditor
;
76 * The TaxonPortalController class is a Spring MVC Controller.
78 * The syntax of the mapped service URIs contains the the {datasource-name} path element.
79 * The available {datasource-name}s are defined in a configuration file which
80 * is loaded by the {@link UpdatableRoutingDataSource}. If the
81 * UpdatableRoutingDataSource is not being used in the actual application
82 * context any arbitrary {datasource-name} may be used.
84 * Methods mapped at type level, inherited from super classes ({@link BaseController}):
86 * URI: <b>/{datasource-name}/portal/taxon/{taxon-uuid}</b>
88 * Get the {@link TaxonBase} instance identified by the <code>{taxon-uuid}</code>.
89 * The returned Taxon is initialized by
90 * the following strategy {@link #TAXON_INIT_STRATEGY}
93 * @author a.kohlbecker
98 @RequestMapping(value
= {"/portal/taxon/{uuid}"})
99 public class TaxonPortalController
extends BaseController
<TaxonBase
, ITaxonService
>
101 public static final Logger logger
= Logger
.getLogger(TaxonPortalController
.class);
104 private INameService nameService
;
107 private IDescriptionService descriptionService
;
110 private IOccurrenceService occurrenceService
;
113 private IClassificationService classificationService
;
116 private ITaxonService taxonService
;
119 private IFeatureTreeService featureTreeService
;
121 private static final List
<String
> TAXON_INIT_STRATEGY
= Arrays
.asList(new String
[]{
124 "relationsToThisName.fromTaxon.name",
127 "name.rank.representations",
128 "name.status.type.representations",
130 // taxon descriptions
131 "descriptions.elements.area.$",
132 "descriptions.elements.multilanguageText",
133 "descriptions.elements.media.representations.parts",
134 "descriptions.elements.media.title",
138 private static final List
<String
> TAXON_WITH_NODES_INIT_STRATEGY
= Arrays
.asList(new String
[]{
140 "taxonNodes.classification.$",
141 "taxonNodes.childNodes.$"
144 private static final List
<String
> SIMPLE_TAXON_INIT_STRATEGY
= Arrays
.asList(new String
[]{
147 "relationsToThisName.fromTaxon.name",
150 "name.rank.representations",
151 "name.status.type.representations",
152 "name.nomenclaturalReference"
155 private static final List
<String
> SYNONYMY_INIT_STRATEGY
= Arrays
.asList(new String
[]{
156 // initialize homotypical and heterotypical groups; needs synonyms
157 "synonymRelations.$",
158 "synonymRelations.synonym.$",
159 "synonymRelations.synonym.name.status.type.representation",
160 "synonymRelations.synonym.name.nomenclaturalReference.inReference",
161 "synonymRelations.synonym.name.homotypicalGroup.typifiedNames.$",
162 "synonymRelations.synonym.name.homotypicalGroup.typifiedNames.taxonBases.$",
163 "synonymRelations.synonym.name.combinationAuthorTeam.$",
165 "name.typeDesignations",
167 "name.homotypicalGroup.$",
168 "name.homotypicalGroup.typifiedNames.$",
169 "name.homotypicalGroup.typifiedNames.nomenclaturalReference.authorTeam",
171 "name.homotypicalGroup.typifiedNames.taxonBases.$"
174 private static final List
<String
> SYNONYMY_WITH_NODES_INIT_STRATEGY
= Arrays
.asList(new String
[]{
175 // initialize homotypical and heterotypical groups; needs synonyms
176 "synonymRelations.$",
177 "synonymRelations.synonym.$",
178 "synonymRelations.synonym.name.status.type.representation",
179 "synonymRelations.synonym.name.nomenclaturalReference.inReference",
180 "synonymRelations.synonym.name.homotypicalGroup.typifiedNames.$",
181 "synonymRelations.synonym.name.homotypicalGroup.typifiedNames.taxonBases.$",
182 "synonymRelations.synonym.name.combinationAuthorTeam.$",
184 "name.homotypicalGroup.$",
185 "name.homotypicalGroup.typifiedNames.$",
186 "name.homotypicalGroup.typifiedNames.nomenclaturalReference.authorTeam",
188 "name.homotypicalGroup.typifiedNames.taxonBases.$",
191 "taxonNodes.classification.$",
192 "taxonNodes.childNodes.$"
194 private static final List
<String
> SIMPLE_TAXON_WITH_NODES_INIT_STRATEGY
= Arrays
.asList(new String
[]{
197 "relationsToThisName.fromTaxon.name",
200 "name.rank.representations",
201 "name.status.type.representations",
202 "name.nomenclaturalReference",
205 "taxonNodes.classification.$",
206 "taxonNodes.childNodes.$"
210 private static final List
<String
> TAXONRELATIONSHIP_INIT_STRATEGY
= Arrays
.asList(new String
[]{
212 "type.inverseRepresentations",
217 private static final List
<String
> NAMERELATIONSHIP_INIT_STRATEGY
= Arrays
.asList(new String
[]{
219 "type.inverseRepresentations",
225 protected static final List
<String
> TAXONDESCRIPTION_INIT_STRATEGY
= Arrays
.asList(new String
[]{
228 "elements.sources.citation.authorTeam",
229 "elements.sources.nameUsedInSource.originalNameString",
230 "elements.multilanguageText",
231 "elements.media.representations.parts",
232 "elements.media.title",
235 protected static final List
<String
> DESCRIPTION_ELEMENT_INIT_STRATEGY
= Arrays
.asList(new String
[]{
237 "sources.citation.authorTeam",
238 "sources.nameUsedInSource.originalNameString",
240 "media.representations.parts",
245 // private static final List<String> NAMEDESCRIPTION_INIT_STRATEGY = Arrays.asList(new String []{
249 // "elements.multilanguageText",
250 // "elements.media.representations.parts",
251 // "elements.media.title",
254 protected static final List
<String
> TAXONDESCRIPTION_MEDIA_INIT_STRATEGY
= Arrays
.asList(new String
[]{
255 "elements.media.representations.parts",
256 "elements.media.title"
260 private static final List
<String
> TYPEDESIGNATION_INIT_STRATEGY
= Arrays
.asList(new String
[]{
263 "citation.authorTeam.$",
267 protected static final List
<String
> TAXONNODE_WITHTAXON_INIT_STRATEGY
= Arrays
.asList(new String
[]{
271 protected static final List
<String
> TAXONNODE_INIT_STRATEGY
= Arrays
.asList(new String
[]{
272 "taxonNodes.classification"
277 private static final String featureTreeUuidPattern
= "^/taxon(?:(?:/)([^/?#&\\.]+))+.*";
279 public TaxonPortalController(){
281 setInitializationStrategy(TAXON_INIT_STRATEGY
);
285 * @see eu.etaxonomy.cdm.remote.controller.GenericController#setService(eu.etaxonomy.cdm.api.service.IService)
289 public void setService(ITaxonService service
) {
290 this.service
= service
;
295 public void initBinder(WebDataBinder binder
) {
296 super.initBinder(binder
);
297 binder
.registerCustomEditor(NamedArea
.class, new NamedAreaPropertyEditor());
298 binder
.registerCustomEditor(MatchMode
.class, new MatchModePropertyEditor());
299 binder
.registerCustomEditor(Class
.class, new CdmTypePropertyEditor());
304 * @see eu.etaxonomy.cdm.remote.controller.BaseController#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
307 @RequestMapping(method = RequestMethod.GET)
308 public TaxonBase doGet(HttpServletRequest request, HttpServletResponse response)throws IOException {
309 logger.info("doGet()");
310 TaxonBase tb = getCdmBase(request, response, TAXON_INIT_STRATEGY, TaxonBase.class);
315 * Find Taxa, Synonyms, Common Names by name, either globally or in a specific geographic area.
317 * URI: <b>/{datasource-name}/portal/taxon/find</b>
320 * the string to query for. Since the wildcard character '*'
321 * internally always is appended to the query string, a search
322 * always compares the query string with the beginning of a name.
323 * - <i>required parameter</i>
325 * the {@link UUID} of a {@link Classification} to which the
326 * search is to be restricted. - <i>optional parameter</i>
328 * restrict the search to a set of geographic {@link NamedArea}s.
329 * The parameter currently takes a list of TDWG area labels.
330 * - <i>optional parameter</i>
332 * the number of the page to be returned, the first page has the
333 * pageNumber = 1 - <i>optional parameter</i>
335 * the maximum number of entities returned per page (can be -1
336 * to return all entities in a single page) - <i>optional parameter</i>
338 * weather to search for instances of {@link Taxon} - <i>optional parameter</i>
340 * weather to search for instances of {@link Synonym} - <i>optional parameter</i>
341 * @param doTaxaByCommonNames
342 * for instances of {@link Taxon} by a common name used - <i>optional parameter</i>
344 * valid values are "EXACT", "BEGINNING", "ANYWHERE", "END" (case sensitive !!!)
345 * @return a Pager on a list of {@link IdentifiableEntity}s initialized by
346 * the following strategy {@link #SIMPLE_TAXON_INIT_STRATEGY}
347 * @throws IOException
349 @RequestMapping(method
= RequestMethod
.GET
,
350 value
= {"/portal/taxon/find"}) //TODO map to path /*/portal/taxon/
351 public Pager
<IdentifiableEntity
> doFind(
352 @RequestParam(value
= "query", required
= false) String query
,
353 @RequestParam(value
= "tree", required
= false) UUID treeUuid
,
354 @RequestParam(value
= "area", required
= false) Set
<NamedArea
> areas
,
355 @RequestParam(value
= "pageNumber", required
= false) Integer pageNumber
,
356 @RequestParam(value
= "pageSize", required
= false) Integer pageSize
,
357 @RequestParam(value
= "doTaxa", required
= false) Boolean doTaxa
,
358 @RequestParam(value
= "doSynonyms", required
= false) Boolean doSynonyms
,
359 @RequestParam(value
= "doTaxaByCommonNames", required
= false) Boolean doTaxaByCommonNames
,
360 @RequestParam(value
= "matchMode", required
= false) MatchMode matchMode
,
361 HttpServletRequest request
,
362 HttpServletResponse response
366 logger
.info("doFind : " + request
.getRequestURI() + "?" + request
.getQueryString() );
368 PagerParameters pagerParams
= new PagerParameters(pageSize
, pageNumber
);
369 pagerParams
.normalizeAndValidate(response
);
371 ITaxonServiceConfigurator config
= new TaxonServiceConfiguratorImpl();
372 config
.setPageNumber(pagerParams
.getPageIndex());
373 config
.setPageSize(pagerParams
.getPageSize());
374 config
.setTitleSearchString(query
);
375 config
.setDoTaxa(doTaxa
!= null ? doTaxa
: Boolean
.FALSE
);
376 config
.setDoSynonyms(doSynonyms
!= null ? doSynonyms
: Boolean
.FALSE
);
377 config
.setDoTaxaByCommonNames(doTaxaByCommonNames
!= null ? doTaxaByCommonNames
: Boolean
.FALSE
);
378 config
.setMatchMode(matchMode
!= null ? matchMode
: MatchMode
.BEGINNING
);
379 config
.setTaxonPropertyPath(SIMPLE_TAXON_INIT_STRATEGY
);
380 config
.setNamedAreas(areas
);
381 if(treeUuid
!= null){
382 Classification classification
= classificationService
.find(treeUuid
);
383 config
.setClassification(classification
);
386 return (Pager
<IdentifiableEntity
>) service
.findTaxaAndNames(config
);
390 * Get the synonymy for a taxon identified by the <code>{taxon-uuid}</code>.
391 * The synonymy consists
392 * of two parts: The group of homotypic synonyms of the taxon and the
393 * heterotypic synonymy groups of the taxon. The synonymy is ordered
394 * historically by the type designations and by the publication date of the
395 * nomenclatural reference
398 * <b>/{datasource-name}/portal/taxon/{taxon-uuid}/synonymy</b>
403 * @return a Map with to entries which are mapped by the following keys:
404 * "homotypicSynonymsByHomotypicGroup", "heterotypicSynonymyGroups",
405 * containing lists of {@link Synonym}s which are initialized using the
406 * following initialization strategy: {@link #SYNONYMY_INIT_STRATEGY}
408 * @throws IOException
411 value
= {"synonymy"},
412 method
= RequestMethod
.GET
)
413 public ModelAndView
doGetSynonymy(@PathVariable("uuid") UUID uuid
,
414 HttpServletRequest request
, HttpServletResponse response
)throws IOException
{
417 logger
.info("doGetSynonymy() " + request
.getServletPath());
419 ModelAndView mv
= new ModelAndView();
420 Taxon taxon
= getCdmBaseInstance(Taxon
.class, uuid
, response
, (List
<String
>)null);
421 Map
<String
, List
<?
>> synonymy
= new Hashtable
<String
, List
<?
>>();
422 synonymy
.put("homotypicSynonymsByHomotypicGroup", service
.getHomotypicSynonymsByHomotypicGroup(taxon
, SYNONYMY_INIT_STRATEGY
));
423 synonymy
.put("heterotypicSynonymyGroups", service
.getHeterotypicSynonymyGroups(taxon
, SYNONYMY_INIT_STRATEGY
));
424 mv
.addObject(synonymy
);
429 * Get the set of accepted {@link Taxon} entities for a given
430 * {@link TaxonBase} entity identified by the <code>{taxon-uuid}</code>.
432 * URI: <b>/{datasource-name}/portal/taxon/{taxon-uuid}/accepted</b>
436 * @return a Set of {@link Taxon} entities which are initialized
437 * using the following initialization strategy:
438 * {@link #SYNONYMY_INIT_STRATEGY}
439 * @throws IOException
441 @RequestMapping(value
= "accepted/{classification_uuid}", method
= RequestMethod
.GET
)
442 public Set
<TaxonBase
> getAccepted(
443 @PathVariable("uuid") UUID uuid
,
444 @PathVariable("classification_uuid") UUID classification_uuid
,
445 HttpServletRequest request
,
446 HttpServletResponse response
)
450 logger
.info("getAccepted() " + request
.getServletPath());
453 TaxonBase tb
= service
.load(uuid
, SYNONYMY_WITH_NODES_INIT_STRATEGY
);
455 response
.sendError(HttpServletResponse
.SC_NOT_FOUND
, "A taxon with the uuid " + uuid
+ " does not exist");
459 HashSet
<TaxonBase
> resultset
= new HashSet
<TaxonBase
>();
461 if (tb
instanceof Taxon
){
462 Taxon taxon
= (Taxon
) tb
;
463 Set
<TaxonNode
> nodes
= taxon
.getTaxonNodes();
464 for (TaxonNode taxonNode
: nodes
) {
465 if (taxonNode
.getClassification().compareTo(classification_uuid
) == 0){
466 resultset
.add((Taxon
) tb
);
469 if (resultset
.size() > 1){
470 //error!! A taxon is not allow to have more taxonnodes for a given classification
471 response
.sendError(HttpServletResponse
.SC_INTERNAL_SERVER_ERROR
,
472 "A taxon with the uuid " + uuid
+ " has more than one taxon node for the given classification" + classification_uuid
);
475 Synonym syn
= (Synonym
) tb
;
476 for(TaxonBase accepted
: syn
.getAcceptedTaxa()){
477 tb
= service
.load(accepted
.getUuid(), SIMPLE_TAXON_WITH_NODES_INIT_STRATEGY
);
478 if (tb
instanceof Taxon
){
479 Taxon taxon
= (Taxon
) tb
;
480 Set
<TaxonNode
> nodes
= taxon
.getTaxonNodes();
481 for (TaxonNode taxonNode
: nodes
) {
482 if (taxonNode
.getClassification().compareTo(classification_uuid
) == 0){
483 resultset
.add((Taxon
) tb
);
486 if (resultset
.size() > 1){
487 //error!! A taxon is not allow to have more taxonnodes for a given classification
488 response
.sendError(HttpServletResponse
.SC_INTERNAL_SERVER_ERROR
,
489 "A taxon with the uuid " + uuid
+ " has more than one taxon node for the given classification" + classification_uuid
);
492 //ERROR!! perhaps missapplied name????
493 //syn.getRelationType((Taxon)accepted);
499 if(tb instanceof Taxon){
500 //the taxon already is accepted
501 //FIXME take the current view into account once views are implemented!!!
502 resultset.add((Taxon)tb);
504 Synonym syn = (Synonym)tb;
505 for(TaxonBase accepted : syn.getAcceptedTaxa()){
506 accepted = service.load(accepted.getUuid(), SIMPLE_TAXON_INIT_STRATEGY);
507 resultset.add(accepted);
515 * Get the list of {@link TaxonRelationship}s for the given
516 * {@link TaxonBase} instance identified by the <code>{taxon-uuid}</code>.
518 * URI: <b>/{datasource-name}/portal/taxon/{taxon-uuid}/taxonRelationships</b>
522 * @return a List of {@link TaxonRelationship} entities which are initialized
523 * using the following initialization strategy:
524 * {@link #TAXONRELATIONSHIP_INIT_STRATEGY}
525 * @throws IOException
528 value
= {"taxonRelationships"},
529 method
= RequestMethod
.GET
)
530 public List
<TaxonRelationship
> doGetTaxonRelations(@PathVariable("uuid") UUID uuid
,
531 HttpServletRequest request
, HttpServletResponse response
)throws IOException
{
533 logger
.info("doGetTaxonRelations()" + request
.getServletPath());
534 Taxon taxon
= getCdmBaseInstance(Taxon
.class, uuid
, response
, (List
<String
>)null);
535 List
<TaxonRelationship
> toRelationships
= service
.listToTaxonRelationships(taxon
, null, null, null, null, TAXONRELATIONSHIP_INIT_STRATEGY
);
536 List
<TaxonRelationship
> fromRelationships
= service
.listFromTaxonRelationships(taxon
, null, null, null, null, TAXONRELATIONSHIP_INIT_STRATEGY
);
538 List
<TaxonRelationship
> allRelationships
= new ArrayList
<TaxonRelationship
>(toRelationships
.size() + fromRelationships
.size());
539 allRelationships
.addAll(toRelationships
);
540 allRelationships
.addAll(fromRelationships
);
542 return allRelationships
;
546 * Get the list of {@link NameRelationship}s of the Name associated with the
547 * {@link TaxonBase} instance identified by the <code>{taxon-uuid}</code>.
549 * URI: <b>/{datasource-name}/portal/taxon/{taxon-uuid}/nameRelationships</b>
553 * @return a List of {@link NameRelationship} entities which are initialized
554 * using the following initialization strategy:
555 * {@link #NAMERELATIONSHIP_INIT_STRATEGY}
556 * @throws IOException
559 value
= {"toNameRelationships"},
560 method
= RequestMethod
.GET
)
561 public List
<NameRelationship
> doGetToNameRelations(@PathVariable("uuid") UUID uuid
,
562 HttpServletRequest request
, HttpServletResponse response
)throws IOException
{
563 logger
.info("doGetNameRelations()" + request
.getServletPath());
564 TaxonBase taxonBase
= getCdmBaseInstance(TaxonBase
.class, uuid
, response
, (List
<String
>)null);
565 List
<NameRelationship
> list
= nameService
.listNameRelationships(taxonBase
.getName(), Direction
.relatedTo
, null, null, 0, null, NAMERELATIONSHIP_INIT_STRATEGY
);
566 //List<NameRelationship> list = nameService.listToNameRelationships(taxonBase.getName(), null, null, null, null, NAMERELATIONSHIP_INIT_STRATEGY);
571 * Get the list of {@link NameRelationship}s of the Name associated with the
572 * {@link TaxonBase} instance identified by the <code>{taxon-uuid}</code>.
574 * URI: <b>/{datasource-name}/portal/taxon/{taxon-uuid}/nameRelationships</b>
578 * @return a List of {@link NameRelationship} entities which are initialized
579 * using the following initialization strategy:
580 * {@link #NAMERELATIONSHIP_INIT_STRATEGY}
581 * @throws IOException
584 value
= {"fromNameRelationships"},
585 method
= RequestMethod
.GET
)
586 public List
<NameRelationship
> doGetFromNameRelations(@PathVariable("uuid") UUID uuid
,
587 HttpServletRequest request
, HttpServletResponse response
)throws IOException
{
588 logger
.info("doGetNameFromNameRelations()" + request
.getServletPath());
590 TaxonBase taxonbase
= getCdmBaseInstance(TaxonBase
.class, uuid
, response
, SIMPLE_TAXON_INIT_STRATEGY
);
591 List
<NameRelationship
> list
= nameService
.listNameRelationships(taxonbase
.getName(), Direction
.relatedFrom
, null, null, 0, null, NAMERELATIONSHIP_INIT_STRATEGY
);
592 //List<NameRelationship> list = nameService.listFromNameRelationships(taxonbase.getName(), null, null, null, null, NAMERELATIONSHIP_INIT_STRATEGY);
597 * Get the list of {@link TypeDesignationBase}s of the
598 * {@link TaxonBase} instance identified by the <code>{taxon-uuid}</code>.
600 * URI: <b>/{datasource-name}/portal/taxon/{taxon-uuid}/nameTypeDesignations</b>
604 * @return a List of {@link TypeDesignationBase} entities which are initialized
605 * using the following initialization strategy:
606 * {@link #TYPEDESIGNATION_INIT_STRATEGY}
607 * @throws IOException
608 * @Deprecated use /name/{uuid}/typeDesignations & /derivedunitfacade/{uuid} instead
609 * also see http://dev.e-taxonomy.eu/trac/ticket/2280
613 value
= {"nameTypeDesignations"},
614 method
= RequestMethod
.GET
)
615 public List
<TypeDesignationBase
> doGetNameTypeDesignations(@PathVariable("uuid") UUID uuid
,
616 HttpServletRequest request
, HttpServletResponse response
)throws IOException
{
617 logger
.info("doGetNameTypeDesignations()" + request
.getServletPath());
618 Taxon taxon
= getCdmBaseInstance(Taxon
.class, uuid
, response
, SIMPLE_TAXON_INIT_STRATEGY
);
619 Pager
<TypeDesignationBase
> p
= nameService
.getTypeDesignations(taxon
.getName(), null, null, null, TYPEDESIGNATION_INIT_STRATEGY
);
620 return p
.getRecords();
623 @RequestMapping(value
= "taxonNodes", method
= RequestMethod
.GET
)
624 public Set
<TaxonNode
> doGetTaxonNodes(
625 @PathVariable("uuid") UUID uuid
,
626 HttpServletRequest request
,
627 HttpServletResponse response
) throws IOException
{
628 TaxonBase tb
= service
.load(uuid
, TAXONNODE_INIT_STRATEGY
);
629 if(tb
instanceof Taxon
){
630 return ((Taxon
)tb
).getTaxonNodes();
632 HttpStatusMessage
.UUID_REFERENCES_WRONG_TYPE
.send(response
);
638 * Get the list of {@link TaxonDescription}s of the
639 * {@link Taxon} instance identified by the <code>{taxon-uuid}</code>.
641 * URI: <b>/{datasource-name}/portal/taxon/{taxon-uuid}/descriptions</b>
645 * @return a List of {@link TaxonDescription} entities which are initialized
646 * using the following initialization strategy:
647 * {@link #TAXONDESCRIPTION_INIT_STRATEGY}
648 * @throws IOException
651 value
= {"descriptions"},
652 method
= RequestMethod
.GET
)
653 public List
<TaxonDescription
> doGetDescriptions(
654 @PathVariable("uuid") UUID uuid
,
655 HttpServletRequest request
,
656 HttpServletResponse response
)throws IOException
{
658 logger
.info("doGetDescriptions()" + request
.getServletPath());
660 Taxon t
= getCdmBaseInstance(Taxon
.class, uuid
, response
, (List
<String
>)null);
661 Pager
<TaxonDescription
> p
= descriptionService
.getTaxonDescriptions(t
, null, null, null, null, TAXONDESCRIPTION_INIT_STRATEGY
);
662 return p
.getRecords();
665 @RequestMapping(value
= "descriptions/elementsByType/{classSimpleName}", method
= RequestMethod
.GET
)
666 public ModelAndView
doGetDescriptionElementsByType(
667 @PathVariable("uuid") UUID uuid
,
668 @PathVariable("classSimpleName") String classSimpleName
,
669 @RequestParam(value
= "count", required
= false, defaultValue
= "false") Boolean doCount
,
670 HttpServletRequest request
,
671 HttpServletResponse response
) throws IOException
{
672 logger
.info("doGetDescriptionElementsByType() - " + request
.getServletPath());
674 ModelAndView mv
= new ModelAndView();
676 List
<DescriptionElementBase
> allElements
= new ArrayList
<DescriptionElementBase
>();
677 List
<DescriptionElementBase
> elements
;
680 List
<String
> initStrategy
= doCount ?
null : DESCRIPTION_ELEMENT_INIT_STRATEGY
;
682 List
<TaxonDescription
> taxonDescriptions
= doGetDescriptions(uuid
, request
, response
);
685 type
= Class
.forName("eu.etaxonomy.cdm.model.description."
687 if (taxonDescriptions
!= null) {
688 for (TaxonDescription description
: taxonDescriptions
) {
689 elements
= descriptionService
.listDescriptionElements(description
, null, type
, null, 0, initStrategy
);
690 allElements
.addAll(elements
);
691 count
+= elements
.size();
695 } catch (ClassNotFoundException e
) {
696 HttpStatusMessage
.fromString(e
.getLocalizedMessage()).send(response
);
701 mv
.addObject(allElements
);
706 // @RequestMapping(value = "specimens", method = RequestMethod.GET)
707 // public ModelAndView doGetSpecimens(
708 // @PathVariable("uuid") UUID uuid,
709 // HttpServletRequest request,
710 // HttpServletResponse response) throws IOException, ClassNotFoundException {
711 // logger.info("doGetSpecimens() - " + request.getServletPath());
713 // ModelAndView mv = new ModelAndView();
715 // List<DerivedUnitFacade> derivedUnitFacadeList = new ArrayList<DerivedUnitFacade>();
717 // // find speciemens in the TaxonDescriptions
718 // List<TaxonDescription> taxonDescriptions = doGetDescriptions(uuid, request, response);
719 // if (taxonDescriptions != null) {
721 // for (TaxonDescription description : taxonDescriptions) {
722 // derivedUnitFacadeList.addAll( occurrenceService.listDerivedUnitFacades(description, null) );
725 // // TODO find speciemens in the NameDescriptions ??
727 // // TODO also find type specimens
729 // mv.addObject(derivedUnitFacadeList);
735 * Get the {@link Media} attached to the {@link Taxon} instance
736 * identified by the <code>{taxon-uuid}</code>.
738 * Usage /{datasource-name}/portal/taxon/{taxon-
739 * uuid}/media/{mime type
740 * list}/{size}[,[widthOrDuration}][,{height}]/
744 * <li><b>{mime type list}</b>: a comma separated list of mime types, in the
745 * order of preference. The forward slashes contained in the mime types must
746 * be replaced by a colon. Regular expressions can be used. Each media
747 * associated with this given taxon is being searched whereas the first
748 * matching mime type matching a representation always rules.</li>
749 * <li><b>{size},{widthOrDuration},{height}</b>: <i>not jet implemented</i>
750 * valid values are an integer or the asterisk '*' as a wildcard</li>
755 * @return a List of {@link Media} entities which are initialized
756 * using the following initialization strategy:
757 * {@link #TAXONDESCRIPTION_INIT_STRATEGY}
758 * @throws IOException
762 method
= RequestMethod
.GET
)
763 public List
<Media
> doGetMedia(
764 @PathVariable("uuid") UUID uuid
,
765 @RequestParam(value
= "type", required
= false) Class
<?
extends MediaRepresentationPart
> type
,
766 @RequestParam(value
= "mimeTypes", required
= false) String
[] mimeTypes
,
767 @RequestParam(value
= "widthOrDuration", required
= false) Integer widthOrDuration
,
768 @RequestParam(value
= "height", required
= false) Integer height
,
769 @RequestParam(value
= "size", required
= false) Integer size
,
770 HttpServletRequest request
, HttpServletResponse response
) throws IOException
{
772 logger
.info("doGetMedia()" + request
.getServletPath());
773 Taxon t
= getCdmBaseInstance(Taxon
.class, uuid
, response
, (List
<String
>)null);
774 String path
= request
.getServletPath();
775 List
<Media
> returnMedia
= getMediaForTaxon(t
, type
, mimeTypes
, widthOrDuration
, height
, size
);
780 value
= {"subtree/media"},
781 method
= RequestMethod
.GET
)
782 public List
<Media
> doGetSubtreeMedia(
783 @PathVariable("uuid") UUID uuid
,
784 @RequestParam(value
= "type", required
= false) Class
<?
extends MediaRepresentationPart
> type
,
785 @RequestParam(value
= "mimeTypes", required
= false) String
[] mimeTypes
,
786 @RequestParam(value
= "widthOrDuration", required
= false) Integer widthOrDuration
,
787 @RequestParam(value
= "height", required
= false) Integer height
,
788 @RequestParam(value
= "size", required
= false) Integer size
,
789 HttpServletRequest request
, HttpServletResponse response
)throws IOException
{
790 logger
.info("doGetMedia()" + request
.getServletPath());
791 Taxon taxon
= getCdmBaseInstance(Taxon
.class, uuid
, response
, TAXON_WITH_NODES_INIT_STRATEGY
);
792 String requestPath
= request
.getServletPath();
793 List
<Media
> returnMedia
= getMediaForTaxon(taxon
, type
, mimeTypes
, widthOrDuration
, height
, size
);
795 //looking for all medias of genus
796 if (taxon
.getTaxonNodes().size()>0){
797 Set
<TaxonNode
> nodes
= taxon
.getTaxonNodes();
798 Iterator
<TaxonNode
> iterator
= nodes
.iterator();
800 node
= iterator
.next();
801 //Check if TaxonNode belongs to the current tree
803 node
= classificationService
.loadTaxonNode(node
, TAXONNODE_WITHTAXON_INIT_STRATEGY
);
804 Set
<TaxonNode
> children
= node
.getChildNodes();
806 for (TaxonNode child
: children
){
807 childTaxon
= child
.getTaxon();
808 childTaxon
= (Taxon
)taxonService
.load(childTaxon
.getUuid(), null);
809 returnMedia
.addAll(getMediaForTaxon(childTaxon
, type
, mimeTypes
, widthOrDuration
, height
, size
));
816 private List
<Media
> getMediaForTaxon(Taxon taxon
, Class
<?
extends MediaRepresentationPart
> type
, String
[] mimeTypes
,
817 Integer widthOrDuration
, Integer height
, Integer size
){
819 Pager
<TaxonDescription
> p
=
820 descriptionService
.getTaxonDescriptions(taxon
, null, null, null, null, TAXONDESCRIPTION_MEDIA_INIT_STRATEGY
);
822 // pars the media and quality parameters
825 // collect all media of the given taxon
826 boolean limitToGalleries
= false;
827 List
<Media
> taxonMedia
= new ArrayList
<Media
>();
828 List
<Media
> taxonGalleryMedia
= new ArrayList
<Media
>();
829 for(TaxonDescription desc
: p
.getRecords()){
831 if(desc
.isImageGallery()){
832 for(DescriptionElementBase element
: desc
.getElements()){
833 for(Media media
: element
.getMedia()){
834 taxonGalleryMedia
.add(media
);
837 } else if(!limitToGalleries
){
838 for(DescriptionElementBase element
: desc
.getElements()){
839 for(Media media
: element
.getMedia()){
840 taxonMedia
.add(media
);
847 taxonGalleryMedia
.addAll(taxonMedia
);
849 List
<Media
> returnMedia
= MediaUtils
.findPreferredMedia(taxonGalleryMedia
, type
,
850 mimeTypes
, null, widthOrDuration
, height
, size
);
856 // ---------------------- code snippet preserved for possible later use --------------------
858 // value = {"/*/portal/taxon/*/descriptions"},
859 // method = RequestMethod.GET)
860 // public List<TaxonDescription> doGetDescriptionsbyFeatureTree(HttpServletRequest request, HttpServletResponse response)throws IOException {
861 // TaxonBase tb = getCdmBase(request, response, null, Taxon.class);
862 // if(tb instanceof Taxon){
863 // //T O D O this is a quick and dirty implementation -> generalize
864 // UUID featureTreeUuid = readValueUuid(request, featureTreeUuidPattern);
866 // FeatureTree featureTree = descriptionService.getFeatureTreeByUuid(featureTreeUuid);
867 // Pager<TaxonDescription> p = descriptionService.getTaxonDescriptions((Taxon)tb, null, null, null, null, TAXONDESCRIPTION_INIT_STRATEGY);
868 // List<TaxonDescription> descriptions = p.getRecords();
870 // if(!featureTree.isDescriptionSeparated()){
872 // TaxonDescription superDescription = TaxonDescription.NewInstance();
873 // //put all descriptionElements in superDescription and make it invisible
874 // for(TaxonDescription description: descriptions){
875 // for(DescriptionElementBase element: description.getElements()){
876 // superDescription.addElement(element);
879 // List<TaxonDescription> separatedDescriptions = new ArrayList<TaxonDescription>(descriptions.size());
880 // separatedDescriptions.add(superDescription);
881 // return separatedDescriptions;
883 // return descriptions;
886 // response.sendError(HttpServletResponse.SC_NOT_FOUND, "invalid type; Taxon expected but " + tb.getClass().getSimpleName() + " found.");