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
;
43 import eu
.etaxonomy
.cdm
.api
.service
.IDescriptionService
;
44 import eu
.etaxonomy
.cdm
.api
.service
.IFeatureTreeService
;
45 import eu
.etaxonomy
.cdm
.api
.service
.IMarkerService
;
46 import eu
.etaxonomy
.cdm
.api
.service
.INameService
;
47 import eu
.etaxonomy
.cdm
.api
.service
.IOccurrenceService
;
48 import eu
.etaxonomy
.cdm
.api
.service
.IService
;
49 import eu
.etaxonomy
.cdm
.api
.service
.ITaxonService
;
50 import eu
.etaxonomy
.cdm
.api
.service
.IClassificationService
;
51 import eu
.etaxonomy
.cdm
.api
.service
.ITermService
;
52 import eu
.etaxonomy
.cdm
.api
.service
.config
.ITaxonServiceConfigurator
;
53 import eu
.etaxonomy
.cdm
.api
.service
.config
.TaxonServiceConfiguratorImpl
;
54 import eu
.etaxonomy
.cdm
.api
.service
.pager
.Pager
;
55 import eu
.etaxonomy
.cdm
.database
.UpdatableRoutingDataSource
;
56 import eu
.etaxonomy
.cdm
.model
.common
.DefinedTermBase
;
57 import eu
.etaxonomy
.cdm
.model
.common
.IdentifiableEntity
;
58 import eu
.etaxonomy
.cdm
.model
.common
.Marker
;
59 import eu
.etaxonomy
.cdm
.model
.common
.MarkerType
;
60 import eu
.etaxonomy
.cdm
.model
.common
.RelationshipBase
.Direction
;
61 import eu
.etaxonomy
.cdm
.model
.description
.DescriptionElementBase
;
62 import eu
.etaxonomy
.cdm
.model
.description
.TaxonDescription
;
63 import eu
.etaxonomy
.cdm
.model
.location
.NamedArea
;
64 import eu
.etaxonomy
.cdm
.model
.location
.NamedAreaLevel
;
65 import eu
.etaxonomy
.cdm
.model
.media
.Media
;
66 import eu
.etaxonomy
.cdm
.model
.media
.MediaRepresentationPart
;
67 import eu
.etaxonomy
.cdm
.model
.media
.MediaUtils
;
68 import eu
.etaxonomy
.cdm
.model
.name
.NameRelationship
;
69 import eu
.etaxonomy
.cdm
.model
.name
.TypeDesignationBase
;
70 import eu
.etaxonomy
.cdm
.model
.taxon
.Synonym
;
71 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
72 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonBase
;
73 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonNode
;
74 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonRelationship
;
75 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonRelationshipType
;
76 import eu
.etaxonomy
.cdm
.model
.taxon
.Classification
;
77 import eu
.etaxonomy
.cdm
.persistence
.query
.MatchMode
;
78 import eu
.etaxonomy
.cdm
.remote
.controller
.util
.PagerParameters
;
79 import eu
.etaxonomy
.cdm
.remote
.editor
.CdmTypePropertyEditor
;
80 import eu
.etaxonomy
.cdm
.remote
.editor
.MatchModePropertyEditor
;
81 import eu
.etaxonomy
.cdm
.remote
.editor
.NamedAreaPropertyEditor
;
82 import eu
.etaxonomy
.cdm
.remote
.editor
.UUIDListPropertyEditor
;
83 import eu
.etaxonomy
.cdm
.remote
.editor
.UuidList
;
86 * The TaxonPortalController class is a Spring MVC Controller.
88 * The syntax of the mapped service URIs contains the the {datasource-name} path element.
89 * The available {datasource-name}s are defined in a configuration file which
90 * is loaded by the {@link UpdatableRoutingDataSource}. If the
91 * UpdatableRoutingDataSource is not being used in the actual application
92 * context any arbitrary {datasource-name} may be used.
94 * Methods mapped at type level, inherited from super classes ({@link BaseController}):
96 * URI: <b>/{datasource-name}/portal/taxon/{taxon-uuid}</b>
98 * Get the {@link TaxonBase} instance identified by the <code>{taxon-uuid}</code>.
99 * The returned Taxon is initialized by
100 * the following strategy {@link #TAXON_INIT_STRATEGY}
103 * @author a.kohlbecker
108 @RequestMapping(value
= {"/portal/taxon/{uuid}"})
109 public class TaxonPortalController
extends BaseController
<TaxonBase
, ITaxonService
>
111 public static final Logger logger
= Logger
.getLogger(TaxonPortalController
.class);
114 private INameService nameService
;
117 private IDescriptionService descriptionService
;
120 private IOccurrenceService occurrenceService
;
123 private IClassificationService classificationService
;
126 private ITaxonService taxonService
;
129 private ITermService markerTypeService
;
132 private IMarkerService markerService
;
133 //private IService<MarkerType> markerTypeService;
136 private IFeatureTreeService featureTreeService
;
138 private static final List
<String
> TAXON_INIT_STRATEGY
= Arrays
.asList(new String
[]{
141 "relationsToThisName.fromTaxon.name",
144 "name.rank.representations",
145 "name.status.type.representations",
147 // taxon descriptions
148 "descriptions.elements.area.$",
149 "descriptions.elements.multilanguageText",
150 "descriptions.elements.media.representations.parts",
151 "descriptions.elements.media.title",
155 private static final List
<String
> TAXON_WITH_NODES_INIT_STRATEGY
= Arrays
.asList(new String
[]{
157 "taxonNodes.classification.$",
158 "taxonNodes.childNodes.$"
161 private static final List
<String
> SIMPLE_TAXON_INIT_STRATEGY
= Arrays
.asList(new String
[]{
164 "relationsToThisName.fromTaxon.name",
167 "name.rank.representations",
168 "name.status.type.representations",
169 "name.nomenclaturalReference"
172 private static final List
<String
> SYNONYMY_INIT_STRATEGY
= Arrays
.asList(new String
[]{
173 // initialize homotypical and heterotypical groups; needs synonyms
174 "synonymRelations.$",
175 "synonymRelations.synonym.$",
176 "synonymRelations.synonym.name.status.type.representation",
177 "synonymRelations.synonym.name.nomenclaturalReference.inReference",
178 "synonymRelations.synonym.name.homotypicalGroup.typifiedNames.$",
179 "synonymRelations.synonym.name.homotypicalGroup.typifiedNames.taxonBases.$",
180 "synonymRelations.synonym.name.combinationAuthorTeam.$",
182 "name.typeDesignations",
184 "name.homotypicalGroup.$",
185 "name.homotypicalGroup.typifiedNames.$",
186 "name.homotypicalGroup.typifiedNames.nomenclaturalReference.authorTeam",
188 "name.homotypicalGroup.typifiedNames.taxonBases.$"
191 private static final List
<String
> SYNONYMY_WITH_NODES_INIT_STRATEGY
= Arrays
.asList(new String
[]{
192 // initialize homotypical and heterotypical groups; needs synonyms
193 "synonymRelations.$",
194 "synonymRelations.synonym.$",
195 "synonymRelations.synonym.name.status.type.representation",
196 "synonymRelations.synonym.name.nomenclaturalReference.inReference",
197 "synonymRelations.synonym.name.homotypicalGroup.typifiedNames.$",
198 "synonymRelations.synonym.name.homotypicalGroup.typifiedNames.taxonBases.$",
199 "synonymRelations.synonym.name.combinationAuthorTeam.$",
201 "name.homotypicalGroup.$",
202 "name.homotypicalGroup.typifiedNames.$",
203 "name.homotypicalGroup.typifiedNames.nomenclaturalReference.authorTeam",
205 "name.homotypicalGroup.typifiedNames.taxonBases.$",
208 "taxonNodes.classification.$",
209 "taxonNodes.childNodes.$"
211 private static final List
<String
> SIMPLE_TAXON_WITH_NODES_INIT_STRATEGY
= Arrays
.asList(new String
[]{
214 "relationsToThisName.fromTaxon.name",
217 "name.rank.representations",
218 "name.status.type.representations",
219 "name.nomenclaturalReference",
222 "taxonNodes.classification.$",
223 "taxonNodes.childNodes.$"
227 private static final List
<String
> TAXONRELATIONSHIP_INIT_STRATEGY
= Arrays
.asList(new String
[]{
229 "type.inverseRepresentations",
236 private static final List
<String
> NAMERELATIONSHIP_INIT_STRATEGY
= Arrays
.asList(new String
[]{
238 "type.inverseRepresentations",
244 protected static final List
<String
> TAXONDESCRIPTION_INIT_STRATEGY
= Arrays
.asList(new String
[]{
247 "elements.sources.citation.authorTeam",
248 "elements.sources.nameUsedInSource.originalNameString",
249 "elements.multilanguageText",
250 "elements.media.representations.parts",
251 "elements.media.title",
254 protected static final List
<String
> TAXONUSEDESCRIPTION_INIT_STRATEGY
= Arrays
.asList(new String
[]{
259 "elements.sources.citation.authorTeam",
260 "elements.sources.nameUsedInSource.originalNameString",
261 /*//"elements.multilanguageText",
262 "elements.media.representations.parts",
263 "elements.media.title",*/
266 protected static final List
<String
> DESCRIPTION_ELEMENT_INIT_STRATEGY
= Arrays
.asList(new String
[]{
268 "sources.citation.authorTeam",
269 "sources.nameUsedInSource.originalNameString",
271 "media.representations.parts",
276 // private static final List<String> NAMEDESCRIPTION_INIT_STRATEGY = Arrays.asList(new String []{
280 // "elements.multilanguageText",
281 // "elements.media.representations.parts",
282 // "elements.media.title",
285 protected static final List
<String
> TAXONDESCRIPTION_MEDIA_INIT_STRATEGY
= Arrays
.asList(new String
[]{
286 "elements.media.representations.parts",
287 "elements.media.title"
291 private static final List
<String
> TYPEDESIGNATION_INIT_STRATEGY
= Arrays
.asList(new String
[]{
294 "citation.authorTeam.$",
298 protected static final List
<String
> TAXONNODE_WITHTAXON_INIT_STRATEGY
= Arrays
.asList(new String
[]{
302 protected static final List
<String
> TAXONNODE_INIT_STRATEGY
= Arrays
.asList(new String
[]{
303 "taxonNodes.classification"
308 private static final String featureTreeUuidPattern
= "^/taxon(?:(?:/)([^/?#&\\.]+))+.*";
310 public TaxonPortalController(){
312 setInitializationStrategy(TAXON_INIT_STRATEGY
);
316 * @see eu.etaxonomy.cdm.remote.controller.GenericController#setService(eu.etaxonomy.cdm.api.service.IService)
320 public void setService(ITaxonService service
) {
321 this.service
= service
;
326 public void initBinder(WebDataBinder binder
) {
327 super.initBinder(binder
);
328 binder
.registerCustomEditor(NamedArea
.class, new NamedAreaPropertyEditor());
329 binder
.registerCustomEditor(MatchMode
.class, new MatchModePropertyEditor());
330 binder
.registerCustomEditor(Class
.class, new CdmTypePropertyEditor());
331 binder
.registerCustomEditor(UuidList
.class, new UUIDListPropertyEditor());
337 * @see eu.etaxonomy.cdm.remote.controller.BaseController#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
340 @RequestMapping(method = RequestMethod.GET)
341 public TaxonBase doGet(HttpServletRequest request, HttpServletResponse response)throws IOException {
342 logger.info("doGet()");
343 TaxonBase tb = getCdmBase(request, response, TAXON_INIT_STRATEGY, TaxonBase.class);
348 * Find Taxa, Synonyms, Common Names by name, either globally or in a specific geographic area.
350 * URI: <b>/{datasource-name}/portal/taxon/find</b>
353 * the string to query for. Since the wildcard character '*'
354 * internally always is appended to the query string, a search
355 * always compares the query string with the beginning of a name.
356 * - <i>required parameter</i>
358 * the {@link UUID} of a {@link Classification} to which the
359 * search is to be restricted. - <i>optional parameter</i>
361 * restrict the search to a set of geographic {@link NamedArea}s.
362 * The parameter currently takes a list of TDWG area labels.
363 * - <i>optional parameter</i>
365 * the number of the page to be returned, the first page has the
366 * pageNumber = 1 - <i>optional parameter</i>
368 * the maximum number of entities returned per page (can be -1
369 * to return all entities in a single page) - <i>optional parameter</i>
371 * weather to search for instances of {@link Taxon} - <i>optional parameter</i>
373 * weather to search for instances of {@link Synonym} - <i>optional parameter</i>
374 * @param doTaxaByCommonNames
375 * for instances of {@link Taxon} by a common name used - <i>optional parameter</i>
377 * valid values are "EXACT", "BEGINNING", "ANYWHERE", "END" (case sensitive !!!)
378 * @return a Pager on a list of {@link IdentifiableEntity}s initialized by
379 * the following strategy {@link #SIMPLE_TAXON_INIT_STRATEGY}
380 * @throws IOException
382 @RequestMapping(method
= RequestMethod
.GET
,
383 value
= {"/portal/taxon/find"}) //TODO map to path /*/portal/taxon/
384 public Pager
<IdentifiableEntity
> doFind(
385 @RequestParam(value
= "query", required
= false) String query
,
386 @RequestParam(value
= "tree", required
= false) UUID treeUuid
,
387 @RequestParam(value
= "area", required
= false) Set
<NamedArea
> areas
,
388 @RequestParam(value
= "pageNumber", required
= false) Integer pageNumber
,
389 @RequestParam(value
= "pageSize", required
= false) Integer pageSize
,
390 @RequestParam(value
= "doTaxa", required
= false) Boolean doTaxa
,
391 @RequestParam(value
= "doSynonyms", required
= false) Boolean doSynonyms
,
392 @RequestParam(value
= "doMisappliedNames", required
= false) Boolean doMisappliedNames
,
393 @RequestParam(value
= "doTaxaByCommonNames", required
= false) Boolean doTaxaByCommonNames
,
394 @RequestParam(value
= "matchMode", required
= false) MatchMode matchMode
,
395 HttpServletRequest request
,
396 HttpServletResponse response
400 logger
.info("doFind : " + request
.getRequestURI() + "?" + request
.getQueryString() );
402 PagerParameters pagerParams
= new PagerParameters(pageSize
, pageNumber
);
403 pagerParams
.normalizeAndValidate(response
);
405 ITaxonServiceConfigurator config
= new TaxonServiceConfiguratorImpl();
406 config
.setPageNumber(pagerParams
.getPageIndex());
407 config
.setPageSize(pagerParams
.getPageSize());
408 config
.setTitleSearchString(query
);
409 config
.setDoTaxa(doTaxa
!= null ? doTaxa
: Boolean
.FALSE
);
410 config
.setDoSynonyms(doSynonyms
!= null ? doSynonyms
: Boolean
.FALSE
);
411 config
.setDoMisappliedNames(doMisappliedNames
!= null ? doMisappliedNames
: Boolean
.FALSE
);
412 config
.setDoTaxaByCommonNames(doTaxaByCommonNames
!= null ? doTaxaByCommonNames
: Boolean
.FALSE
);
413 config
.setMatchMode(matchMode
!= null ? matchMode
: MatchMode
.BEGINNING
);
414 config
.setTaxonPropertyPath(SIMPLE_TAXON_INIT_STRATEGY
);
415 config
.setNamedAreas(areas
);
416 if(treeUuid
!= null){
417 Classification classification
= classificationService
.find(treeUuid
);
418 config
.setClassification(classification
);
421 return (Pager
<IdentifiableEntity
>) service
.findTaxaAndNames(config
);
425 * Get the synonymy for a taxon identified by the <code>{taxon-uuid}</code>.
426 * The synonymy consists
427 * of two parts: The group of homotypic synonyms of the taxon and the
428 * heterotypic synonymy groups of the taxon. The synonymy is ordered
429 * historically by the type designations and by the publication date of the
430 * nomenclatural reference
433 * <b>/{datasource-name}/portal/taxon/{taxon-uuid}/synonymy</b>
438 * @return a Map with to entries which are mapped by the following keys:
439 * "homotypicSynonymsByHomotypicGroup", "heterotypicSynonymyGroups",
440 * containing lists of {@link Synonym}s which are initialized using the
441 * following initialization strategy: {@link #SYNONYMY_INIT_STRATEGY}
443 * @throws IOException
446 value
= {"synonymy"},
447 method
= RequestMethod
.GET
)
448 public ModelAndView
doGetSynonymy(@PathVariable("uuid") UUID uuid
,
449 HttpServletRequest request
, HttpServletResponse response
)throws IOException
{
452 logger
.info("doGetSynonymy() " + request
.getServletPath());
454 ModelAndView mv
= new ModelAndView();
455 Taxon taxon
= getCdmBaseInstance(Taxon
.class, uuid
, response
, (List
<String
>)null);
456 Map
<String
, List
<?
>> synonymy
= new Hashtable
<String
, List
<?
>>();
457 synonymy
.put("homotypicSynonymsByHomotypicGroup", service
.getHomotypicSynonymsByHomotypicGroup(taxon
, SYNONYMY_INIT_STRATEGY
));
458 synonymy
.put("heterotypicSynonymyGroups", service
.getHeterotypicSynonymyGroups(taxon
, SYNONYMY_INIT_STRATEGY
));
459 mv
.addObject(synonymy
);
464 * Get the set of accepted {@link Taxon} entities for a given
465 * {@link TaxonBase} entity identified by the <code>{taxon-uuid}</code>.
467 * URI: <b>/{datasource-name}/portal/taxon/{taxon-uuid}/accepted</b>
471 * @return a Set of {@link Taxon} entities which are initialized
472 * using the following initialization strategy:
473 * {@link #SYNONYMY_INIT_STRATEGY}
474 * @throws IOException
476 @RequestMapping(value
= "accepted/{classification_uuid}", method
= RequestMethod
.GET
)
477 public Set
<TaxonBase
> getAccepted(
478 @PathVariable("uuid") UUID uuid
,
479 @PathVariable("classification_uuid") UUID classification_uuid
,
480 HttpServletRequest request
,
481 HttpServletResponse response
)
485 logger
.info("getAccepted() " + request
.getServletPath());
488 TaxonBase tb
= service
.load(uuid
, SYNONYMY_WITH_NODES_INIT_STRATEGY
);
490 response
.sendError(HttpServletResponse
.SC_NOT_FOUND
, "A taxon with the uuid " + uuid
+ " does not exist");
494 HashSet
<TaxonBase
> resultset
= new HashSet
<TaxonBase
>();
496 if (tb
instanceof Taxon
){
497 Taxon taxon
= (Taxon
) tb
;
498 Set
<TaxonNode
> nodes
= taxon
.getTaxonNodes();
499 for (TaxonNode taxonNode
: nodes
) {
500 if (taxonNode
.getClassification().compareTo(classification_uuid
) == 0){
501 resultset
.add((Taxon
) tb
);
504 if (resultset
.size() > 1){
505 //error!! A taxon is not allow to have more taxonnodes for a given classification
506 response
.sendError(HttpServletResponse
.SC_INTERNAL_SERVER_ERROR
,
507 "A taxon with the uuid " + uuid
+ " has more than one taxon node for the given classification" + classification_uuid
);
510 Synonym syn
= (Synonym
) tb
;
511 for(TaxonBase accepted
: syn
.getAcceptedTaxa()){
512 tb
= service
.load(accepted
.getUuid(), SIMPLE_TAXON_WITH_NODES_INIT_STRATEGY
);
513 if (tb
instanceof Taxon
){
514 Taxon taxon
= (Taxon
) tb
;
515 Set
<TaxonNode
> nodes
= taxon
.getTaxonNodes();
516 for (TaxonNode taxonNode
: nodes
) {
517 if (taxonNode
.getClassification().compareTo(classification_uuid
) == 0){
518 resultset
.add((Taxon
) tb
);
521 if (resultset
.size() > 1){
522 //error!! A taxon is not allow to have more taxonnodes for a given classification
523 response
.sendError(HttpServletResponse
.SC_INTERNAL_SERVER_ERROR
,
524 "A taxon with the uuid " + uuid
+ " has more than one taxon node for the given classification" + classification_uuid
);
527 //ERROR!! perhaps missapplied name????
528 //syn.getRelationType((Taxon)accepted);
534 if(tb instanceof Taxon){
535 //the taxon already is accepted
536 //FIXME take the current view into account once views are implemented!!!
537 resultset.add((Taxon)tb);
539 Synonym syn = (Synonym)tb;
540 for(TaxonBase accepted : syn.getAcceptedTaxa()){
541 accepted = service.load(accepted.getUuid(), SIMPLE_TAXON_INIT_STRATEGY);
542 resultset.add(accepted);
550 * Get the list of {@link TaxonRelationship}s for the given
551 * {@link TaxonBase} instance identified by the <code>{taxon-uuid}</code>.
553 * URI: <b>/{datasource-name}/portal/taxon/{taxon-uuid}/taxonRelationships</b>
557 * @return a List of {@link TaxonRelationship} entities which are initialized
558 * using the following initialization strategy:
559 * {@link #TAXONRELATIONSHIP_INIT_STRATEGY}
560 * @throws IOException
563 value
= {"taxonRelationships"},
564 method
= RequestMethod
.GET
)
565 public List
<TaxonRelationship
> doGetTaxonRelations(@PathVariable("uuid") UUID uuid
,
566 HttpServletRequest request
, HttpServletResponse response
)throws IOException
{
568 logger
.info("doGetTaxonRelations()" + request
.getServletPath());
569 Taxon taxon
= getCdmBaseInstance(Taxon
.class, uuid
, response
, (List
<String
>)null);
570 List
<TaxonRelationship
> toRelationships
= service
.listToTaxonRelationships(taxon
, null, null, null, null, TAXONRELATIONSHIP_INIT_STRATEGY
);
571 List
<TaxonRelationship
> fromRelationships
= service
.listFromTaxonRelationships(taxon
, null, null, null, null, TAXONRELATIONSHIP_INIT_STRATEGY
);
573 List
<TaxonRelationship
> allRelationships
= new ArrayList
<TaxonRelationship
>(toRelationships
.size() + fromRelationships
.size());
574 allRelationships
.addAll(toRelationships
);
575 allRelationships
.addAll(fromRelationships
);
577 return allRelationships
;
581 * Get the list of {@link NameRelationship}s of the Name associated with the
582 * {@link TaxonBase} instance identified by the <code>{taxon-uuid}</code>.
584 * URI: <b>/{datasource-name}/portal/taxon/{taxon-uuid}/nameRelationships</b>
588 * @return a List of {@link NameRelationship} entities which are initialized
589 * using the following initialization strategy:
590 * {@link #NAMERELATIONSHIP_INIT_STRATEGY}
591 * @throws IOException
594 value
= {"toNameRelationships"},
595 method
= RequestMethod
.GET
)
596 public List
<NameRelationship
> doGetToNameRelations(@PathVariable("uuid") UUID uuid
,
597 HttpServletRequest request
, HttpServletResponse response
)throws IOException
{
598 logger
.info("doGetNameRelations()" + request
.getServletPath());
599 TaxonBase taxonBase
= getCdmBaseInstance(TaxonBase
.class, uuid
, response
, (List
<String
>)null);
600 List
<NameRelationship
> list
= nameService
.listNameRelationships(taxonBase
.getName(), Direction
.relatedTo
, null, null, 0, null, NAMERELATIONSHIP_INIT_STRATEGY
);
601 //List<NameRelationship> list = nameService.listToNameRelationships(taxonBase.getName(), null, null, null, null, NAMERELATIONSHIP_INIT_STRATEGY);
606 * Get the list of {@link NameRelationship}s of the Name associated with the
607 * {@link TaxonBase} instance identified by the <code>{taxon-uuid}</code>.
609 * URI: <b>/{datasource-name}/portal/taxon/{taxon-uuid}/nameRelationships</b>
613 * @return a List of {@link NameRelationship} entities which are initialized
614 * using the following initialization strategy:
615 * {@link #NAMERELATIONSHIP_INIT_STRATEGY}
616 * @throws IOException
619 value
= {"fromNameRelationships"},
620 method
= RequestMethod
.GET
)
621 public List
<NameRelationship
> doGetFromNameRelations(@PathVariable("uuid") UUID uuid
,
622 HttpServletRequest request
, HttpServletResponse response
)throws IOException
{
623 logger
.info("doGetNameFromNameRelations()" + request
.getServletPath());
625 TaxonBase taxonbase
= getCdmBaseInstance(TaxonBase
.class, uuid
, response
, SIMPLE_TAXON_INIT_STRATEGY
);
626 List
<NameRelationship
> list
= nameService
.listNameRelationships(taxonbase
.getName(), Direction
.relatedFrom
, null, null, 0, null, NAMERELATIONSHIP_INIT_STRATEGY
);
627 //List<NameRelationship> list = nameService.listFromNameRelationships(taxonbase.getName(), null, null, null, null, NAMERELATIONSHIP_INIT_STRATEGY);
632 * Get the list of {@link TypeDesignationBase}s of the
633 * {@link TaxonBase} instance identified by the <code>{taxon-uuid}</code>.
635 * URI: <b>/{datasource-name}/portal/taxon/{taxon-uuid}/nameTypeDesignations</b>
639 * @return a List of {@link TypeDesignationBase} entities which are initialized
640 * using the following initialization strategy:
641 * {@link #TYPEDESIGNATION_INIT_STRATEGY}
642 * @throws IOException
643 * @Deprecated use /name/{uuid}/typeDesignations & /derivedunitfacade/{uuid} instead
644 * also see http://dev.e-taxonomy.eu/trac/ticket/2280
648 value
= {"nameTypeDesignations"},
649 method
= RequestMethod
.GET
)
650 public List
<TypeDesignationBase
> doGetNameTypeDesignations(@PathVariable("uuid") UUID uuid
,
651 HttpServletRequest request
, HttpServletResponse response
)throws IOException
{
652 logger
.info("doGetNameTypeDesignations()" + request
.getServletPath());
653 Taxon taxon
= getCdmBaseInstance(Taxon
.class, uuid
, response
, SIMPLE_TAXON_INIT_STRATEGY
);
654 Pager
<TypeDesignationBase
> p
= nameService
.getTypeDesignations(taxon
.getName(), null, null, null, TYPEDESIGNATION_INIT_STRATEGY
);
655 return p
.getRecords();
658 @RequestMapping(value
= "taxonNodes", method
= RequestMethod
.GET
)
659 public Set
<TaxonNode
> doGetTaxonNodes(
660 @PathVariable("uuid") UUID uuid
,
661 HttpServletRequest request
,
662 HttpServletResponse response
) throws IOException
{
663 TaxonBase tb
= service
.load(uuid
, TAXONNODE_INIT_STRATEGY
);
664 if(tb
instanceof Taxon
){
665 return ((Taxon
)tb
).getTaxonNodes();
667 HttpStatusMessage
.UUID_REFERENCES_WRONG_TYPE
.send(response
);
673 * Get the list of {@link TaxonDescription}s of the
674 * {@link Taxon} instance identified by the <code>{taxon-uuid}</code>.
676 * URI: <b>/{datasource-name}/portal/taxon/{taxon-uuid}/descriptions</b>
680 * @return a List of {@link TaxonDescription} entities which are initialized
681 * using the following initialization strategy:
682 * {@link #TAXONDESCRIPTION_INIT_STRATEGY}
683 * @throws IOException
686 value
= {"descriptions"},
687 method
= RequestMethod
.GET
)
688 public List
<TaxonDescription
> doGetDescriptions(
689 @PathVariable("uuid") UUID uuid
,
690 @RequestParam(value
= "markerTypes", required
= false) UuidList markerTypeUUIDs
,
691 // @PathVariable("markerTypes") String markerTypeUUIDs,
692 HttpServletRequest request
,
693 HttpServletResponse response
)throws IOException
{
695 logger
.info("doGetDescriptions()" + request
.getServletPath());
697 List
<DefinedTermBase
> markerTypeTerms
= new ArrayList
<DefinedTermBase
>();
698 Set
<UUID
> sMarkerTypeUUIDs
= new HashSet
<UUID
>();
699 //if(markerTypeUUIDs !=null) {
700 // if(!markerTypeUUIDs.equals("test") && !markerTypeUUIDs.equals("$1") ) {
701 // String[] strMarkerTypeUUIDs = markerTypeUUIDs.split(",");
702 // for (String uuidMarkerType : strMarkerTypeUUIDs) {
703 // sMarkerTypeUUIDs.add(UUID.fromString(uuidMarkerType));
706 // markerTypeTerms = markerTypeService.find(sMarkerTypeUUIDs);
708 if(markerTypeUUIDs
!= null && !markerTypeUUIDs
.isEmpty()){
709 markerTypeTerms
= markerTypeService
.find(sMarkerTypeUUIDs
);
710 } else if(markerTypeUUIDs
.isEmpty()){
711 markerTypeTerms
= new ArrayList
<DefinedTermBase
>();
713 Set
<MarkerType
> markerTypes
= new HashSet
<MarkerType
>();
714 List
<TaxonDescription
> descriptions
= new ArrayList
<TaxonDescription
>();
715 for (DefinedTermBase markerTypeTerm
: markerTypeTerms
) {
716 markerTypes
.add((MarkerType
)markerTypeTerm
);
718 Taxon t
= getCdmBaseInstance(Taxon
.class, uuid
, response
, (List
<String
>)null);
719 if (markerTypes
== null) {
721 Pager
<TaxonDescription
> p
= descriptionService
.getTaxonDescriptions(t
, null, null, null, null, TAXONDESCRIPTION_INIT_STRATEGY
);
722 descriptions
= p
.getRecords();
725 else if (sMarkerTypeUUIDs
.isEmpty()) {
726 descriptions
= descriptionService
.listTaxonDescriptions(t
, null, null, markerTypes
, null, null, TAXONUSEDESCRIPTION_INIT_STRATEGY
);
730 descriptions
= descriptionService
.listTaxonDescriptions(t
, null, null, markerTypes
, null, null, TAXONUSEDESCRIPTION_INIT_STRATEGY
);
732 /*Set<MarkerType> sMarkerTypes = new HashSet<MarkerType>(markerTypeService.listByTermClass(MarkerType.class, null, null, null, null));
733 //Set<MarkerType> markerTypesToUse = new HashSet<MarkerType>(markerTypeService.);
734 //MarkerType useMarkerType = (MarkerType) markerTypeService.find(UUID.fromString("2e6e42d9-e92a-41f4-899b-03c0ac64f059"));
735 MarkerType useMarkerType = (MarkerType) markerTypeService.find(UUID.fromString("2e6e42d9-e92a-41f4-899b-03c0ac64f039"));
737 markerTypes.remove(useMarkerType);
739 //List<TaxonDescription> descriptions = descriptionService.listTaxonDescriptions(t, null, null, markerTypes, null, null, TAXONUSEDESCRIPTION_INIT_STRATEGY);
740 Pager<TaxonDescription> p = descriptionService.getTaxonDescriptions(t, null, null, null, null, TAXONDESCRIPTION_INIT_STRATEGY);
741 //List<TaxonDescription> descriptions = p.getRecords();
742 Iterator<TaxonDescription> itr = descriptions.iterator();
743 //for(TaxonDescription taxonDesc: descriptions) {
744 while (itr.hasNext()) {
745 TaxonDescription taxonDesc = (TaxonDescription) itr.next();
746 Pager<Marker> pMarkers = descriptionService.getMarkers(taxonDesc, null, null, null, null, null);
747 Pager<Marker> useMarkers = markerService.page(useMarkerType, null, null, null, null);
748 List<DefinedTermBase> useMarkers2 = markerTypeService.list(MarkerType.class, null, null, null, null);
749 if(pMarkers.getCount() != 0) {
750 List<Marker> testMarkers = pMarkers.getRecords();
751 List<Marker> testUseMarkers = useMarkers.getRecords();
752 for (Marker marker: testMarkers) {
753 for (Marker useMaker: testUseMarkers){
754 if(marker.equals(useMaker)) {
761 //return p.getRecords();
765 @RequestMapping(value
= "useDescriptions", method
= RequestMethod
.GET
)
766 public List
<TaxonDescription
> doGetUseDescriptions(
767 @PathVariable("uuid") UUID uuid
,
768 HttpServletRequest request
,
769 HttpServletResponse response
) throws IOException
{
770 logger
.info("doGetDescriptionElements() - " + request
.getServletPath());
772 //ModelAndView mv = new ModelAndView();
773 Taxon t
= getCdmBaseInstance(Taxon
.class, uuid
, response
, (List
<String
>)null);
775 //MarkerType useMarkerType = (MarkerType) markerTypeService.find(UUID.fromString("2e6e42d9-e92a-41f4-899b-03c0ac64f059"));
776 MarkerType useMarkerType
= (MarkerType
) markerTypeService
.find(UUID
.fromString("2e6e42d9-e92a-41f4-899b-03c0ac64f039"));
778 //find(UUID.fromString("2e6e42d9-e92a-41f4-899b-03c0ac64f059"));
779 Set
<MarkerType
> markerTypes
= new HashSet
<MarkerType
>();
780 markerTypes
.add(useMarkerType
);
781 List
<TaxonDescription
> descriptionElements
= descriptionService
.listTaxonDescriptions(t
, null, null, markerTypes
, null, null, TAXONUSEDESCRIPTION_INIT_STRATEGY
);
782 //getDescriptionElements(description, features, type, pageSize, pageNumber, propertyPaths) load(uuid);
784 /*if(!(description instanceof TaxonDescription)){
785 HttpStatusMessage.UUID_REFERENCES_WRONG_TYPE.send(response);
786 // will terminate thread
789 //boolean hasStructuredData = service. hasStructuredData(description);
791 //mv.addObject(hasStructuredData);
793 return descriptionElements
;
796 @RequestMapping(value
= "descriptions/elementsByType/{classSimpleName}", method
= RequestMethod
.GET
)
797 public ModelAndView
doGetDescriptionElementsByType(
798 @PathVariable("uuid") UUID uuid
,
799 @PathVariable("classSimpleName") String classSimpleName
,
800 //@RequestParam(value = "markerTypes", required = false, defaultValue = "false") Set<UUID> markerTypes,
801 // @PathVariable(value = "markerTypes") String markerTypes,
802 @RequestParam(value
= "markerTypes", required
= false) UuidList markerTypeUUIDs
,
803 @RequestParam(value
= "count", required
= false, defaultValue
= "false") Boolean doCount
,
804 HttpServletRequest request
,
805 HttpServletResponse response
) throws IOException
{
806 logger
.info("doGetDescriptionElementsByType() - " + request
.getServletPath());
808 ModelAndView mv
= new ModelAndView();
810 List
<DescriptionElementBase
> allElements
= new ArrayList
<DescriptionElementBase
>();
811 List
<DescriptionElementBase
> elements
;
814 List
<String
> initStrategy
= doCount ?
null : DESCRIPTION_ELEMENT_INIT_STRATEGY
;
816 List
<TaxonDescription
> taxonDescriptions
= doGetDescriptions(uuid
, markerTypeUUIDs
, request
, response
);
819 type
= Class
.forName("eu.etaxonomy.cdm.model.description."
821 if (taxonDescriptions
!= null) {
822 for (TaxonDescription description
: taxonDescriptions
) {
823 elements
= descriptionService
.listDescriptionElements(description
, null, type
, null, 0, initStrategy
);
824 allElements
.addAll(elements
);
825 count
+= elements
.size();
829 } catch (ClassNotFoundException e
) {
830 HttpStatusMessage
.fromString(e
.getLocalizedMessage()).send(response
);
835 mv
.addObject(allElements
);
840 // @RequestMapping(value = "specimens", method = RequestMethod.GET)
841 // public ModelAndView doGetSpecimens(
842 // @PathVariable("uuid") UUID uuid,
843 // HttpServletRequest request,
844 // HttpServletResponse response) throws IOException, ClassNotFoundException {
845 // logger.info("doGetSpecimens() - " + request.getServletPath());
847 // ModelAndView mv = new ModelAndView();
849 // List<DerivedUnitFacade> derivedUnitFacadeList = new ArrayList<DerivedUnitFacade>();
851 // // find speciemens in the TaxonDescriptions
852 // List<TaxonDescription> taxonDescriptions = doGetDescriptions(uuid, request, response);
853 // if (taxonDescriptions != null) {
855 // for (TaxonDescription description : taxonDescriptions) {
856 // derivedUnitFacadeList.addAll( occurrenceService.listDerivedUnitFacades(description, null) );
859 // // TODO find speciemens in the NameDescriptions ??
861 // // TODO also find type specimens
863 // mv.addObject(derivedUnitFacadeList);
869 * Get the {@link Media} attached to the {@link Taxon} instance
870 * identified by the <code>{taxon-uuid}</code>.
872 * Usage /{datasource-name}/portal/taxon/{taxon-
873 * uuid}/media/{mime type
874 * list}/{size}[,[widthOrDuration}][,{height}]/
878 * <li><b>{mime type list}</b>: a comma separated list of mime types, in the
879 * order of preference. The forward slashes contained in the mime types must
880 * be replaced by a colon. Regular expressions can be used. Each media
881 * associated with this given taxon is being searched whereas the first
882 * matching mime type matching a representation always rules.</li>
883 * <li><b>{size},{widthOrDuration},{height}</b>: <i>not jet implemented</i>
884 * valid values are an integer or the asterisk '*' as a wildcard</li>
889 * @return a List of {@link Media} entities which are initialized
890 * using the following initialization strategy:
891 * {@link #TAXONDESCRIPTION_INIT_STRATEGY}
892 * @throws IOException
896 method
= RequestMethod
.GET
)
897 public List
<Media
> doGetMedia(
898 @PathVariable("uuid") UUID uuid
,
899 @RequestParam(value
= "type", required
= false) Class
<?
extends MediaRepresentationPart
> type
,
900 @RequestParam(value
= "mimeTypes", required
= false) String
[] mimeTypes
,
901 @RequestParam(value
= "widthOrDuration", required
= false) Integer widthOrDuration
,
902 @RequestParam(value
= "height", required
= false) Integer height
,
903 @RequestParam(value
= "size", required
= false) Integer size
,
904 HttpServletRequest request
, HttpServletResponse response
) throws IOException
{
906 logger
.info("doGetMedia()" + request
.getServletPath());
907 Taxon t
= getCdmBaseInstance(Taxon
.class, uuid
, response
, (List
<String
>)null);
908 String path
= request
.getServletPath();
909 List
<Media
> returnMedia
= getMediaForTaxon(t
, type
, mimeTypes
, widthOrDuration
, height
, size
);
914 value
= {"subtree/media"},
915 method
= RequestMethod
.GET
)
916 public List
<Media
> doGetSubtreeMedia(
917 @PathVariable("uuid") UUID uuid
,
918 @RequestParam(value
= "type", required
= false) Class
<?
extends MediaRepresentationPart
> type
,
919 @RequestParam(value
= "mimeTypes", required
= false) String
[] mimeTypes
,
920 @RequestParam(value
= "widthOrDuration", required
= false) Integer widthOrDuration
,
921 @RequestParam(value
= "height", required
= false) Integer height
,
922 @RequestParam(value
= "size", required
= false) Integer size
,
923 HttpServletRequest request
, HttpServletResponse response
)throws IOException
{
924 logger
.info("doGetMedia()" + request
.getServletPath());
925 Taxon taxon
= getCdmBaseInstance(Taxon
.class, uuid
, response
, TAXON_WITH_NODES_INIT_STRATEGY
);
926 String requestPath
= request
.getServletPath();
927 List
<Media
> returnMedia
= getMediaForTaxon(taxon
, type
, mimeTypes
, widthOrDuration
, height
, size
);
929 //looking for all medias of genus
930 if (taxon
.getTaxonNodes().size()>0){
931 Set
<TaxonNode
> nodes
= taxon
.getTaxonNodes();
932 Iterator
<TaxonNode
> iterator
= nodes
.iterator();
934 node
= iterator
.next();
935 //Check if TaxonNode belongs to the current tree
937 node
= classificationService
.loadTaxonNode(node
, TAXONNODE_WITHTAXON_INIT_STRATEGY
);
938 Set
<TaxonNode
> children
= node
.getChildNodes();
940 for (TaxonNode child
: children
){
941 childTaxon
= child
.getTaxon();
942 childTaxon
= (Taxon
)taxonService
.load(childTaxon
.getUuid(), null);
943 returnMedia
.addAll(getMediaForTaxon(childTaxon
, type
, mimeTypes
, widthOrDuration
, height
, size
));
950 private List
<Media
> getMediaForTaxon(Taxon taxon
, Class
<?
extends MediaRepresentationPart
> type
, String
[] mimeTypes
,
951 Integer widthOrDuration
, Integer height
, Integer size
){
953 Pager
<TaxonDescription
> p
=
954 descriptionService
.getTaxonDescriptions(taxon
, null, null, null, null, TAXONDESCRIPTION_MEDIA_INIT_STRATEGY
);
956 // pars the media and quality parameters
959 // collect all media of the given taxon
960 boolean limitToGalleries
= false;
961 List
<Media
> taxonMedia
= new ArrayList
<Media
>();
962 List
<Media
> taxonGalleryMedia
= new ArrayList
<Media
>();
963 for(TaxonDescription desc
: p
.getRecords()){
965 if(desc
.isImageGallery()){
966 for(DescriptionElementBase element
: desc
.getElements()){
967 for(Media media
: element
.getMedia()){
968 taxonGalleryMedia
.add(media
);
971 } else if(!limitToGalleries
){
972 for(DescriptionElementBase element
: desc
.getElements()){
973 for(Media media
: element
.getMedia()){
974 taxonMedia
.add(media
);
981 taxonGalleryMedia
.addAll(taxonMedia
);
983 List
<Media
> returnMedia
= MediaUtils
.findPreferredMedia(taxonGalleryMedia
, type
,
984 mimeTypes
, null, widthOrDuration
, height
, size
);
990 // ---------------------- code snippet preserved for possible later use --------------------
992 // value = {"/*/portal/taxon/*/descriptions"},
993 // method = RequestMethod.GET)
994 // public List<TaxonDescription> doGetDescriptionsbyFeatureTree(HttpServletRequest request, HttpServletResponse response)throws IOException {
995 // TaxonBase tb = getCdmBase(request, response, null, Taxon.class);
996 // if(tb instanceof Taxon){
997 // //T O D O this is a quick and dirty implementation -> generalize
998 // UUID featureTreeUuid = readValueUuid(request, featureTreeUuidPattern);
1000 // FeatureTree featureTree = descriptionService.getFeatureTreeByUuid(featureTreeUuid);
1001 // Pager<TaxonDescription> p = descriptionService.getTaxonDescriptions((Taxon)tb, null, null, null, null, TAXONDESCRIPTION_INIT_STRATEGY);
1002 // List<TaxonDescription> descriptions = p.getRecords();
1004 // if(!featureTree.isDescriptionSeparated()){
1006 // TaxonDescription superDescription = TaxonDescription.NewInstance();
1007 // //put all descriptionElements in superDescription and make it invisible
1008 // for(TaxonDescription description: descriptions){
1009 // for(DescriptionElementBase element: description.getElements()){
1010 // superDescription.addElement(element);
1013 // List<TaxonDescription> separatedDescriptions = new ArrayList<TaxonDescription>(descriptions.size());
1014 // separatedDescriptions.add(superDescription);
1015 // return separatedDescriptions;
1017 // return descriptions;
1020 // response.sendError(HttpServletResponse.SC_NOT_FOUND, "invalid type; Taxon expected but " + tb.getClass().getSimpleName() + " found.");