2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
10 package eu
.etaxonomy
.cdm
.remote
.controller
;
12 import java
.io
.IOException
;
13 import java
.util
.ArrayList
;
14 import java
.util
.Arrays
;
15 import java
.util
.HashSet
;
16 import java
.util
.List
;
18 import java
.util
.UUID
;
20 import javax
.persistence
.EntityNotFoundException
;
21 import javax
.servlet
.http
.HttpServletRequest
;
22 import javax
.servlet
.http
.HttpServletResponse
;
24 import org
.apache
.log4j
.Logger
;
25 import org
.springframework
.beans
.factory
.annotation
.Autowired
;
26 import org
.springframework
.stereotype
.Controller
;
27 import org
.springframework
.web
.bind
.WebDataBinder
;
28 import org
.springframework
.web
.bind
.annotation
.PathVariable
;
29 import org
.springframework
.web
.bind
.annotation
.RequestMapping
;
30 import org
.springframework
.web
.bind
.annotation
.RequestMethod
;
31 import org
.springframework
.web
.bind
.annotation
.RequestParam
;
32 import org
.springframework
.web
.servlet
.ModelAndView
;
34 import eu
.etaxonomy
.cdm
.api
.service
.IDescriptionService
;
35 import eu
.etaxonomy
.cdm
.api
.service
.INameService
;
36 import eu
.etaxonomy
.cdm
.api
.service
.IOccurrenceService
;
37 import eu
.etaxonomy
.cdm
.api
.service
.ITaxonNodeService
;
38 import eu
.etaxonomy
.cdm
.api
.service
.ITaxonService
;
39 import eu
.etaxonomy
.cdm
.api
.service
.ITermService
;
40 import eu
.etaxonomy
.cdm
.api
.service
.config
.IncludedTaxonConfiguration
;
41 import eu
.etaxonomy
.cdm
.api
.service
.dto
.IncludedTaxaDTO
;
42 import eu
.etaxonomy
.cdm
.api
.service
.pager
.Pager
;
43 import eu
.etaxonomy
.cdm
.model
.common
.MarkerType
;
44 import eu
.etaxonomy
.cdm
.model
.description
.DescriptionElementBase
;
45 import eu
.etaxonomy
.cdm
.model
.description
.TaxonDescription
;
46 import eu
.etaxonomy
.cdm
.model
.occurrence
.SpecimenOrObservationBase
;
47 import eu
.etaxonomy
.cdm
.model
.taxon
.Classification
;
48 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
49 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonBase
;
50 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonNode
;
51 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonNodeAgentRelation
;
52 import eu
.etaxonomy
.cdm
.persistence
.query
.OrderHint
;
53 import eu
.etaxonomy
.cdm
.persistence
.query
.OrderHint
.SortOrder
;
54 import eu
.etaxonomy
.cdm
.remote
.controller
.util
.PagerParameters
;
55 import eu
.etaxonomy
.cdm
.remote
.editor
.TermBasePropertyEditor
;
56 import io
.swagger
.annotations
.Api
;
59 * TODO write controller documentation
61 * @author a.kohlbecker
67 @RequestMapping(value
= {"/taxon/{uuid}"})
68 public class TaxonController
extends AbstractIdentifiableController
<TaxonBase
, ITaxonService
>
70 public static final Logger logger
= Logger
.getLogger(TaxonController
.class);
73 private IOccurrenceService occurrenceService
;
76 private INameService nameService
;
79 private ITaxonNodeService nodeService
;
82 private IDescriptionService descriptionService
;
85 private ITermService termService
;
87 protected static final List
<String
> TAXONNODE_INIT_STRATEGY
= Arrays
.asList(new String
[]{
91 public TaxonController(){
93 setInitializationStrategy(Arrays
.asList(new String
[]{
95 "name.nomenclaturalReference"
102 public void setService(ITaxonService service
) {
103 this.service
= service
;
110 public void initBinder(WebDataBinder binder
) {
111 super.initBinder(binder
);
112 binder
.registerCustomEditor(MarkerType
.class, new TermBasePropertyEditor
<>(termService
));
115 protected List
<String
> getTaxonDescriptionInitStrategy() {
116 return getInitializationStrategy();
119 protected List
<String
> getTaxonDescriptionElementInitStrategy() {
120 return getInitializationStrategy();
125 * Get the accepted {@link Taxon} for a given
126 * {@link TaxonBase} entity identified by the <code>{taxon-uuid}</code>.
128 * URI: <b>/{datasource-name}/taxon/{taxon-uuid}/accepted</b>
132 * @return a set on a list of {@link Taxon} entities which are initialized
133 * using the following initialization strategy:
134 * {@link #DEFAULT_INIT_STRATEGY}
135 * @throws IOException
137 @RequestMapping(value
= "accepted", method
= RequestMethod
.GET
)
138 public Taxon
getAcceptedFor(
139 @PathVariable("uuid") UUID uuid
,
140 @RequestParam(value
= "classificationFilter", required
= false) UUID classification_uuid
,
141 HttpServletRequest request
,
142 HttpServletResponse response
)
145 logger
.info("getAcceptedFor() " + requestPathAndQuery(request
));
150 result
= service
.findAcceptedTaxonFor(uuid
, classification_uuid
, getInitializationStrategy());
151 } catch (EntityNotFoundException e
){
152 HttpStatusMessage
.UUID_NOT_FOUND
.send(response
);
158 @RequestMapping(value
= "classifications", method
= RequestMethod
.GET
)
159 public List
<Classification
> doGetClassifications(
160 @PathVariable("uuid") UUID uuid
,
161 HttpServletRequest request
,
162 HttpServletResponse response
) throws IOException
{
164 boolean includeUnpublished
= NO_UNPUBLISHED
;
166 logger
.info("doGetClassifications(): " + request
.getRequestURI());
167 TaxonBase
<?
> taxonBase
= service
.load(uuid
);
168 taxonBase
= checkExistsAndAccess(taxonBase
, includeUnpublished
, response
);
170 return service
.listClassifications(taxonBase
, null, null, getInitializationStrategy());
173 @RequestMapping(value
= "taxonNodes", method
= RequestMethod
.GET
)
174 public Set
<TaxonNode
> doGetTaxonNodes(
175 @PathVariable("uuid") UUID uuid
,
176 HttpServletRequest request
,
177 HttpServletResponse response
) throws IOException
{
179 TaxonBase
<?
> tb
= service
.load(uuid
, NO_UNPUBLISHED
, TAXONNODE_INIT_STRATEGY
);
180 if(tb
instanceof Taxon
){
181 return ((Taxon
)tb
).getTaxonNodes();
183 HttpStatusMessage
.UUID_REFERENCES_WRONG_TYPE
.send(response
);
190 * See also {@link AgentController#doGetTaxonNodeAgentRelations(UUID, UUID, Integer, Integer, HttpServletRequest, HttpServletResponse)}
193 * @param classificationUuid
199 * @throws IOException
202 @RequestMapping(value
= "taxonNodeAgentRelations/{classification_uuid}", method
= RequestMethod
.GET
)
203 public Pager
<TaxonNodeAgentRelation
> doGetTaxonNodeAgentRelations(
204 @PathVariable("uuid") UUID uuid
,
205 @PathVariable("classification_uuid") UUID classificationUuid
,
206 @RequestParam(value
= "relType_uuid" , required
= false) UUID relTypeUuid
,
207 @RequestParam(value
= "pageNumber", required
= false) Integer pageNumber
,
208 @RequestParam(value
= "pageSize", required
= false) Integer pageSize
,
209 HttpServletRequest request
,
210 HttpServletResponse response
) throws IOException
{
212 PagerParameters pagerParams
= new PagerParameters(pageSize
, pageNumber
);
213 pagerParams
.normalizeAndValidate(response
);
215 Pager
<TaxonNodeAgentRelation
> pager
= nodeService
.pageTaxonNodeAgentRelations(uuid
, classificationUuid
,
216 null, null, relTypeUuid
, pagerParams
.getPageSize(), pagerParams
.getPageIndex(), null);
221 @RequestMapping(value
= "specimensOrObservations", method
= RequestMethod
.GET
)
222 public ModelAndView
doListSpecimensOrObservations(
223 @PathVariable("uuid") UUID uuid
,
224 HttpServletRequest request
,
225 HttpServletResponse response
) throws IOException
{
226 logger
.info("doListSpecimensOrObservations() - " + request
.getRequestURI());
228 ModelAndView mv
= new ModelAndView();
230 TaxonBase
<?
> tb
= service
.load(uuid
);
232 List
<OrderHint
> orderHints
= new ArrayList
<OrderHint
>();
233 orderHints
.add(new OrderHint("titleCache", SortOrder
.DESCENDING
));
235 if(tb
instanceof Taxon
){
236 List
<SpecimenOrObservationBase
<?
>> specimensOrObservations
= occurrenceService
.listByAssociatedTaxon(null, null, (Taxon
)tb
, null, null, null, orderHints
, null);
237 mv
.addObject(specimensOrObservations
);
239 HttpStatusMessage
.UUID_REFERENCES_WRONG_TYPE
.send(response
);
246 @RequestMapping(value
= "associatedFieldUnits", method
= RequestMethod
.GET
)
247 public Pager
<SpecimenOrObservationBase
> doGetFieldUnits(
248 @PathVariable("uuid") UUID uuid
,
249 @RequestParam(value
= "maxDepth", required
= false) Integer maxDepth
,
250 @RequestParam(value
= "pageNumber", required
= false) Integer pageNumber
,
251 @RequestParam(value
= "pageSize", required
= false) Integer pageSize
,
252 HttpServletRequest request
,
253 HttpServletResponse response
) throws IOException
{
254 logger
.info("doGetFieldUnits() - " + request
.getRequestURI());
256 TaxonBase
<?
> taxonBase
= service
.load(uuid
);
257 taxonBase
= checkExistsAndAccess(taxonBase
, NO_UNPUBLISHED
, response
);
259 List
<OrderHint
> orderHints
= new ArrayList
<>();
260 orderHints
.add(new OrderHint("titleCache", SortOrder
.ASCENDING
));
262 if(taxonBase
instanceof Taxon
){
263 PagerParameters pagerParams
= new PagerParameters(pageSize
, pageNumber
);
264 pagerParams
.normalizeAndValidate(response
);
266 return occurrenceService
.pageFieldUnitsByAssociatedTaxon(null, (Taxon
) taxonBase
, null, pagerParams
.getPageSize(), pagerParams
.getPageIndex(), orderHints
, null);
272 @RequestMapping(value
= "taggedName", method
= RequestMethod
.GET
)
273 public ModelAndView
doGetTaggedName(
274 @PathVariable("uuid") UUID uuid
,
275 HttpServletRequest request
) {
276 logger
.info("doGetDescriptionElementsByType() - " + request
.getRequestURI());
278 ModelAndView mv
= new ModelAndView();
280 TaxonBase
<?
> tb
= service
.load(uuid
, NO_UNPUBLISHED
, Arrays
.asList(new String
[] {"name"}));
281 mv
.addObject(nameService
.getTaggedName(tb
.getName().getUuid()));
286 * This webservice endpoint returns all taxa which are congruent or included in the taxon represented by the given taxon uuid.
287 * The result also returns the path to these taxa represented by the uuids of the taxon relationships types and doubtful information.
288 * If classificationUuids is set only taxa of classifications are returned which are included in the given classifications.
289 * Also the path to these taxa may not include taxa from other classifications.
291 * @param taxonUUIDString
292 * @param classificationStringList
293 * @param includeDoubtful
294 * @param onlyCongruent
298 * @throws IOException
301 @RequestMapping(value
= { "includedTaxa" }, method
= { RequestMethod
.GET
})
302 public ModelAndView
doGetIncludedTaxa(
303 @PathVariable("uuid") UUID uuid
,
304 @RequestParam(value
="classificationFilter", required
=false) final List
<String
> classificationStringList
,
305 @RequestParam(value
="includeDoubtful", required
=false) final boolean includeDoubtful
,
306 @RequestParam(value
="onlyCongruent", required
=false) final boolean onlyCongruent
,
307 HttpServletResponse response
,
308 HttpServletRequest request
) throws IOException
{
310 ModelAndView mv
= new ModelAndView();
312 * List<UUID> classificationFilter,
313 * boolean includeDoubtful,
314 * boolean onlyCongruent)
316 List
<UUID
> classificationFilter
= null;
317 if( classificationStringList
!= null ){
318 classificationFilter
= new ArrayList
<>();
319 for(String classString
:classificationStringList
){
320 classificationFilter
.add(UUID
.fromString(classString
));
323 IncludedTaxonConfiguration configuration
=
324 new IncludedTaxonConfiguration(classificationFilter
, includeDoubtful
, onlyCongruent
);
325 IncludedTaxaDTO listIncludedTaxa
= service
.listIncludedTaxa(uuid
, configuration
);
326 mv
.addObject(listIncludedTaxa
);
330 // TODO ================================================================================ //
331 // move all description and descriptionElement related methods into the according
332 // Description Controllers
335 * Get the list of {@link TaxonDescription}s of the
336 * {@link Taxon} instance identified by the <code>{taxon-uuid}</code>.
338 * URI: <b>/{datasource-name}/portal/taxon/{taxon-uuid}/descriptions</b>
342 * @return a List of {@link TaxonDescription} entities which are initialized
343 * using the following initialization strategy:
344 * {@link #TAXONDESCRIPTION_INIT_STRATEGY}
345 * @throws IOException
348 value
= {"descriptions"},
349 method
= RequestMethod
.GET
)
350 public Pager
<TaxonDescription
> doGetDescriptions(
351 @PathVariable("uuid") UUID uuid
,
352 @RequestParam(value
= "markerTypes", required
= false) List
<MarkerType
> markerTypes
,
353 HttpServletRequest request
,
354 HttpServletResponse response
)throws IOException
{
357 logger
.info("doGetDescriptions()" + requestPathAndQuery(request
));
360 Taxon taxon
= getCdmBaseInstance(Taxon
.class, uuid
, response
, (List
<String
>)null);
361 taxon
= checkExistsAndAccess(taxon
, NO_UNPUBLISHED
, response
);
363 Set
<MarkerType
> markerTypesSet
= new HashSet
<>();
364 if (markerTypes
!= null) {
365 markerTypesSet
.addAll(markerTypes
);
368 Pager
<TaxonDescription
> p
= descriptionService
.pageTaxonDescriptions(taxon
, null, null, markerTypesSet
, null, null, getTaxonDescriptionInitStrategy());
373 @RequestMapping(value
= "descriptions/elementsByType/{classSimpleName}", method
= RequestMethod
.GET
)
374 public ModelAndView
doGetDescriptionElementsByType(
375 @PathVariable("uuid") UUID uuid
,
376 @PathVariable("classSimpleName") String classSimpleName
,
377 @RequestParam(value
= "markerTypes", required
= false) List
<MarkerType
> markerTypes
,
378 @RequestParam(value
= "count", required
= false, defaultValue
= "false") Boolean doCount
,
379 HttpServletRequest request
,
380 HttpServletResponse response
) throws IOException
{
381 logger
.info("doGetDescriptionElementsByType() - " + requestPathAndQuery(request
));
384 boolean includeUnpublished
= NO_UNPUBLISHED
;
386 ModelAndView mv
= new ModelAndView();
388 List
<DescriptionElementBase
> allElements
= new ArrayList
<>();
389 List
<DescriptionElementBase
> elements
;
392 List
<String
> initStrategy
= doCount ?
null : getTaxonDescriptionElementInitStrategy();
394 Taxon taxon
= getCdmBaseInstance(Taxon
.class, uuid
, response
, (List
<String
>)null);
396 taxon
= checkExistsAndAccess(taxon
, includeUnpublished
, response
);
399 Set
<MarkerType
> markerTypesSet
= new HashSet
<>();
400 if (markerTypes
== null) {
401 markerTypesSet
.addAll(markerTypes
);
404 List
<TaxonDescription
> taxonDescriptions
= descriptionService
.listTaxonDescriptions(
405 taxon
, null, null, markerTypesSet
, null, null, null);
408 type
= Class
.forName("eu.etaxonomy.cdm.model.description."
410 if (taxonDescriptions
!= null) {
411 for (TaxonDescription description
: taxonDescriptions
) {
412 elements
= descriptionService
.listDescriptionElements(description
, null, type
, null, 0, initStrategy
);
413 allElements
.addAll(elements
);
414 count
+= elements
.size();
418 } catch (ClassNotFoundException e
) {
419 HttpStatusMessage
.create(e
.getLocalizedMessage(), 400).send(response
);
424 mv
.addObject(allElements
);
429 // TODO ================================================================================ //