cleanup and remove rows(xxx) method
[cdmlib.git] / cdmlib-remote / src / main / java / eu / etaxonomy / cdm / remote / controller / TaxonController.java
1 /**
2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
5 *
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.
8 */
9
10 package eu.etaxonomy.cdm.remote.controller;
11
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;
17 import java.util.Set;
18 import java.util.UUID;
19
20 import javax.persistence.EntityNotFoundException;
21 import javax.servlet.http.HttpServletRequest;
22 import javax.servlet.http.HttpServletResponse;
23
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;
33
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;
57
58 /**
59 * TODO write controller documentation
60 *
61 * @author a.kohlbecker
62 * @since 20.07.2009
63 *
64 */
65 @Controller
66 @Api("taxon")
67 @RequestMapping(value = {"/taxon/{uuid}"})
68 public class TaxonController extends AbstractIdentifiableController<TaxonBase, ITaxonService>
69 {
70 public static final Logger logger = Logger.getLogger(TaxonController.class);
71
72 @Autowired
73 private IOccurrenceService occurrenceService;
74
75 @Autowired
76 private INameService nameService;
77
78 @Autowired
79 private ITaxonNodeService nodeService;
80
81 @Autowired
82 private IDescriptionService descriptionService;
83
84 @Autowired
85 private ITermService termService;
86
87 protected static final List<String> TAXONNODE_INIT_STRATEGY = Arrays.asList(new String []{
88 "taxonNodes"
89 });
90
91 public TaxonController(){
92 super();
93 setInitializationStrategy(Arrays.asList(new String[]{
94 "$",
95 "name.nomenclaturalReference"
96 }
97 ));
98 }
99
100 @Override
101 @Autowired
102 public void setService(ITaxonService service) {
103 this.service = service;
104 }
105
106 /**
107 * {@inheritDoc}
108 */
109 @Override
110 public void initBinder(WebDataBinder binder) {
111 super.initBinder(binder);
112 binder.registerCustomEditor(MarkerType.class, new TermBasePropertyEditor<>(termService));
113 }
114
115 protected List<String> getTaxonDescriptionInitStrategy() {
116 return getInitializationStrategy();
117 }
118
119 protected List<String> getTaxonDescriptionElementInitStrategy() {
120 return getInitializationStrategy();
121 }
122
123
124 /**
125 * Get the accepted {@link Taxon} for a given
126 * {@link TaxonBase} entity identified by the <code>{taxon-uuid}</code>.
127 * <p>
128 * URI: <b>&#x002F;{datasource-name}&#x002F;taxon&#x002F;{taxon-uuid}&#x002F;accepted</b>
129 *
130 * @param request
131 * @param response
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
136 */
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)
143 throws IOException {
144 if(request != null){
145 logger.info("getAcceptedFor() " + requestPathAndQuery(request));
146 }
147
148 Taxon result = null;
149 try {
150 result = service.findAcceptedTaxonFor(uuid, classification_uuid, getInitializationStrategy());
151 } catch (EntityNotFoundException e){
152 HttpStatusMessage.UUID_NOT_FOUND.send(response);
153 }
154
155 return result;
156 }
157
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 {
163
164 boolean includeUnpublished = NO_UNPUBLISHED;
165
166 logger.info("doGetClassifications(): " + request.getRequestURI());
167 TaxonBase<?> taxonBase = service.load(uuid);
168 taxonBase = checkExistsAndAccess(taxonBase, includeUnpublished, response);
169
170 return service.listClassifications(taxonBase, null, null, getInitializationStrategy());
171 }
172
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 {
178
179 TaxonBase<?> tb = service.load(uuid, NO_UNPUBLISHED, TAXONNODE_INIT_STRATEGY);
180 if(tb instanceof Taxon){
181 return ((Taxon)tb).getTaxonNodes();
182 } else {
183 HttpStatusMessage.UUID_REFERENCES_WRONG_TYPE.send(response);
184 return null;
185 }
186 }
187
188 /**
189 *
190 * See also {@link AgentController#doGetTaxonNodeAgentRelations(UUID, UUID, Integer, Integer, HttpServletRequest, HttpServletResponse)}
191 *
192 * @param uuid
193 * @param classificationUuid
194 * @param pageNumber
195 * @param pageSize
196 * @param request
197 * @param response
198 * @return
199 * @throws IOException
200 *
201 */
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 {
211
212 PagerParameters pagerParams = new PagerParameters(pageSize, pageNumber);
213 pagerParams.normalizeAndValidate(response);
214
215 Pager<TaxonNodeAgentRelation> pager = nodeService.pageTaxonNodeAgentRelations(uuid, classificationUuid,
216 null, null, relTypeUuid, pagerParams.getPageSize(), pagerParams.getPageIndex(), null);
217 return pager;
218 }
219
220
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());
227
228 ModelAndView mv = new ModelAndView();
229
230 TaxonBase<?> tb = service.load(uuid);
231
232 List<OrderHint> orderHints = new ArrayList<OrderHint>();
233 orderHints.add(new OrderHint("titleCache", SortOrder.DESCENDING));
234
235 if(tb instanceof Taxon){
236 List<SpecimenOrObservationBase<?>> specimensOrObservations = occurrenceService.listByAssociatedTaxon(null, null, (Taxon)tb, null, null, null, orderHints, null);
237 mv.addObject(specimensOrObservations);
238 } else {
239 HttpStatusMessage.UUID_REFERENCES_WRONG_TYPE.send(response);
240 return null;
241 }
242
243 return mv;
244 }
245
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());
255
256 TaxonBase<?> taxonBase = service.load(uuid);
257 taxonBase = checkExistsAndAccess(taxonBase, NO_UNPUBLISHED, response);
258
259 List<OrderHint> orderHints = new ArrayList<>();
260 orderHints.add(new OrderHint("titleCache", SortOrder.ASCENDING));
261
262 if(taxonBase instanceof Taxon){
263 PagerParameters pagerParams = new PagerParameters(pageSize, pageNumber);
264 pagerParams.normalizeAndValidate(response);
265
266 return occurrenceService.pageFieldUnitsByAssociatedTaxon(null, (Taxon) taxonBase, null, pagerParams.getPageSize(), pagerParams.getPageIndex(), orderHints, null);
267 }else{
268 return null;
269 }
270 }
271
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());
277
278 ModelAndView mv = new ModelAndView();
279
280 TaxonBase<?> tb = service.load(uuid, NO_UNPUBLISHED, Arrays.asList(new String[] {"name"}));
281 mv.addObject(nameService.getTaggedName(tb.getName().getUuid()));
282 return mv;
283 }
284
285 /**
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.
290 *
291 * @param taxonUUIDString
292 * @param classificationStringList
293 * @param includeDoubtful
294 * @param onlyCongruent
295 * @param response
296 * @param request
297 * @return
298 * @throws IOException
299 */
300
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 {
309
310 ModelAndView mv = new ModelAndView();
311 /**
312 * List<UUID> classificationFilter,
313 * boolean includeDoubtful,
314 * boolean onlyCongruent)
315 */
316 List<UUID> classificationFilter = null;
317 if( classificationStringList != null ){
318 classificationFilter = new ArrayList<>();
319 for(String classString :classificationStringList){
320 classificationFilter.add(UUID.fromString(classString));
321 }
322 }
323 IncludedTaxonConfiguration configuration =
324 new IncludedTaxonConfiguration(classificationFilter, includeDoubtful, onlyCongruent);
325 IncludedTaxaDTO listIncludedTaxa = service.listIncludedTaxa(uuid, configuration);
326 mv.addObject(listIncludedTaxa);
327 return mv;
328 }
329
330 // TODO ================================================================================ //
331 // move all description and descriptionElement related methods into the according
332 // Description Controllers
333
334 /**
335 * Get the list of {@link TaxonDescription}s of the
336 * {@link Taxon} instance identified by the <code>{taxon-uuid}</code>.
337 * <p>
338 * URI: <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}&#x002F;descriptions</b>
339 *
340 * @param request
341 * @param response
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
346 */
347 @RequestMapping(
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 {
355
356 if(request != null){
357 logger.info("doGetDescriptions()" + requestPathAndQuery(request));
358 }
359
360 Taxon taxon = getCdmBaseInstance(Taxon.class, uuid, response, (List<String>)null);
361 taxon = checkExistsAndAccess(taxon, NO_UNPUBLISHED, response);
362
363 Set<MarkerType> markerTypesSet = new HashSet<>();
364 if (markerTypes != null) {
365 markerTypesSet.addAll(markerTypes);
366 }
367
368 Pager<TaxonDescription> p = descriptionService.pageTaxonDescriptions(taxon, null, null, markerTypesSet, null, null, getTaxonDescriptionInitStrategy());
369
370 return p;
371 }
372
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));
382
383
384 boolean includeUnpublished = NO_UNPUBLISHED;
385
386 ModelAndView mv = new ModelAndView();
387
388 List<DescriptionElementBase> allElements = new ArrayList<>();
389 List<DescriptionElementBase> elements;
390 int count = 0;
391
392 List<String> initStrategy = doCount ? null : getTaxonDescriptionElementInitStrategy();
393
394 Taxon taxon = getCdmBaseInstance(Taxon.class, uuid, response, (List<String>)null);
395
396 taxon = checkExistsAndAccess(taxon, includeUnpublished, response);
397
398
399 Set<MarkerType> markerTypesSet = new HashSet<>();
400 if (markerTypes == null) {
401 markerTypesSet.addAll(markerTypes);
402 }
403
404 List<TaxonDescription> taxonDescriptions = descriptionService.listTaxonDescriptions(
405 taxon, null, null, markerTypesSet, null, null, null);
406 try {
407 Class type;
408 type = Class.forName("eu.etaxonomy.cdm.model.description."
409 + classSimpleName);
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();
415 }
416
417 }
418 } catch (ClassNotFoundException e) {
419 HttpStatusMessage.create(e.getLocalizedMessage(), 400).send(response);
420 }
421 if(doCount){
422 mv.addObject(count);
423 } else {
424 mv.addObject(allElements);
425 }
426 return mv;
427 }
428
429 // TODO ================================================================================ //
430
431 }