Project

General

Profile

Download (35.8 KB) Statistics
| Branch: | Tag: | Revision:
1
// $Id: TaxonController.java 5473 2009-03-25 13:42:07Z a.kohlbecker $
2
/**
3
* Copyright (C) 2007 EDIT
4
* European Distributed Institute of Taxonomy
5
* http://www.e-taxonomy.eu
6
*
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.
9
*/
10

    
11
package eu.etaxonomy.cdm.remote.controller;
12

    
13
import io.swagger.annotations.Api;
14

    
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;
22
import java.util.Map;
23
import java.util.Set;
24
import java.util.UUID;
25

    
26
import javax.servlet.http.HttpServletRequest;
27
import javax.servlet.http.HttpServletResponse;
28

    
29
import org.apache.log4j.Logger;
30
import org.springframework.beans.factory.annotation.Autowired;
31
import org.springframework.stereotype.Controller;
32
import org.springframework.web.bind.WebDataBinder;
33
import org.springframework.web.bind.annotation.InitBinder;
34
import org.springframework.web.bind.annotation.PathVariable;
35
import org.springframework.web.bind.annotation.RequestMapping;
36
import org.springframework.web.bind.annotation.RequestMethod;
37
import org.springframework.web.bind.annotation.RequestParam;
38
import org.springframework.web.servlet.ModelAndView;
39

    
40
import eu.etaxonomy.cdm.api.service.IClassificationService;
41
import eu.etaxonomy.cdm.api.service.IDescriptionService;
42
import eu.etaxonomy.cdm.api.service.IFeatureTreeService;
43
import eu.etaxonomy.cdm.api.service.INameService;
44
import eu.etaxonomy.cdm.api.service.IOccurrenceService;
45
import eu.etaxonomy.cdm.api.service.ITaxonService;
46
import eu.etaxonomy.cdm.api.service.ITermService;
47
import eu.etaxonomy.cdm.api.service.pager.Pager;
48
import eu.etaxonomy.cdm.api.service.util.TaxonRelationshipEdge;
49
import eu.etaxonomy.cdm.database.UpdatableRoutingDataSource;
50
import eu.etaxonomy.cdm.model.common.DefinedTermBase;
51
import eu.etaxonomy.cdm.model.common.MarkerType;
52
import eu.etaxonomy.cdm.model.common.RelationshipBase.Direction;
53
import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
54
import eu.etaxonomy.cdm.model.description.TaxonDescription;
55
import eu.etaxonomy.cdm.model.location.NamedArea;
56
import eu.etaxonomy.cdm.model.media.Media;
57
import eu.etaxonomy.cdm.model.media.MediaRepresentation;
58
import eu.etaxonomy.cdm.model.media.MediaRepresentationPart;
59
import eu.etaxonomy.cdm.model.media.MediaUtils;
60
import eu.etaxonomy.cdm.model.name.NameRelationship;
61
import eu.etaxonomy.cdm.model.taxon.Synonym;
62
import eu.etaxonomy.cdm.model.taxon.Taxon;
63
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
64
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
65
import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;
66
import eu.etaxonomy.cdm.persistence.query.MatchMode;
67
import eu.etaxonomy.cdm.remote.controller.util.ControllerUtils;
68
import eu.etaxonomy.cdm.remote.editor.CdmTypePropertyEditor;
69
import eu.etaxonomy.cdm.remote.editor.DefinedTermBaseList;
70
import eu.etaxonomy.cdm.remote.editor.MatchModePropertyEditor;
71
import eu.etaxonomy.cdm.remote.editor.NamedAreaPropertyEditor;
72
import eu.etaxonomy.cdm.remote.editor.TermBaseListPropertyEditor;
73
import eu.etaxonomy.cdm.remote.editor.UUIDListPropertyEditor;
74
import eu.etaxonomy.cdm.remote.editor.UuidList;
75

    
76
/**
77
 * The TaxonPortalController class is a Spring MVC Controller.
78
 * <p>
79
 * The syntax of the mapped service URIs contains the the {datasource-name} path element.
80
 * The available {datasource-name}s are defined in a configuration file which
81
 * is loaded by the {@link UpdatableRoutingDataSource}. If the
82
 * UpdatableRoutingDataSource is not being used in the actual application
83
 * context any arbitrary {datasource-name} may be used.
84
 * <p>
85
 * Methods mapped at type level, inherited from super classes ({@link BaseController}):
86
 * <blockquote>
87
 * URI: <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}</b>
88
 *
89
 * Get the {@link TaxonBase} instance identified by the <code>{taxon-uuid}</code>.
90
 * The returned Taxon is initialized by
91
 * the following strategy {@link #TAXON_INIT_STRATEGY}
92
 * </blockquote>
93
 *
94
 * @author a.kohlbecker
95
 * @date 20.07.2009
96
 *
97
 */
