Project

General

Profile

Download (27 KB) Statistics
| Branch: | Tag: | Revision:
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
import java.util.stream.Collectors;
20

    
21
import javax.persistence.EntityNotFoundException;
22
import javax.servlet.http.HttpServletRequest;
23
import javax.servlet.http.HttpServletResponse;
24

    
25
import org.apache.log4j.Logger;
26
import org.springframework.beans.factory.annotation.Autowired;
27
import org.springframework.stereotype.Controller;
28
import org.springframework.web.bind.WebDataBinder;
29
import org.springframework.web.bind.annotation.PathVariable;
30
import org.springframework.web.bind.annotation.RequestMapping;
31
import org.springframework.web.bind.annotation.RequestMethod;
32
import org.springframework.web.bind.annotation.RequestParam;
33
import org.springframework.web.servlet.ModelAndView;
34

    
35
import eu.etaxonomy.cdm.api.service.IDescriptionService;
36
import eu.etaxonomy.cdm.api.service.INameService;
37
import eu.etaxonomy.cdm.api.service.IOccurrenceService;
38
import eu.etaxonomy.cdm.api.service.ITaxonNodeService;
39
import eu.etaxonomy.cdm.api.service.ITaxonService;
40
import eu.etaxonomy.cdm.api.service.ITermService;
41
import eu.etaxonomy.cdm.api.service.config.FindOccurrencesConfigurator;
42
import eu.etaxonomy.cdm.api.service.config.IncludedTaxonConfiguration;
43
import eu.etaxonomy.cdm.api.service.dto.FieldUnitDTO;
44
import eu.etaxonomy.cdm.api.service.dto.IncludedTaxaDTO;
45
import eu.etaxonomy.cdm.api.service.dto.SpecimenOrObservationBaseDTO;
46
import eu.etaxonomy.cdm.api.service.dto.TaxonRelationshipsDTO;
47
import eu.etaxonomy.cdm.api.service.pager.Pager;
48
import eu.etaxonomy.cdm.exception.UnpublishedException;
49
import eu.etaxonomy.cdm.model.common.CdmBase;
50
import eu.etaxonomy.cdm.model.common.MarkerType;
51
import eu.etaxonomy.cdm.model.common.RelationshipBase.Direction;
52
import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
53
import eu.etaxonomy.cdm.model.description.DescriptionType;
54
import eu.etaxonomy.cdm.model.description.TaxonDescription;
55
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
56
import eu.etaxonomy.cdm.model.taxon.Classification;
57
import eu.etaxonomy.cdm.model.taxon.Synonym;
58
import eu.etaxonomy.cdm.model.taxon.Taxon;
59
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
60
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
61
import eu.etaxonomy.cdm.model.taxon.TaxonNodeAgentRelation;
62
import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;
63
import eu.etaxonomy.cdm.model.term.DefinedTermBase;
64
import eu.etaxonomy.cdm.persistence.dao.initializer.EntityInitStrategy;
65
import eu.etaxonomy.cdm.persistence.dto.TaxonNodeDto;
66
import eu.etaxonomy.cdm.persistence.query.OrderHint;
67
import eu.etaxonomy.cdm.persistence.query.OrderHint.SortOrder;
68
import eu.etaxonomy.cdm.remote.controller.util.PagerParameters;
69
import eu.etaxonomy.cdm.remote.dto.common.StringResultDTO;
70
import eu.etaxonomy.cdm.remote.editor.TermBasePropertyEditor;
71
import eu.etaxonomy.cdm.remote.editor.UuidList;
72
import io.swagger.annotations.Api;
73

    
74
/**
75
 * TODO write controller documentation
76
 *
77
 * @author a.kohlbecker
78
 * @since 20.07.2009
79
 *
80
 */