98
@Controller
99
@Api("portal_taxon")
100
@RequestMapping(value = {"/portal/taxon/{uuid}"})
101
public class TaxonPortalController extends TaxonController
102
{
103

    
104
    public static final Logger logger = Logger.getLogger(TaxonPortalController.class);
105

    
106
    @Autowired
107
    private INameService nameService;
108

    
109
    @Autowired
110
    private IDescriptionService descriptionService;
111

    
112
    @Autowired
113
    private IOccurrenceService occurrenceService;
114

    
115
    @Autowired
116
    private IClassificationService classificationService;
117

    
118
    @Autowired
119
    private ITaxonService taxonService;
120

    
121
    @Autowired
122
    private ITermService termService;
123

    
124
    @Autowired
125
    private IFeatureTreeService featureTreeService;
126

    
127
    private static final List<String> TAXON_INIT_STRATEGY = Arrays.asList(new String []{
128
            "$",
129
            "sources",
130
            // taxon relations
131
//            "relationsToThisName.fromTaxon.name",
132
            // the name
133
            "name.$",
134
            "name.nomenclaturalReference.authorship",
135
            "name.nomenclaturalReference.inReference",
136
            "name.rank.representations",
137
            "name.status.type.representations",
138

    
139
//            "descriptions" // TODO remove
140

    
141
            });
142

    
143
    private static final List<String> TAXON_WITH_NODES_INIT_STRATEGY = Arrays.asList(new String []{
144
            "taxonNodes.$",
145
            "taxonNodes.classification.$",
146
            "taxonNodes.childNodes.$"
147
            });
148

    
149
    private static final List<String> SIMPLE_TAXON_INIT_STRATEGY = Arrays.asList(new String []{
150
            "$",
151
            // the name
152
            "name.$",
153
            "name.rank.representations",
154
            "name.status.type.representations",
155
            "name.nomenclaturalReference.authorship",
156
            "name.nomenclaturalReference.inReference",
157
            "taxonNodes.classification",
158
            });
159

    
160
    private static final List<String> SYNONYMY_INIT_STRATEGY = Arrays.asList(new String []{
161
            // initialize homotypical and heterotypical groups; needs synonyms
162
            "synonymRelations.$",
163
            "synonymRelations.synonym.$",
164
            "synonymRelations.synonym.name.status.type.representations",
165
            "synonymRelations.synonym.name.nomenclaturalReference.authorship",
166
            "synonymRelations.synonym.name.nomenclaturalReference.inReference",
167
            "synonymRelations.synonym.name.homotypicalGroup.typifiedNames.$",
168
            "synonymRelations.synonym.name.homotypicalGroup.typifiedNames.taxonBases.$",
169
            "synonymRelations.synonym.name.combinationAuthorship.$",
170

    
171
            "name.typeDesignations",
172

    
173
            "name.homotypicalGroup.$",
174
            "name.homotypicalGroup.typifiedNames.$",
175
            "name.homotypicalGroup.typifiedNames.nomenclaturalReference.authorship",
176
            "name.homotypicalGroup.typifiedNames.nomenclaturalReference.inReference",
177
            "name.homotypicalGroup.typifiedNames.taxonBases.$"
178
    });
179

    
180
    private static final List<String> SYNONYMY_WITH_NODES_INIT_STRATEGY = Arrays.asList(new String []{
181
            // initialize homotypical and heterotypical groups; needs synonyms
182
            "synonymRelations.$",
183
            "synonymRelations.synonym.$",
184
            "synonymRelations.synonym.name.status.type.representation",
185
            "synonymRelations.synonym.name.nomenclaturalReference.authorship",
186
            "synonymRelations.synonym.name.nomenclaturalReference.inReference",
187
            "synonymRelations.synonym.name.homotypicalGroup.typifiedNames.$",
188
            "synonymRelations.synonym.name.homotypicalGroup.typifiedNames.taxonBases.$",
189
            "synonymRelations.synonym.name.combinationAuthorship.$",
190

    
191
            "name.homotypicalGroup.$",
192
            "name.homotypicalGroup.typifiedNames.$",
193
            "name.homotypicalGroup.typifiedNames.nomenclaturalReference.authorship",
194
            "name.homotypicalGroup.typifiedNames.nomenclaturalReference.inReference",
195

    
196
            "name.homotypicalGroup.typifiedNames.taxonBases.$",
197

    
198
            "taxonNodes.$",
199
            "taxonNodes.classification.$",
200
            "taxonNodes.childNodes.$"
201
    });
202
    private static final List<String> SIMPLE_TAXON_WITH_NODES_INIT_STRATEGY = Arrays.asList(new String []{
203
            "*",
204
            // taxon relations
205
            "relationsToThisName.fromTaxon.name",
206
            // the name
207
            "name.$",
208
            "name.rank.representations",
209
            "name.status.type.representations",
210
            "name.nomenclaturalReference.authorship",
211
            "name.nomenclaturalReference.inReference",
212

    
213
            "taxonNodes.$",
214
            "taxonNodes.classification.$",
215
            "taxonNodes.childNodes.$"
216
            });
217

    
218

    
219
    private static final List<String> TAXONRELATIONSHIP_INIT_STRATEGY = Arrays.asList(new String []{
220
            "$",
221
            "type.inverseRepresentations",
222
            "fromTaxon.sec",
223
            "fromTaxon.name",
224
            "toTaxon.sec",
225
            "toTaxon.name"
226
    });
227

    
228
    private static final List<String> NAMERELATIONSHIP_INIT_STRATEGY = Arrays.asList(new String []{
229
            "$",
230
            "type.inverseRepresentations",
231
            "toName.$",
232
            "toName.nomenclaturalReference.authorship",
233
            "toName.nomenclaturalReference.inReference",
234
            "fromName.$",
235
            "fromName.nomenclaturalReference.authorship",
236
            "fromName.nomenclaturalReference.inReference",
237

    
238
    });
239

    
240

    
241
    protected static final List<String> TAXONDESCRIPTION_INIT_STRATEGY = Arrays.asList(new String [] {
242
            "$",
243
            "elements.$",
244
            "elements.stateData.$",
245
            "elements.sources.citation.authorship",
246
            "elements.sources.nameUsedInSource",
247
            "elements.multilanguageText",
248
            "elements.media",
249
            "elements.modifyingText",
250
            "elements.modifiers",
251
            "elements.kindOfUnit",
252
            "name.$",
253
            "name.rank.representations",
254
            "name.status.type.representations",
255
            "sources.$",
256
    });
257

    
258
    protected static final List<String> DESCRIPTION_ELEMENT_INIT_STRATEGY = Arrays.asList(new String []{
259
            "$",
260
            "sources.citation.authorship",
261
            "sources.nameUsedInSource",
262
            "multilanguageText",
263
            "media",
264
    });
265

    
266

    
267
//	private static final List<String> NAMEDESCRIPTION_INIT_STRATEGY = Arrays.asList(new String []{
268
//			"uuid",
269
//			"feature",
270
//			"elements.$",
271
//			"elements.multilanguageText",
272
//			"elements.media",
273
//	});
274

    
275
    protected static final List<String> TAXONDESCRIPTION_MEDIA_INIT_STRATEGY = Arrays.asList(new String []{
276
            "elements.media"
277

    
278
    });
279

    
280
    private static final List<String> TYPEDESIGNATION_INIT_STRATEGY = Arrays.asList(new String []{
281
            "typeSpecimen.$",
282
            "citation.authorship.$",
283
            "typeName",
284
            "typeStatus"
285
    });
286

    
287
    protected static final List<String> TAXONNODE_WITHTAXON_INIT_STRATEGY = Arrays.asList(new String []{
288
            "childNodes.taxon",
289
    });
290

    
291
    protected static final List<String> TAXONNODE_INIT_STRATEGY = Arrays.asList(new String []{
292
            "taxonNodes.classification"
293
    });
294

    
295

    
296

    
297
    private static final String featureTreeUuidPattern = "^/taxon(?:(?:/)([^/?#&\\.]+))+.*";
298

    
299
    public TaxonPortalController(){
300
        super();
301
        setInitializationStrategy(TAXON_INIT_STRATEGY);
302
    }
303

    
304
    /* (non-Javadoc)
305
     * @see eu.etaxonomy.cdm.remote.controller.GenericController#setService(eu.etaxonomy.cdm.api.service.IService)
306
     */
307
    @Autowired
308
    @Override
309
    public void setService(ITaxonService service) {
310
        this.service = service;
311
    }
312

    
313
    @InitBinder
314
    @Override
315
    public void initBinder(WebDataBinder binder) {
316
        super.initBinder(binder);
317
        binder.registerCustomEditor(NamedArea.class, new NamedAreaPropertyEditor());
318
        binder.registerCustomEditor(MatchMode.class, new MatchModePropertyEditor());
319
        binder.registerCustomEditor(Class.class, new CdmTypePropertyEditor());
320
        binder.registerCustomEditor(UuidList.class, new UUIDListPropertyEditor());
321
        binder.registerCustomEditor(DefinedTermBaseList.class, new TermBaseListPropertyEditor<NamedArea>(termService));
322

    
323
    }
324

    
325

    
326
    /* (non-Javadoc)
327
     * @see eu.etaxonomy.cdm.remote.controller.BaseController#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
328

    
329
    @Override
330
    @RequestMapping(method = RequestMethod.GET)
331
    public TaxonBase doGet(HttpServletRequest request, HttpServletResponse response)throws IOException {
332
        logger.info("doGet()");
333
        TaxonBase tb = getCdmBase(request, response, TAXON_INIT_STRATEGY, TaxonBase.class);
334
        return tb;
335
    }
336
     */
337

    
338
    /**
339
     * Get the synonymy for a taxon identified by the <code>{taxon-uuid}</code>.
340
     * The synonymy consists
341
     * of two parts: The group of homotypic synonyms of the taxon and the
342
     * heterotypic synonymy groups of the taxon. The synonymy is ordered
343
     * historically by the type designations and by the publication date of the
344
     * nomenclatural reference
345
     * <p>
346
     * URI:
347
     * <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}&#x002F;synonymy</b>
348
     *
349
     *
350
     * @param request
351
     * @param response
352
     * @return a Map with to entries which are mapped by the following keys:
353
     *         "homotypicSynonymsByHomotypicGroup", "heterotypicSynonymyGroups",
354
     *         containing lists of {@link Synonym}s which are initialized using the
355
     *         following initialization strategy: {@link #SYNONYMY_INIT_STRATEGY}
356
     *
357
     * @throws IOException
358
     */
359
    @RequestMapping(
360
            value = {"synonymy"},
361
            method = RequestMethod.GET)
362
    public ModelAndView doGetSynonymy(@PathVariable("uuid") UUID uuid,
363
            HttpServletRequest request, HttpServletResponse response)throws IOException {
364

    
365
        if(request != null){
366
            logger.info("doGetSynonymy() " + requestPathAndQuery(request));
367
        }
368
        ModelAndView mv = new ModelAndView();
369
        Taxon taxon = getCdmBaseInstance(Taxon.class, uuid, response, (List<String>)null);
370
        Map<String, List<?>> synonymy = new Hashtable<String, List<?>>();
371

    
372
        //new
373
        List<List<Synonym>> synonymyGroups = service.getSynonymsByHomotypicGroup(taxon, SYNONYMY_INIT_STRATEGY);
374
        synonymy.put("homotypicSynonymsByHomotypicGroup", synonymyGroups.get(0));
375
        synonymyGroups.remove(0);
376
        synonymy.put("heterotypicSynonymyGroups", synonymyGroups);
377

    
378
        //old
379
//        synonymy.put("homotypicSynonymsByHomotypicGroup", service.getHomotypicSynonymsByHomotypicGroup(taxon, SYNONYMY_INIT_STRATEGY));
380
//        synonymy.put("heterotypicSynonymyGroups", service.getHeterotypicSynonymyGroups(taxon, SYNONYMY_INIT_STRATEGY));
381

    
382

    
383
        mv.addObject(synonymy);
384
        return mv;
385
    }
386

    
387

    
388
    /**
389
     * Get the list of {@link TaxonRelationship}s for the given
390
     * {@link TaxonBase} instance identified by the <code>{taxon-uuid}</code>.
391
     * <p>
392
     * URI: <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}&#x002F;taxonRelationships</b>
393
     *
394
     * @param request
395
     * @param response
396
     * @return a List of {@link TaxonRelationship} entities which are initialized
397
     *         using the following initialization strategy:
398
     *         {@link #TAXONRELATIONSHIP_INIT_STRATEGY}
399
     * @throws IOException
400
     */
401
    @RequestMapping(
402
            value = {"taxonRelationships"},
403
            method = RequestMethod.GET)
404
    public List<TaxonRelationship> doGetTaxonRelations(@PathVariable("uuid") UUID uuid,
405
            HttpServletRequest request, HttpServletResponse response)throws IOException {
406

    
407
        logger.info("doGetTaxonRelations()" + requestPathAndQuery(request));
408
        Taxon taxon = getCdmBaseInstance(Taxon.class, uuid, response, (List<String>)null);
409
        List<TaxonRelationship> toRelationships = service.listToTaxonRelationships(taxon, null, null, null, null, TAXONRELATIONSHIP_INIT_STRATEGY);
410
        List<TaxonRelationship> fromRelationships = service.listFromTaxonRelationships(taxon, null, null, null, null, TAXONRELATIONSHIP_INIT_STRATEGY);
411

    
412
        List<TaxonRelationship> allRelationships = new ArrayList<TaxonRelationship>(toRelationships.size() + fromRelationships.size());
413
        allRelationships.addAll(toRelationships);
414
        allRelationships.addAll(fromRelationships);
415

    
416
        return allRelationships;
417
    }
418

    
419
    /**
420
     * Get the list of {@link NameRelationship}s of the Name associated with the
421
     * {@link TaxonBase} instance identified by the <code>{taxon-uuid}</code>.
422
     * <p>
423
     * URI: <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}&#x002F;nameRelationships</b>
424
     *
425
     * @param request
426
     * @param response
427
     * @return a List of {@link NameRelationship} entities which are initialized
428
     *         using the following initialization strategy:
429
     *         {@link #NAMERELATIONSHIP_INIT_STRATEGY}
430
     * @throws IOException
431
     */
432
    @RequestMapping(
433
            value = {"toNameRelationships"},
434
            method = RequestMethod.GET)
435
    public List<NameRelationship> doGetToNameRelations(@PathVariable("uuid") UUID uuid,
436
            HttpServletRequest request, HttpServletResponse response)throws IOException {
437
        logger.info("doGetNameRelations()" + request.getRequestURI());
438
        TaxonBase taxonBase = getCdmBaseInstance(TaxonBase.class, uuid, response, (List<String>)null);
439
        List<NameRelationship> list = nameService.listNameRelationships(taxonBase.getName(), Direction.relatedTo, null, null, 0, null, NAMERELATIONSHIP_INIT_STRATEGY);
440
        //List<NameRelationship> list = nameService.listToNameRelationships(taxonBase.getName(), null, null, null, null, NAMERELATIONSHIP_INIT_STRATEGY);
441
        return list;
442
    }
443

    
444
    /**
445
     * Get the list of {@link NameRelationship}s of the Name associated with the
446
     * {@link TaxonBase} instance identified by the <code>{taxon-uuid}</code>.
447
     * <p>
448
     * URI: <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}&#x002F;nameRelationships</b>
449
     *
450
     * @param request
451
     * @param response
452
     * @return a List of {@link NameRelationship} entities which are initialized
453
     *         using the following initialization strategy:
454
     *         {@link #NAMERELATIONSHIP_INIT_STRATEGY}
455
     * @throws IOException
456
     */
457
    @RequestMapping(
458
            value = {"fromNameRelationships"},
459
            method = RequestMethod.GET)
460
    public List<NameRelationship> doGetFromNameRelations(@PathVariable("uuid") UUID uuid,
461
            HttpServletRequest request, HttpServletResponse response)throws IOException {
462
        logger.info("doGetNameFromNameRelations()" + requestPathAndQuery(request));
463

    
464
        TaxonBase taxonbase = getCdmBaseInstance(TaxonBase.class, uuid, response, SIMPLE_TAXON_INIT_STRATEGY);
465
        List<NameRelationship> list = nameService.listNameRelationships(taxonbase.getName(), Direction.relatedFrom, null, null, 0, null, NAMERELATIONSHIP_INIT_STRATEGY);
466
        //List<NameRelationship> list = nameService.listFromNameRelationships(taxonbase.getName(), null, null, null, null, NAMERELATIONSHIP_INIT_STRATEGY);
467
        return list;
468
    }
469

    
470
    @Override
471
    @RequestMapping(value = "taxonNodes", method = RequestMethod.GET)
472
    public Set<TaxonNode>  doGetTaxonNodes(
473
            @PathVariable("uuid") UUID uuid,
474
            HttpServletRequest request,
475
            HttpServletResponse response) throws IOException {
476
        logger.info("doGetTaxonNodes" + requestPathAndQuery(request));
477
        TaxonBase taxon = service.load(uuid, TAXONNODE_INIT_STRATEGY);
478
        if(taxon instanceof Taxon){
479
            return ((Taxon)taxon).getTaxonNodes();
480
        } else {
481
            HttpStatusMessage.UUID_REFERENCES_WRONG_TYPE.send(response);
482
            return null;
483
        }
484
    }
485

    
486
    /**
487
     * Get the list of {@link TaxonDescription}s of the
488
     * {@link Taxon} instance identified by the <code>{taxon-uuid}</code>.
489
     * <p>
490
     * URI: <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}&#x002F;descriptions</b>
491
     *
492
     * @param request
493
     * @param response
494
     * @return a List of {@link TaxonDescription} entities which are initialized
495
     *         using the following initialization strategy:
496
     *         {@link #TAXONDESCRIPTION_INIT_STRATEGY}
497
     * @throws IOException
498
     */
499
    @RequestMapping(
500
            value = {"descriptions"},
501
            method = RequestMethod.GET)
502
    public List<TaxonDescription> doGetDescriptions(
503
            @PathVariable("uuid") UUID uuid,
504
            @RequestParam(value = "markerTypes", required = false) UuidList markerTypeUUIDs,
505
            HttpServletRequest request,
506
            HttpServletResponse response)throws IOException {
507
        if(request != null){
508
            logger.info("doGetDescriptions()" + requestPathAndQuery(request));
509
        }
510
        List<DefinedTermBase> markerTypeTerms = null;
511
        Set<UUID> sMarkerTypeUUIDs = null;
512

    
513
        if(markerTypeUUIDs != null && !markerTypeUUIDs.isEmpty()){
514
            sMarkerTypeUUIDs = new HashSet<UUID>(markerTypeUUIDs);
515
            markerTypeTerms = termService.find(sMarkerTypeUUIDs);
516
        } else if(markerTypeUUIDs != null && markerTypeUUIDs.isEmpty()){
517
            markerTypeTerms = new ArrayList<DefinedTermBase>();
518
        }
519
        Set<MarkerType> markerTypes = new HashSet<MarkerType>();
520
        List<TaxonDescription> descriptions = new ArrayList<TaxonDescription>();
521
        if (markerTypeTerms != null) {
522
            for (DefinedTermBase markerTypeTerm : markerTypeTerms) {
523
                markerTypes.add((MarkerType)markerTypeTerm);
524
            }
525
        }
526
        Taxon t = getCdmBaseInstance(Taxon.class, uuid, response, (List<String>)null);
527
        if (markerTypeTerms == null) {
528

    
529
            Pager<TaxonDescription> p = descriptionService.pageTaxonDescriptions(t, null, null, null, null, TAXONDESCRIPTION_INIT_STRATEGY);
530
            descriptions = p.getRecords();
531
        }
532

    
533
        else if (markerTypeTerms != null && markerTypeTerms.isEmpty()) {
534
            descriptions = descriptionService.listTaxonDescriptions(t, null, null, markerTypes, null, null, TAXONDESCRIPTION_INIT_STRATEGY);
535

    
536
        }
537
        else {
538
            descriptions = descriptionService.listTaxonDescriptions(t, null, null, markerTypes, null, null, TAXONDESCRIPTION_INIT_STRATEGY);
539
            /*for (TaxonDescription description: descriptions) {
540
                for (IdentifiableSource source :description.getSources()) {
541
                    if (source.getOriginalNameString() != null) {
542
                        description.
543
                    }
544

    
545
                }
546

    
547

    
548
            }*/
549
        }
550
        return descriptions;
551
    }
552

    
553
    @RequestMapping(value = "useDescriptions", method = RequestMethod.GET)
554
    public List<TaxonDescription> doGetUseDescriptions(
555
            @PathVariable("uuid") UUID uuid,
556
            HttpServletRequest request,
557
            HttpServletResponse response) throws IOException {
558
        logger.info("doGetDescriptionElements() - " + requestPathAndQuery(request));
559

    
560
        //ModelAndView mv = new ModelAndView();
561
        Taxon t = getCdmBaseInstance(Taxon.class, uuid, response, (List<String>)null);
562

    
563
       //MarkerType useMarkerType = (MarkerType) markerTypeService.find(UUID.fromString("2e6e42d9-e92a-41f4-899b-03c0ac64f059"));
564
        MarkerType useMarkerType = (MarkerType) termService.find(UUID.fromString("2e6e42d9-e92a-41f4-899b-03c0ac64f039"));
565

    
566
       //find(UUID.fromString("2e6e42d9-e92a-41f4-899b-03c0ac64f059"));
567
       Set<MarkerType> markerTypes =  new HashSet<MarkerType>();
568
       markerTypes.add(useMarkerType);
569
       List<TaxonDescription> descriptionElements = descriptionService.listTaxonDescriptions(t, null, null, markerTypes, null, null, TAXONDESCRIPTION_INIT_STRATEGY);
570
        //getDescriptionElements(description, features, type, pageSize, pageNumber, propertyPaths)  load(uuid);
571

    
572
        /*if(!(description instanceof TaxonDescription)){
573
            HttpStatusMessage.UUID_REFERENCES_WRONG_TYPE.send(response);
574
            // will terminate thread
575
        }*/
576

    
577
        //boolean hasStructuredData = service.        hasStructuredData(description);
578

    
579
        //mv.addObject(hasStructuredData);
580

    
581
        return descriptionElements;
582
    }
583

    
584
    @RequestMapping(value = "descriptions/elementsByType/{classSimpleName}", method = RequestMethod.GET)
585
    public ModelAndView doGetDescriptionElementsByType(
586
            @PathVariable("uuid") UUID uuid,
587
            @PathVariable("classSimpleName") String classSimpleName,
588
            @RequestParam(value = "markerTypes", required = false) UuidList markerTypeUUIDs,
589
            @RequestParam(value = "count", required = false, defaultValue = "false") Boolean doCount,
590
            HttpServletRequest request,
591
            HttpServletResponse response) throws IOException {
592
        logger.info("doGetDescriptionElementsByType() - " + requestPathAndQuery(request));
593

    
594
        ModelAndView mv = new ModelAndView();
595

    
596
        List<DescriptionElementBase> allElements = new ArrayList<DescriptionElementBase>();
597
        List<DescriptionElementBase> elements;
598
        int count = 0;
599

    
600
        List<String> initStrategy = doCount ? null : DESCRIPTION_ELEMENT_INIT_STRATEGY;
601

    
602
        List<TaxonDescription> taxonDescriptions = doGetDescriptions(uuid, markerTypeUUIDs, request, response);
603
        try {
604
            Class type;
605
            type = Class.forName("eu.etaxonomy.cdm.model.description."
606
                    + classSimpleName);
607
            if (taxonDescriptions != null) {
608
                for (TaxonDescription description : taxonDescriptions) {
609
                    elements = descriptionService.listDescriptionElements(description, null, type, null, 0, initStrategy);
610
                    allElements.addAll(elements);
611
                    count += elements.size();
612
                }
613

    
614
            }
615
        } catch (ClassNotFoundException e) {
616
            HttpStatusMessage.create(e.getLocalizedMessage(), 400).send(response);
617
        }
618
        if(doCount){
619
            mv.addObject(count);
620
        } else {
621
            mv.addObject(allElements);
622
        }
623
        return mv;
624
    }
625

    
626
//	@RequestMapping(value = "specimens", method = RequestMethod.GET)
627
//	public ModelAndView doGetSpecimens(
628
//			@PathVariable("uuid") UUID uuid,
629
//			HttpServletRequest request,
630
//			HttpServletResponse response) throws IOException, ClassNotFoundException {
631
//		logger.info("doGetSpecimens() - " + request.getRequestURI());
632
//
633
//		ModelAndView mv = new ModelAndView();
634
//
635
//		List<DerivedUnitFacade> derivedUnitFacadeList = new ArrayList<DerivedUnitFacade>();
636
//
637
//		// find speciemens in the TaxonDescriptions
638
//		List<TaxonDescription> taxonDescriptions = doGetDescriptions(uuid, request, response);
639
//		if (taxonDescriptions != null) {
640
//
641
//			for (TaxonDescription description : taxonDescriptions) {
642
//				derivedUnitFacadeList.addAll( occurrenceService.listDerivedUnitFacades(description, null) );
643
//			}
644
//		}
645
//		// TODO find speciemens in the NameDescriptions ??
646
//
647
//		// TODO also find type specimens
648
//
649
//		mv.addObject(derivedUnitFacadeList);
650
//
651
//		return mv;
652
//	}
653

    
654
    /**
655
     * Get the {@link Media} attached to the {@link Taxon} instance
656
     * identified by the <code>{taxon-uuid}</code>.
657
     *
658
     * Usage &#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-
659
     * uuid}&#x002F;media&#x002F;{mime type
660
     * list}&#x002F;{size}[,[widthOrDuration}][,{height}]&#x002F;
661
     *
662
     * Whereas
663
     * <ul>
664
     * <li><b>{mime type list}</b>: a comma separated list of mime types, in the
665
     * order of preference. The forward slashes contained in the mime types must
666
     * be replaced by a colon. Regular expressions can be used. Each media
667
     * associated with this given taxon is being searched whereas the first
668
     * matching mime type matching a representation always rules.</li>
669
     * <li><b>{size},{widthOrDuration},{height}</b>: <i>not jet implemented</i>
670
     * valid values are an integer or the asterisk '*' as a wildcard</li>
671
     * </ul>
672
     *
673
     * @param request
674
     * @param response
675
     * @return a List of {@link Media} entities which are initialized
676
     *         using the following initialization strategy:
677
     *         {@link #TAXONDESCRIPTION_INIT_STRATEGY}
678
     * @throws IOException
679
     */
680
    @RequestMapping(
681
        value = {"media"},
682
        method = RequestMethod.GET)
683
    public List<Media> doGetMedia(
684
            @PathVariable("uuid") UUID uuid,
685
            @RequestParam(value = "type", required = false) Class<? extends MediaRepresentationPart> type,
686
            @RequestParam(value = "mimeTypes", required = false) String[] mimeTypes,
687
            @RequestParam(value = "relationships", required = false) UuidList relationshipUuids,
688
            @RequestParam(value = "relationshipsInvers", required = false) UuidList relationshipInversUuids,
689
            @RequestParam(value = "includeTaxonDescriptions", required = true) Boolean  includeTaxonDescriptions,
690
            @RequestParam(value = "includeOccurrences", required = true) Boolean  includeOccurrences,
691
            @RequestParam(value = "includeTaxonNameDescriptions", required = true) Boolean  includeTaxonNameDescriptions,
692
            @RequestParam(value = "widthOrDuration", required = false) Integer  widthOrDuration,
693
            @RequestParam(value = "height", required = false) Integer height,
694
            @RequestParam(value = "size", required = false) Integer size,
695
            HttpServletRequest request, HttpServletResponse response) throws IOException {
696

    
697
        logger.info("doGetMedia() " + requestPathAndQuery(request));
698

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

    
701
        Set<TaxonRelationshipEdge> includeRelationships = ControllerUtils.loadIncludeRelationships(relationshipUuids, relationshipInversUuids, termService);
702

    
703
        List<Media> returnMedia = getMediaForTaxon(taxon, includeRelationships,
704
                includeTaxonDescriptions, includeOccurrences, includeTaxonNameDescriptions,
705
                type, mimeTypes, widthOrDuration, height, size);
706
        return returnMedia;
707
    }
708

    
709
    @RequestMapping(
710
            value = {"subtree/media"},
711
            method = RequestMethod.GET)
712
        public List<Media> doGetSubtreeMedia(
713
                @PathVariable("uuid") UUID uuid,
714
                @RequestParam(value = "type", required = false) Class<? extends MediaRepresentationPart> type,
715
                @RequestParam(value = "mimeTypes", required = false) String[] mimeTypes,
716
                @RequestParam(value = "relationships", required = false) UuidList relationshipUuids,
717
                @RequestParam(value = "relationshipsInvers", required = false) UuidList relationshipInversUuids,
718
                @RequestParam(value = "includeTaxonDescriptions", required = true) Boolean  includeTaxonDescriptions,
719
                @RequestParam(value = "includeOccurrences", required = true) Boolean  includeOccurrences,
720
                @RequestParam(value = "includeTaxonNameDescriptions", required = true) Boolean  includeTaxonNameDescriptions,
721
                @RequestParam(value = "widthOrDuration", required = false) Integer  widthOrDuration,
722
                @RequestParam(value = "height", required = false) Integer height,
723
                @RequestParam(value = "size", required = false) Integer size,
724
                HttpServletRequest request, HttpServletResponse response)throws IOException {
725

    
726
        logger.info("doGetSubtreeMedia() " + requestPathAndQuery(request));
727

    
728
        Taxon taxon = getCdmBaseInstance(Taxon.class, uuid, response, TAXON_WITH_NODES_INIT_STRATEGY);
729

    
730
        Set<TaxonRelationshipEdge> includeRelationships = ControllerUtils.loadIncludeRelationships(relationshipUuids, relationshipInversUuids, termService);
731

    
732
        List<Media> returnMedia = getMediaForTaxon(taxon, includeRelationships,
733
                includeTaxonDescriptions, includeOccurrences, includeTaxonNameDescriptions,
734
                type, mimeTypes, widthOrDuration, height, size);
735
        TaxonNode node;
736
        //looking for all medias of genus
737
        if (taxon.getTaxonNodes().size()>0){
738
            Set<TaxonNode> nodes = taxon.getTaxonNodes();
739
            Iterator<TaxonNode> iterator = nodes.iterator();
740
            //TaxonNode holen
741
            node = iterator.next();
742
            //Check if TaxonNode belongs to the current tree
743

    
744
            node = classificationService.loadTaxonNode(node, TAXONNODE_WITHTAXON_INIT_STRATEGY);
745
            List<TaxonNode> children = node.getChildNodes();
746
            Taxon childTaxon;
747
            for (TaxonNode child : children){
748
                childTaxon = child.getTaxon();
749
                if(childTaxon != null) {
750
                childTaxon = (Taxon)taxonService.load(childTaxon.getUuid(), null);
751
                    returnMedia.addAll(getMediaForTaxon(childTaxon, includeRelationships,
752
                            includeTaxonDescriptions, includeOccurrences, includeTaxonNameDescriptions,
753
                            type, mimeTypes, widthOrDuration, height, size));
754
                }
755
            }
756
        }
757
        return returnMedia;
758
    }
759

    
760
    /**
761
     *
762
     * @param taxon
763
     * @param includeRelationships
764
     * @param type
765
     * @param mimeTypes
766
     * @param widthOrDuration
767
     * @param height
768
     * @param size
769
     * @return
770
     */
771
    private List<Media> getMediaForTaxon(Taxon taxon, Set<TaxonRelationshipEdge> includeRelationships,
772
            Boolean includeTaxonDescriptions, Boolean includeOccurrences, Boolean includeTaxonNameDescriptions,
773
            Class<? extends MediaRepresentationPart> type, String[] mimeTypes, Integer widthOrDuration,
774
            Integer height, Integer size) {
775

    
776
        // list the media
777
        logger.trace("getMediaForTaxon() - list the media");
778
        List<Media> taxonGalleryMedia = service.listMedia(taxon, includeRelationships,
779
                false, includeTaxonDescriptions, includeOccurrences, includeTaxonNameDescriptions, null);
780

    
781
        // filter by preferred size and type
782

    
783
        logger.trace("getMediaForTaxon() - filter the media");
784
        Map<Media, MediaRepresentation> mediaRepresentationMap = MediaUtils.findPreferredMedia(
785
                taxonGalleryMedia, type, mimeTypes, null, widthOrDuration, height, size);
786

    
787
        List<Media> filteredMedia = new ArrayList<Media>(mediaRepresentationMap.size());
788
        for (Media media : mediaRepresentationMap.keySet()) {
789
            media.getRepresentations().clear();
790
            media.addRepresentation(mediaRepresentationMap.get(media));
791
            filteredMedia.add(media);
792
        }
793

    
794
        logger.trace("getMediaForTaxon() - END ");
795

    
796
        return filteredMedia;
797
    }
798

    
799
// ---------------------- code snippet preserved for possible later use --------------------
800
//	@RequestMapping(
801
//			value = {"//*/portal/taxon/*/descriptions"}, // mapped as absolute path, see CdmAntPathMatcher
802
//			method = RequestMethod.GET)
803
//	public List<TaxonDescription> doGetDescriptionsbyFeatureTree(HttpServletRequest request, HttpServletResponse response)throws IOException {
804
//		TaxonBase tb = getCdmBase(request, response, null, Taxon.class);
805
//		if(tb instanceof Taxon){
806
//			//T O D O this is a quick and dirty implementation -> generalize
807
//			UUID featureTreeUuid = readValueUuid(request, featureTreeUuidPattern);
808
//
809
//			FeatureTree featureTree = descriptionService.getFeatureTreeByUuid(featureTreeUuid);
810
//			Pager<TaxonDescription> p = descriptionService.getTaxonDescriptions((Taxon)tb, null, null, null, null, TAXONDESCRIPTION_INIT_STRATEGY);
811
//			List<TaxonDescription> descriptions = p.getRecords();
812
//
813
//			if(!featureTree.isDescriptionSeparated()){
814
//
815
//				TaxonDescription superDescription = TaxonDescription.NewInstance();
816
//				//put all descriptionElements in superDescription and make it invisible
817
//				for(TaxonDescription description: descriptions){
818
//					for(DescriptionElementBase element: description.getElements()){
819
//						superDescription.addElement(element);
820
//					}
821
//				}
822
//				List<TaxonDescription> separatedDescriptions = new ArrayList<TaxonDescription>(descriptions.size());
823
//				separatedDescriptions.add(superDescription);
824
//				return separatedDescriptions;
825
//			}else{
826
//				return descriptions;
827
//			}
828
//		} else {
829
//			response.sendError(HttpServletResponse.SC_NOT_FOUND, "invalid type; Taxon expected but " + tb.getClass().getSimpleName() + " found.");
830
//			return null;
831
//		}
832
//	}
833

    
834
}
(58-58/63)