81
@Controller
82
@Api("taxon")
83
@RequestMapping(value = {"/taxon/{uuid}"})
84
public class TaxonController extends AbstractIdentifiableController<TaxonBase, ITaxonService>{
85

    
86
    public static final Logger logger = Logger.getLogger(TaxonController.class);
87

    
88
    @Autowired
89
    private IOccurrenceService occurrenceService;
90

    
91
    @Autowired
92
    private INameService nameService;
93

    
94
    @Autowired
95
    private ITaxonNodeService nodeService;
96

    
97
    @Autowired
98
    private IDescriptionService descriptionService;
99

    
100
    @Autowired
101
    private ITermService termService;
102

    
103
    protected static final EntityInitStrategy TAXONNODE_INIT_STRATEGY = new EntityInitStrategy(Arrays.asList(new String []{
104
            "taxonNodes.classification",
105
            "taxonNodes.parent",
106
            "taxonNodes.taxon.name",
107
            "taxonNodes.taxon.secSource.citation",
108
            "acceptedTaxon.taxonNodes.classification"
109
    }));
110

    
111
    public TaxonController(){
112
        super();
113
        setInitializationStrategy(Arrays.asList(new String[]{
114
                "$",
115
                "name.nomenclaturalSource.citation"
116
                }
117
        ));
118
    }
119

    
120
    @Override
121
    @Autowired
122
    public void setService(ITaxonService service) {
123
        this.service = service;
124
    }
125

    
126
    @Override
127
    public void initBinder(WebDataBinder binder) {
128
        super.initBinder(binder);
129
        binder.registerCustomEditor(MarkerType.class, new TermBasePropertyEditor<>(termService));
130
    }
131

    
132
    protected List<String> getTaxonDescriptionInitStrategy() {
133
        return getInitializationStrategy(); // return Arrays.asList("$", "")
134
    }
135

    
136
    protected List<String> getTaxonDescriptionElementInitStrategy() {
137
        return getInitializationStrategy();
138
    }
139

    
140
    @RequestMapping(params="subtree", method = RequestMethod.GET)
141
    public TaxonBase<?> doGet(@PathVariable("uuid") UUID uuid,
142
            @RequestParam(value = "subtree", required = true) UUID subtreeUuid,  //if subtree does not exist the base class method is used, therefore required
143
            HttpServletRequest request,
144
            HttpServletResponse response) throws IOException {
145
        if(request != null) {
146
            logger.info("doGet() " + requestPathAndQuery(request));
147
        }
148
        //TODO do we want to allow Synonyms at all? Maybe needs initialization
149
        EntityInitStrategy initStrategy = new EntityInitStrategy(getInitializationStrategy());
150
        initStrategy.extend(null, getTaxonNodeInitStrategy(), false);
151
        TaxonBase<?> taxonBase = getCdmBaseInstance(uuid, response, initStrategy.getPropertyPaths());
152
        //TODO we should move subtree check down to service or persistence
153
        TaxonNode subtree = getSubtreeOrError(subtreeUuid, nodeService, response);
154
        taxonBase = checkExistsSubtreeAndAccess(taxonBase, subtree, NO_UNPUBLISHED, response);
155
        return taxonBase;
156
    }
157

    
158
    /**
159
     * Checks if a {@link TaxonBase taxonBase} is public and belongs to a {@link TaxonNode subtree}
160
     * as accepted taxon or synonym.
161
     * If not the according {@link HttpStatusMessage http messages} are send to response.
162
     * <BR>
163
     * Not (yet) checked is the relation to a subtree via a concept relationship.
164
     * @param taxonBase
165
     * @param includeUnpublished
166
     * @param response
167
     * @return
168
     * @throws IOException
169
     */
170
    protected <S extends TaxonBase<?>> S checkExistsSubtreeAndAccess(S taxonBase,
171
            TaxonNode subtree, boolean includeUnpublished,
172
            HttpServletResponse response) throws IOException {
173
        taxonBase = checkExistsAndAccess(taxonBase, NO_UNPUBLISHED, response);
174
        if (subtree == null){
175
            return taxonBase;
176
        }else if(taxonBase != null){
177
            //TODO synonyms maybe can not be initialized
178
            Taxon taxon = taxonBase.isInstanceOf(Synonym.class)?
179
                    CdmBase.deproxy(taxonBase, Synonym.class).getAcceptedTaxon():
180
                    CdmBase.deproxy(taxonBase, Taxon.class);
181
            //check if taxon has any node that is a descendant of subtree
182
            for (TaxonNode taxonNode :taxon.getTaxonNodes()){
183
                if (subtree.isAncestor(taxonNode)){
184
                    return taxonBase;
185
                }
186
            }
187
            HttpStatusMessage.ACCESS_DENIED.send(response);
188
        }
189
        return null;
190
    }
191

    
192

    
193
    /**
194
     * Get the accepted {@link Taxon} for a given
195
     * {@link TaxonBase} entity identified by the <code>{taxon-uuid}</code>.
196
     * <p>
197
     * URI: <b>&#x002F;{datasource-name}&#x002F;taxon&#x002F;{taxon-uuid}&#x002F;accepted</b>
198
     *
199
     * @param request
200
     * @param response
201
     * @return a set on a list of {@link Taxon} entities which are initialized
202
     *         using the following initialization strategy:
203
     *         {@link #DEFAULT_INIT_STRATEGY}
204
     * @throws IOException
205
     */
206
    @RequestMapping(value = "accepted", method = RequestMethod.GET)
207
    public Taxon doGetAcceptedFor(
208
            @PathVariable("uuid") UUID uuid,
209
            @RequestParam(value = "classificationFilter", required = false) UUID classification_uuid,
210
            HttpServletRequest request,
211
            HttpServletResponse response)
212
            throws IOException {
213
        if(request != null){
214
            logger.info("doGetAcceptedFor() " + requestPathAndQuery(request));
215
        }
216

    
217
        try {
218
            boolean includeUnpublished = NO_UNPUBLISHED;
219
            Taxon result = service.findAcceptedTaxonFor(uuid, classification_uuid, includeUnpublished, getInitializationStrategy());
220
            result = checkExistsAndAccess(result, includeUnpublished, response);
221

    
222
            return result;
223
        } catch (EntityNotFoundException e){
224
            HttpStatusMessage.UUID_NOT_FOUND.send(response, e.getMessage());
225
        } catch (UnpublishedException e) {
226
            HttpStatusMessage.ACCESS_DENIED.send(response, e.getMessage());
227
        }
228
        return null;
229

    
230
    }
231

    
232
    @RequestMapping(value = "classifications", method = RequestMethod.GET)
233
    public List<Classification> doGetClassifications(
234
            @PathVariable("uuid") UUID uuid,
235
            HttpServletRequest request,
236
            HttpServletResponse response) throws IOException {
237

    
238
        boolean includeUnpublished = NO_UNPUBLISHED;
239

    
240
        logger.info("doGetClassifications(): " + request.getRequestURI());
241
        TaxonBase<?> taxonBase = service.load(uuid);
242
        taxonBase = checkExistsAndAccess(taxonBase, includeUnpublished, response);
243

    
244
        return service.listClassifications(taxonBase, null, null, getInitializationStrategy());
245
    }
246

    
247
    @RequestMapping(value = "taxonNodes", method = RequestMethod.GET)
248
    public Set<TaxonNodeDto>  doGetTaxonNodes(
249
            @PathVariable("uuid") UUID taxonUuid,
250
            @RequestParam(value = "subtree", required = false) UUID subtreeUuid,
251
            HttpServletRequest request,
252
            HttpServletResponse response) throws IOException {
253

    
254
        logger.info("doGetTaxonNodes" + requestPathAndQuery(request));
255
        TaxonBase<?> taxonBase;
256
        if (subtreeUuid != null){
257
            taxonBase = doGet(taxonUuid, subtreeUuid, request, response);
258
        }else{
259
            taxonBase = service.load(taxonUuid, NO_UNPUBLISHED, getTaxonNodeInitStrategy().getPropertyPaths());
260
        }
261
        if(taxonBase instanceof Taxon){
262
            return ((Taxon)taxonBase).getTaxonNodes().stream().map(e -> new TaxonNodeDto(e)).collect(Collectors.toSet());
263
        } else {
264
            HttpStatusMessage.UUID_REFERENCES_WRONG_TYPE.send(response);
265
            return null;
266
        }
267
    }
268

    
269
    protected  EntityInitStrategy getTaxonNodeInitStrategy() {
270
        return TAXONNODE_INIT_STRATEGY;
271
    }
272

    
273
    /**
274
    *
275
    * See also {@link AgentController#doGetTaxonNodeAgentRelations(UUID, UUID, Integer, Integer, HttpServletRequest, HttpServletResponse)}
276
    *
277
    * @param uuid
278
    * @param classificationUuid
279
    * @param pageNumber
280
    * @param pageSize
281
    * @param request
282
    * @param response
283
    * @return
284
    * @throws IOException
285
    *
286
    */
287
    @RequestMapping(value = "taxonNodeAgentRelations/{classification_uuid}", method = RequestMethod.GET)
288
    public Pager<TaxonNodeAgentRelation>  doGetTaxonNodeAgentRelations(
289
            @PathVariable("uuid") UUID uuid,
290
            @PathVariable("classification_uuid") UUID classificationUuid,
291
            @RequestParam(value = "relType_uuid" , required = false) UUID relTypeUuid,
292
            @RequestParam(value = "pageNumber", required = false) Integer pageNumber,
293
            @RequestParam(value = "pageSize", required = false) Integer pageSize,
294
            HttpServletRequest request,
295
            HttpServletResponse response) throws IOException {
296

    
297
        PagerParameters pagerParams = new PagerParameters(pageSize, pageNumber);
298
        pagerParams.normalizeAndValidate(response);
299

    
300
        Pager<TaxonNodeAgentRelation> pager = nodeService.pageTaxonNodeAgentRelations(uuid, classificationUuid,
301
                null, null, relTypeUuid, pagerParams.getPageSize(), pagerParams.getPageIndex(), null);
302
        return pager;
303
    }
304

    
305

    
306
    @RequestMapping(value = "specimensOrObservationsCount", method = RequestMethod.GET)
307
    public StringResultDTO doCountSpecimensOrObservations(
308
            @PathVariable("uuid") UUID uuid,
309
            HttpServletRequest request,
310
            HttpServletResponse response) throws IOException {
311
        logger.info("doListSpecimensOrObservations() - " + request.getRequestURI());
312

    
313
        List<OrderHint> orderHints = new ArrayList<>();
314
        orderHints.add(new OrderHint("titleCache", SortOrder.DESCENDING));
315
        FindOccurrencesConfigurator config = new FindOccurrencesConfigurator();
316
        config.setAssociatedTaxonUuid(uuid);
317
        long countSpecimen = occurrenceService.countOccurrences(config);
318
        return new StringResultDTO(String.valueOf(countSpecimen));
319
    }
320

    
321
    /**
322
     *
323
     * @deprecated replaced by rootUnitDTOs
324
     */
325
    @Deprecated
326
    @RequestMapping(value = "fieldUnitDTOs", method = RequestMethod.GET)
327
    public List<SpecimenOrObservationBaseDTO> doListFieldUnitDTOs(
328
            @PathVariable("uuid") UUID uuid,
329
            HttpServletRequest request,
330
            HttpServletResponse response) throws IOException {
331
        logger.info("doListFieldUnitDTOs() - " + request.getRequestURI());
332

    
333
        List<SpecimenOrObservationBaseDTO> rootUnitDtos = occurrenceService.listRootUnitDTOsByAssociatedTaxon(null, uuid, OccurrenceController.DERIVED_UNIT_INIT_STRATEGY);
334
        return rootUnitDtos.stream().filter(dto -> dto instanceof FieldUnitDTO).collect(Collectors.toList());
335
    }
336

    
337
    @RequestMapping(value = "rootUnitDTOs", method = RequestMethod.GET)
338
    public List<SpecimenOrObservationBaseDTO> doListRooUnitDTOs(
339
            @PathVariable("uuid") UUID uuid,
340
            HttpServletRequest request,
341
            HttpServletResponse response) throws IOException {
342
        logger.info("rootUnitDTOs() - " + request.getRequestURI());
343

    
344
        List<SpecimenOrObservationBaseDTO> rootUnitDtos = occurrenceService.listRootUnitDTOsByAssociatedTaxon(null, uuid, OccurrenceController.DERIVED_UNIT_INIT_STRATEGY);
345
           // List<SpecimenOrObservationBase<?>> specimensOrObservations = occurrenceService.listByAssociatedTaxon(null, null, (Taxon)tb, null, null, null, orderHints, null);
346
        return rootUnitDtos;
347
    }
348

    
349
    @RequestMapping(value = "specimensOrObservations", method = RequestMethod.GET)
350
    public List<SpecimenOrObservationBase<?>> doListSpecimensOrObservations(
351
            @PathVariable("uuid") UUID uuid,
352
            HttpServletRequest request,
353
            HttpServletResponse response) throws IOException {
354
        logger.info("doListSpecimensOrObservations() - " + request.getRequestURI());
355

    
356
        TaxonBase<?> tb = service.load(uuid);
357
        List<OrderHint> orderHints = new ArrayList<>();
358
        orderHints.add(new OrderHint("titleCache", SortOrder.DESCENDING));
359
        if(tb instanceof Taxon){
360
            List<SpecimenOrObservationBase<?>> specimensOrObservations = occurrenceService.listByAssociatedTaxon(null, null, (Taxon)tb, null, null, null, orderHints, null);
361
            return specimensOrObservations;
362
        } else {
363
            HttpStatusMessage.UUID_REFERENCES_WRONG_TYPE.send(response);
364
            return null;
365
        }
366
    }
367

    
368
    @RequestMapping(value = "associatedRootUnits", method = RequestMethod.GET)
369
    public Pager<SpecimenOrObservationBase> doGetAssociatedRootUnits(
370
            @PathVariable("uuid") UUID uuid,
371
            @RequestParam(value = "maxDepth", required = false) Integer maxDepth,
372
            @RequestParam(value = "pageNumber", required = false) Integer pageNumber,
373
            @RequestParam(value = "pageSize", required = false) Integer pageSize,
374
            HttpServletRequest request,
375
            HttpServletResponse response) throws IOException {
376
        logger.info("doGetAssociatedRootUnits() - " + request.getRequestURI());
377

    
378
        TaxonBase<?> taxonBase = service.load(uuid);
379
        taxonBase = checkExistsAndAccess(taxonBase, NO_UNPUBLISHED, response);
380

    
381
        List<OrderHint> orderHints = new ArrayList<>();
382
        orderHints.add(new OrderHint("titleCache", SortOrder.ASCENDING));
383

    
384
        if(taxonBase instanceof Taxon){
385
            PagerParameters pagerParams = new PagerParameters(pageSize, pageNumber);
386
            pagerParams.normalizeAndValidate(response);
387

    
388
            return occurrenceService.pageRootUnitsByAssociatedTaxon(null, null, (Taxon) taxonBase, maxDepth, pagerParams.getPageSize(), pagerParams.getPageIndex(), orderHints, null);
389
        }else{
390
            // FIXME proper HTTP code response
391
            return null;
392
        }
393
    }
394

    
395
    @RequestMapping(value = "taggedName", method = RequestMethod.GET)
396
    public ModelAndView doGetTaggedName(
397
            @PathVariable("uuid") UUID uuid,
398
            HttpServletRequest request) {
399
        logger.info("doGetDescriptionElementsByType() - " + request.getRequestURI());
400

    
401
        ModelAndView mv = new ModelAndView();
402

    
403
        TaxonBase<?> tb = service.load(uuid, NO_UNPUBLISHED, Arrays.asList(new String[] {"name"}));
404
        mv.addObject(nameService.getTaggedName(tb.getName().getUuid()));
405
        return mv;
406
    }
407

    
408
    /**
409
     * This webservice endpoint returns all taxa which are congruent or included in the taxon represented by the given taxon uuid.
410
     * The result also returns the path to these taxa represented by the uuids of the taxon relationships types and doubtful information.
411
     * If classificationUuids is set only taxa of classifications are returned which are included in the given classifications.
412
     * Also the path to these taxa may not include taxa from other classifications.
413
     *
414
     * @param taxonUUIDString
415
     * @param classificationStringList
416
     * @param includeDoubtful
417
     * @param onlyCongruent
418
     * @param response
419
     * @param request
420
     * @return
421
     * @throws IOException
422
     */
423
    @RequestMapping(value = { "includedTaxa" }, method = { RequestMethod.GET })
424
    public IncludedTaxaDTO doGetIncludedTaxa(
425
            @PathVariable("uuid") UUID uuid,
426
            @RequestParam(value="classificationFilter", required=false) final List<String> classificationStringList,
427
            @RequestParam(value="includeDoubtful", required=false) final boolean includeDoubtful,
428
            @RequestParam(value="onlyCongruent", required=false) final boolean onlyCongruent,
429
            HttpServletResponse response,
430
            HttpServletRequest request) throws IOException {
431

    
432

    
433
        if(request != null){
434
            logger.info("doGetIncludedTaxa()" + requestPathAndQuery(request));
435
        }
436

    
437
        List<UUID> classificationFilter = null;
438
        if( classificationStringList != null ){
439
            classificationFilter = new ArrayList<>();
440
            for(String classString :classificationStringList){
441
                classificationFilter.add(UUID.fromString(classString));
442
            }
443
        }
444
        IncludedTaxonConfiguration configuration =
445
                new IncludedTaxonConfiguration(classificationFilter, includeDoubtful, onlyCongruent);
446
        IncludedTaxaDTO listIncludedTaxa = service.listIncludedTaxa(uuid, configuration);
447
        return listIncludedTaxa;
448
    }
449

    
450
    // TODO ================================================================================ //
451
    // move all description and descriptionElement related methods into the according
452
    // Description Controllers
453

    
454
    /**
455
     * Get the list of {@link TaxonDescription}s of the
456
     * {@link Taxon} instance identified by the <code>{taxon-uuid}</code>.
457
     * <p>
458
     * URI: <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}&#x002F;descriptions</b>
459
     *
460
     * @param request
461
     * @param response
462
     * @return a List of {@link TaxonDescription} entities which are initialized
463
     *         using the following initialization strategy:
464
     *         {@link #TAXONDESCRIPTION_INIT_STRATEGY}
465
     * @throws IOException
466
     */
467
    @RequestMapping(
468
            value = {"descriptions"},
469
            method = RequestMethod.GET)
470
    public Pager<TaxonDescription> doGetDescriptions(
471
            @PathVariable("uuid") UUID uuid,
472
            @RequestParam(value = "markerTypes", required = false) List<MarkerType> markerTypes,
473
            @RequestParam(value = "descriptionTypes", required = false) List<DescriptionType> descriptionTypes,
474
            HttpServletRequest request,
475
            HttpServletResponse response)throws IOException {
476

    
477
        if(request != null){
478
            logger.info("doGetDescriptions()" + requestPathAndQuery(request));
479
        }
480

    
481
        Taxon taxon = getCdmBaseInstance(Taxon.class, uuid, response, (List<String>)null);
482
        taxon = checkExistsAndAccess(taxon, NO_UNPUBLISHED, response);
483

    
484
        Set<MarkerType> markerTypesSet = new HashSet<>();
485
        if (markerTypes != null) {
486
            markerTypesSet.addAll(markerTypes);
487
        }
488
        Set<DescriptionType> descriptionTypesSet = new HashSet<>();
489
        if (descriptionTypes != null) {
490
            descriptionTypesSet.addAll(descriptionTypes);
491
        }
492

    
493
        List<String> taxonDescriptionInitStrategy = getTaxonDescriptionInitStrategy();
494
        Pager<TaxonDescription> p = descriptionService.pageTaxonDescriptions(taxon, null, null, markerTypesSet, descriptionTypesSet, null, null, taxonDescriptionInitStrategy);
495

    
496
        return p;
497
    }
498

    
499
    @RequestMapping(value = "descriptions/elementsByType/{classSimpleName}", method = RequestMethod.GET)
500
    public ModelAndView doGetDescriptionElementsByType(
501
            @PathVariable("uuid") UUID uuid,
502
            @PathVariable("classSimpleName") String classSimpleName,
503
            @RequestParam(value = "markerTypes", required = false) List<MarkerType> markerTypes,
504
            @RequestParam(value = "descriptionTypes", required = false) List<DescriptionType> descriptionTypes,
505
            @RequestParam(value = "count", required = false, defaultValue = "false") Boolean doCount,
506
            HttpServletRequest request,
507
            HttpServletResponse response) throws IOException {
508
        logger.info("doGetDescriptionElementsByType() - " + requestPathAndQuery(request));
509

    
510

    
511
        boolean includeUnpublished = NO_UNPUBLISHED;
512

    
513
        ModelAndView mv = new ModelAndView();
514

    
515
        List<DescriptionElementBase> allElements = new ArrayList<>();
516
        List<DescriptionElementBase> elements;
517
        int count = 0;
518

    
519
        List<String> initStrategy = doCount ? null : getTaxonDescriptionElementInitStrategy();
520

    
521
        Taxon taxon = getCdmBaseInstance(Taxon.class, uuid, response, (List<String>)null);
522

    
523
        taxon = checkExistsAndAccess(taxon, includeUnpublished, response);
524

    
525

    
526
        Set<MarkerType> markerTypesSet = new HashSet<>();
527
        if (markerTypes != null) {
528
            markerTypesSet.addAll(markerTypes);
529
        }
530
        Set<DescriptionType> descriptionTypesSet = new HashSet<>();
531
        if (descriptionTypes != null) {
532
            descriptionTypesSet.addAll(descriptionTypes);
533
        }
534

    
535
        List<TaxonDescription> taxonDescriptions = descriptionService.listTaxonDescriptions(
536
                taxon, null, null, markerTypesSet, descriptionTypesSet, null, null, null);
537
        try {
538
            Class type;
539
            type = Class.forName("eu.etaxonomy.cdm.model.description."
540
                    + classSimpleName);
541
            if (taxonDescriptions != null) {
542
                for (TaxonDescription description : taxonDescriptions) {
543
                    elements = descriptionService.listDescriptionElements(description, null, type, null, 0, initStrategy);
544
                    allElements.addAll(elements);
545
                    count += elements.size();
546
                }
547

    
548
            }
549
        } catch (ClassNotFoundException e) {
550
            HttpStatusMessage.create(e.getLocalizedMessage(), 400).send(response);
551
        }
552
        if(doCount){
553
            mv.addObject(count);
554
        } else {
555
            mv.addObject(allElements);
556
        }
557
        return mv;
558
    }
559

    
560
    @RequestMapping(value = "taxonRelationshipsDTO", method = RequestMethod.GET)
561
    public TaxonRelationshipsDTO doGetTaxonRelationshipsDTO(
562
            @PathVariable("uuid") UUID taxonUuid,
563
            @RequestParam(value = "directTypes", required = false) UuidList directTypeUuids,
564
            @RequestParam(value = "inversTypes", required = false) UuidList inversTypeUuids,
565
            @RequestParam(value = "direction", required = false) Direction direction,
566
            @RequestParam(value="groupMisapplications", required=false, defaultValue="false") final boolean groupMisapplications,
567
            HttpServletRequest request,
568
            HttpServletResponse response) throws IOException {
569

    
570
        boolean includeUnpublished = NO_UNPUBLISHED;
571

    
572
        logger.info("doGetTaxonRelationshipDTOs(): " + request.getRequestURI());
573
        TaxonBase<?> taxonBase = service.load(taxonUuid);
574
        checkExistsAccessType(taxonBase, includeUnpublished, Taxon.class, response);
575

    
576
        Set<TaxonRelationshipType> directTypes = getTermsByUuidSet(TaxonRelationshipType.class, directTypeUuids);
577
        Set<TaxonRelationshipType> inversTypes = getTermsByUuidSet(TaxonRelationshipType.class, inversTypeUuids);
578

    
579
//        Set<TaxonRelationshipType> inversTypes = null;
580
//        if (directTypeUuids != null && !directTypeUuids.isEmpty()){
581
//            types = new HashSet<>();
582
//            List<TaxonRelationshipType> typeList = termService.find(TaxonRelationshipType.class, new HashSet<>(directTypeUuids));
583
//            types.addAll(typeList);
584
//            //TODO should we handle missing uuids as error response
585
////            HttpStatusMessage.UUID_REFERENCES_WRONG_TYPE.send(response);
586
//        }
587

    
588

    
589

    
590
//        boolean deduplicateMisapplications = true;
591
        Integer pageSize = null;
592
        Integer pageNumber = null;
593
        return service.listTaxonRelationships(taxonUuid, directTypes, inversTypes, direction, groupMisapplications,
594
                includeUnpublished, pageSize, pageNumber);
595
    }
596

    
597
    /**
598
     * @param directTypeUuids
599
     * @return
600
     */
601
    protected <T extends DefinedTermBase<T>> Set<T> getTermsByUuidSet(Class<T> clazz, UuidList directTypeUuids) {
602
        Set<T> directTypes = null;
603

    
604
        if (directTypeUuids != null && !directTypeUuids.isEmpty()){
605
            directTypes = new HashSet<>();
606
            List<T> typeList = termService.find(clazz, new HashSet<>(directTypeUuids));
607
            directTypes.addAll(typeList);
608
            //TODO should we handle missing uuids as error response
609
//            HttpStatusMessage.UUID_REFERENCES_WRONG_TYPE.send(response);
610
        }
611
        return directTypes;
612
    }
613

    
614
    // TODO ================================================================================ //
615

    
616
}
(57-57/76)