Project

General

Profile

Download (50.3 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 java.io.IOException;
14
import java.util.ArrayList;
15
import java.util.Arrays;
16
import java.util.EnumSet;
17
import java.util.HashSet;
18
import java.util.Hashtable;
19
import java.util.Iterator;
20
import java.util.List;
21
import java.util.Map;
22
import java.util.Set;
23
import java.util.UUID;
24

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

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

    
41
import eu.etaxonomy.cdm.api.service.IClassificationService;
42
import eu.etaxonomy.cdm.api.service.IDescriptionService;
43
import eu.etaxonomy.cdm.api.service.IFeatureTreeService;
44
import eu.etaxonomy.cdm.api.service.INameService;
45
import eu.etaxonomy.cdm.api.service.IOccurrenceService;
46
import eu.etaxonomy.cdm.api.service.ITaxonService;
47
import eu.etaxonomy.cdm.api.service.ITermService;
48
import eu.etaxonomy.cdm.api.service.TaxaAndNamesSearchMode;
49
import eu.etaxonomy.cdm.api.service.config.FindTaxaAndNamesConfiguratorImpl;
50
import eu.etaxonomy.cdm.api.service.config.IFindTaxaAndNamesConfigurator;
51
import eu.etaxonomy.cdm.api.service.pager.Pager;
52
import eu.etaxonomy.cdm.api.service.search.LuceneMultiSearchException;
53
import eu.etaxonomy.cdm.api.service.search.SearchResult;
54
import eu.etaxonomy.cdm.api.service.util.TaxonRelationshipEdge;
55
import eu.etaxonomy.cdm.database.UpdatableRoutingDataSource;
56
import eu.etaxonomy.cdm.model.common.DefinedTermBase;
57
import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
58
import eu.etaxonomy.cdm.model.common.Language;
59
import eu.etaxonomy.cdm.model.common.MarkerType;
60
import eu.etaxonomy.cdm.model.common.RelationshipBase.Direction;
61
import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
62
import eu.etaxonomy.cdm.model.description.Feature;
63
import eu.etaxonomy.cdm.model.description.PresenceAbsenceTermBase;
64
import eu.etaxonomy.cdm.model.description.TaxonDescription;
65
import eu.etaxonomy.cdm.model.location.NamedArea;
66
import eu.etaxonomy.cdm.model.media.Media;
67
import eu.etaxonomy.cdm.model.media.MediaRepresentation;
68
import eu.etaxonomy.cdm.model.media.MediaRepresentationPart;
69
import eu.etaxonomy.cdm.model.media.MediaUtils;
70
import eu.etaxonomy.cdm.model.name.NameRelationship;
71
import eu.etaxonomy.cdm.model.name.TypeDesignationBase;
72
import eu.etaxonomy.cdm.model.taxon.Classification;
73
import eu.etaxonomy.cdm.model.taxon.Synonym;
74
import eu.etaxonomy.cdm.model.taxon.Taxon;
75
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
76
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
77
import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;
78
import eu.etaxonomy.cdm.persistence.query.MatchMode;
79
import eu.etaxonomy.cdm.persistence.query.OrderHint;
80
import eu.etaxonomy.cdm.remote.controller.util.ControllerUtils;
81
import eu.etaxonomy.cdm.remote.controller.util.PagerParameters;
82
import eu.etaxonomy.cdm.remote.editor.CdmTypePropertyEditor;
83
import eu.etaxonomy.cdm.remote.editor.MatchModePropertyEditor;
84
import eu.etaxonomy.cdm.remote.editor.NamedAreaPropertyEditor;
85
import eu.etaxonomy.cdm.remote.editor.UUIDListPropertyEditor;
86
import eu.etaxonomy.cdm.remote.editor.UuidList;
87

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

    
115
    public static final Logger logger = Logger.getLogger(TaxonPortalController.class);
116

    
117
    @Autowired
118
    private INameService nameService;
119

    
120
    @Autowired
121
    private IDescriptionService descriptionService;
122

    
123
    @Autowired
124
    private IOccurrenceService occurrenceService;
125

    
126
    @Autowired
127
    private IClassificationService classificationService;
128

    
129
    @Autowired
130
    private ITaxonService taxonService;
131

    
132
    @Autowired
133
    private ITermService termService;
134

    
135
    @Autowired
136
    private IFeatureTreeService featureTreeService;
137

    
138
    private static final List<String> TAXON_INIT_STRATEGY = Arrays.asList(new String []{
139
            "*",
140
            // taxon relations
141
            "relationsToThisName.fromTaxon.name",
142
            // the name
143
            "name.$",
144
            "name.rank.representations",
145
            "name.status.type.representations",
146

    
147
            // taxon descriptions
148
            "descriptions.elements.area.$",
149
            "descriptions.elements.multilanguageText",
150
            "descriptions.elements.media",
151

    
152
            });
153

    
154
    private static final List<String> TAXON_WITH_NODES_INIT_STRATEGY = Arrays.asList(new String []{
155
            "taxonNodes.$",
156
            "taxonNodes.classification.$",
157
            "taxonNodes.childNodes.$"
158
            });
159

    
160
    private static final List<String> SIMPLE_TAXON_INIT_STRATEGY = Arrays.asList(new String []{
161
            "*",
162
            // taxon relations
163
            "relationsToThisName.fromTaxon.name",
164
            // the name
165
            "name.$",
166
            "name.rank.representations",
167
            "name.status.type.representations",
168
            "name.nomenclaturalReference"
169
            });
170

    
171
    private static final List<String> SYNONYMY_INIT_STRATEGY = Arrays.asList(new String []{
172
            // initialize homotypical and heterotypical groups; needs synonyms
173
            "synonymRelations.$",
174
            "synonymRelations.synonym.$",
175
            "synonymRelations.synonym.name.status.type.representation",
176
            "synonymRelations.synonym.name.nomenclaturalReference.inReference",
177
            "synonymRelations.synonym.name.homotypicalGroup.typifiedNames.$",
178
            "synonymRelations.synonym.name.homotypicalGroup.typifiedNames.taxonBases.$",
179
            "synonymRelations.synonym.name.combinationAuthorTeam.$",
180

    
181
            "name.typeDesignations",
182

    
183
            "name.homotypicalGroup.$",
184
            "name.homotypicalGroup.typifiedNames.$",
185
            "name.homotypicalGroup.typifiedNames.nomenclaturalReference.authorTeam",
186

    
187
            "name.homotypicalGroup.typifiedNames.taxonBases.$"
188
    });
189

    
190
    private static final List<String> SYNONYMY_WITH_NODES_INIT_STRATEGY = Arrays.asList(new String []{
191
            // initialize homotypical and heterotypical groups; needs synonyms
192
            "synonymRelations.$",
193
            "synonymRelations.synonym.$",
194
            "synonymRelations.synonym.name.status.type.representation",
195
            "synonymRelations.synonym.name.nomenclaturalReference.inReference",
196
            "synonymRelations.synonym.name.homotypicalGroup.typifiedNames.$",
197
            "synonymRelations.synonym.name.homotypicalGroup.typifiedNames.taxonBases.$",
198
            "synonymRelations.synonym.name.combinationAuthorTeam.$",
199

    
200
            "name.homotypicalGroup.$",
201
            "name.homotypicalGroup.typifiedNames.$",
202
            "name.homotypicalGroup.typifiedNames.nomenclaturalReference.authorTeam",
203

    
204
            "name.homotypicalGroup.typifiedNames.taxonBases.$",
205

    
206
            "taxonNodes.$",
207
            "taxonNodes.classification.$",
208
            "taxonNodes.childNodes.$"
209
    });
210
    private static final List<String> SIMPLE_TAXON_WITH_NODES_INIT_STRATEGY = Arrays.asList(new String []{
211
            "*",
212
            // taxon relations
213
            "relationsToThisName.fromTaxon.name",
214
            // the name
215
            "name.$",
216
            "name.rank.representations",
217
            "name.status.type.representations",
218
            "name.nomenclaturalReference",
219

    
220
            "taxonNodes.$",
221
            "taxonNodes.classification.$",
222
            "taxonNodes.childNodes.$"
223
            });
224

    
225

    
226
    private static final List<String> TAXONRELATIONSHIP_INIT_STRATEGY = Arrays.asList(new String []{
227
            "$",
228
            "type.inverseRepresentations",
229
            "fromTaxon.sec",
230
            "fromTaxon.name",
231
            "toTaxon.sec",
232
            "toTaxon.name"
233
    });
234

    
235
    private static final List<String> NAMERELATIONSHIP_INIT_STRATEGY = Arrays.asList(new String []{
236
            "$",
237
            "type.inverseRepresentations",
238
            "fromName",
239
            "toName.$",
240
    });
241

    
242

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

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

    
265

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

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

    
277
    });
278

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

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

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

    
294

    
295

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

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

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

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

    
321
    }
322

    
323

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

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

    
336
    @RequestMapping(method = RequestMethod.GET,
337
            value = {"/portal/taxon/find"}) //TODO map to path /*/portal/taxon/
338
    public Pager<IdentifiableEntity> doFind(
339
            @RequestParam(value = "query", required = false) String query,
340
            @RequestParam(value = "tree", required = false) UUID treeUuid,
341
            @RequestParam(value = "area", required = false) Set<NamedArea> areas,
342
            @RequestParam(value = "pageNumber", required = false) Integer pageNumber,
343
            @RequestParam(value = "pageSize", required = false) Integer pageSize,
344
            @RequestParam(value = "doTaxa", required = false) Boolean doTaxa,
345
            @RequestParam(value = "doSynonyms", required = false) Boolean doSynonyms,
346
            @RequestParam(value = "doMisappliedNames", required = false) Boolean doMisappliedNames,
347
            @RequestParam(value = "doTaxaByCommonNames", required = false) Boolean doTaxaByCommonNames,
348
            @RequestParam(value = "matchMode", required = false) MatchMode matchMode,
349
            HttpServletRequest request,
350
            HttpServletResponse response
351
            )
352
             throws IOException {
353

    
354
        logger.info("doFind : " + request.getRequestURI() + "?" + request.getQueryString() );
355

    
356
        PagerParameters pagerParams = new PagerParameters(pageSize, pageNumber);
357
        pagerParams.normalizeAndValidate(response);
358

    
359
        IFindTaxaAndNamesConfigurator config = new FindTaxaAndNamesConfiguratorImpl();
360
        config.setPageNumber(pagerParams.getPageIndex());
361
        config.setPageSize(pagerParams.getPageSize());
362
        config.setTitleSearchString(query);
363
        config.setDoTaxa(doTaxa!= null ? doTaxa : Boolean.FALSE );
364
        config.setDoSynonyms(doSynonyms != null ? doSynonyms : Boolean.FALSE );
365
        config.setDoMisappliedNames(doMisappliedNames != null ? doMisappliedNames : Boolean.FALSE);
366
        config.setDoTaxaByCommonNames(doTaxaByCommonNames != null ? doTaxaByCommonNames : Boolean.FALSE );
367
        config.setMatchMode(matchMode != null ? matchMode : MatchMode.BEGINNING);
368
        config.setTaxonPropertyPath(SIMPLE_TAXON_INIT_STRATEGY);
369
        config.setNamedAreas(areas);
370
        if(treeUuid != null){
371
            Classification classification = classificationService.find(treeUuid);
372
            config.setClassification(classification);
373
        }
374

    
375
        return service.findTaxaAndNames(config);
376
    }
377

    
378
    /**
379
     * <b>NOTE and TODO</b>: this method is a direct copy of the same method in {@link TaxonListController},
380
     * refactorting needed to avoid method dublication
381
     * <p>
382
     * Find Taxa, Synonyms, Common Names by name, either globally or in a specific geographic area.
383
     * <p>
384
     * URI: <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;find</b>
385
     *
386
     * @param query
387
     *            the string to query for. Since the wildcard character '*'
388
     *            internally always is appended to the query string, a search
389
     *            always compares the query string with the beginning of a name.
390
     *            - <i>required parameter</i>
391
     * @param treeUuid
392
     *            the {@link UUID} of a {@link Classification} to which the
393
     *            search is to be restricted. - <i>optional parameter</i>
394
     * @param areas
395
     *            restrict the search to a set of geographic {@link NamedArea}s.
396
     *            The parameter currently takes a list of TDWG area labels.
397
     *            - <i>optional parameter</i>
398
     * @param pageNumber
399
     *            the number of the page to be returned, the first page has the
400
     *            pageNumber = 1 - <i>optional parameter</i>
401
     * @param pageSize
402
     *            the maximum number of entities returned per page (can be -1
403
     *            to return all entities in a single page) - <i>optional parameter</i>
404
     * @param doTaxa
405
     *            weather to search for instances of {@link Taxon} - <i>optional parameter</i>
406
     * @param doSynonyms
407
     *            weather to search for instances of {@link Synonym} - <i>optional parameter</i>
408
     * @param doTaxaByCommonNames
409
     *            for instances of {@link Taxon} by a common name used - <i>optional parameter</i>
410
     * @return a Pager on a list of {@link IdentifiableEntity}s initialized by
411
     *         the following strategy {@link #SIMPLE_TAXON_INIT_STRATEGY}
412
     * @throws IOException
413
     * @throws LuceneMultiSearchException
414
     * @throws ParseException
415
     */
416
    @RequestMapping(method = RequestMethod.GET, value={"/portal/taxon/search"})
417
    public Pager<SearchResult<TaxonBase>> doSearch(
418
            @RequestParam(value = "query", required = true) String query,
419
            @RequestParam(value = "tree", required = false) UUID treeUuid,
420
            @RequestParam(value = "area", required = false) Set<NamedArea> areas,
421
            @RequestParam(value = "status", required = false) Set<PresenceAbsenceTermBase<?>> status,
422
            @RequestParam(value = "pageNumber", required = false) Integer pageNumber,
423
            @RequestParam(value = "pageSize", required = false) Integer pageSize,
424
            @RequestParam(value = "doTaxa", required = false) Boolean doTaxa,
425
            @RequestParam(value = "doSynonyms", required = false) Boolean doSynonyms,
426
            @RequestParam(value = "doMisappliedNames", required = false) Boolean doMisappliedNames,
427
            @RequestParam(value = "doTaxaByCommonNames", required = false) Boolean doTaxaByCommonNames,
428
            HttpServletRequest request,
429
            HttpServletResponse response
430
            )
431
             throws IOException, ParseException, LuceneMultiSearchException {
432

    
433

    
434
        logger.info("search : " + requestPathAndQuery(request) );
435

    
436
        PagerParameters pagerParams = new PagerParameters(pageSize, pageNumber);
437
        pagerParams.normalizeAndValidate(response);
438

    
439
        // TODO change type of do* parameters  to TaxaAndNamesSearchMode
440
        EnumSet<TaxaAndNamesSearchMode> searchModes = EnumSet.noneOf(TaxaAndNamesSearchMode.class);
441
        if(BooleanUtils.toBoolean(doTaxa)) {
442
            searchModes.add(TaxaAndNamesSearchMode.doTaxa);
443
        }
444
        if(BooleanUtils.toBoolean(doSynonyms)) {
445
            searchModes.add(TaxaAndNamesSearchMode.doSynonyms);
446
        }
447
        if(BooleanUtils.toBoolean(doMisappliedNames)) {
448
            searchModes.add(TaxaAndNamesSearchMode.doMisappliedNames);
449
        }
450
        if(BooleanUtils.toBoolean(doTaxaByCommonNames)) {
451
            searchModes.add(TaxaAndNamesSearchMode.doTaxaByCommonNames);
452
        }
453

    
454
        Classification classification = null;
455
        if(treeUuid != null){
456
            classification = classificationService.find(treeUuid);
457
        }
458

    
459
        return service.findTaxaAndNamesByFullText(searchModes, query,
460
                classification, areas, status, null,
461
                false, pagerParams.getPageSize(), pagerParams.getPageIndex(),
462
                null, SIMPLE_TAXON_INIT_STRATEGY);
463
    }
464

    
465
    /**
466
     * @param clazz
467
     * @param queryString
468
     * @param treeUuid
469
     * @param languages
470
     * @param features one or more feature uuids
471
     * @param pageNumber
472
     * @param pageSize
473
     * @param request
474
     * @param response
475
     * @return
476
     * @throws IOException
477
     * @throws ParseException
478
     */
479
    @SuppressWarnings("rawtypes")
480
    @RequestMapping(method = RequestMethod.GET, value={"/portal/taxon/findByDescriptionElementFullText"})
481
    public Pager<SearchResult<TaxonBase>> dofindByDescriptionElementFullText(
482
            @RequestParam(value = "clazz", required = false) Class clazz,
483
            @RequestParam(value = "query", required = true) String queryString,
484
            @RequestParam(value = "tree", required = false) UUID treeUuid,
485
            @RequestParam(value = "features", required = false) UuidList featureUuids,
486
            @RequestParam(value = "languages", required = false) List<Language> languages,
487
            @RequestParam(value = "hl", required = false) Boolean highlighting,
488
            @RequestParam(value = "pageNumber", required = false) Integer pageNumber,
489
            @RequestParam(value = "pageSize", required = false) Integer pageSize,
490
            HttpServletRequest request,
491
            HttpServletResponse response
492
            )
493
             throws IOException, ParseException {
494

    
495
         logger.info("findByDescriptionElementFullText : " + requestPathAndQuery(request) );
496

    
497
         PagerParameters pagerParams = new PagerParameters(pageSize, pageNumber);
498
         pagerParams.normalizeAndValidate(response);
499

    
500
         if(highlighting == null){
501
             highlighting = false;
502
         }
503

    
504
         Classification classification = null;
505
        if(treeUuid != null){
506
            classification = classificationService.find(treeUuid);
507
        }
508

    
509
        List<Feature> features = null;
510
        if(featureUuids != null){
511
            features = new ArrayList<Feature>(featureUuids.size());
512
            for(UUID uuid : featureUuids){
513
                features.add((Feature) termService.find(uuid));
514
            }
515
        }
516

    
517
        Pager<SearchResult<TaxonBase>> pager = service.findByDescriptionElementFullText(clazz, queryString, classification, features, languages, highlighting, pagerParams.getPageSize(), pagerParams.getPageIndex(), ((List<OrderHint>)null), SIMPLE_TAXON_INIT_STRATEGY);
518
        return pager;
519
    }
520

    
521
    /**
522
     * Get the synonymy for a taxon identified by the <code>{taxon-uuid}</code>.
523
     * The synonymy consists
524
     * of two parts: The group of homotypic synonyms of the taxon and the
525
     * heterotypic synonymy groups of the taxon. The synonymy is ordered
526
     * historically by the type designations and by the publication date of the
527
     * nomenclatural reference
528
     * <p>
529
     * URI:
530
     * <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}&#x002F;synonymy</b>
531
     *
532
     *
533
     * @param request
534
     * @param response
535
     * @return a Map with to entries which are mapped by the following keys:
536
     *         "homotypicSynonymsByHomotypicGroup", "heterotypicSynonymyGroups",
537
     *         containing lists of {@link Synonym}s which are initialized using the
538
     *         following initialization strategy: {@link #SYNONYMY_INIT_STRATEGY}
539
     *
540
     * @throws IOException
541
     */
542
    @RequestMapping(
543
            value = {"synonymy"},
544
            method = RequestMethod.GET)
545
    public ModelAndView doGetSynonymy(@PathVariable("uuid") UUID uuid,
546
            HttpServletRequest request, HttpServletResponse response)throws IOException {
547

    
548
        if(request != null){
549
            logger.info("doGetSynonymy() " + requestPathAndQuery(request));
550
        }
551
        ModelAndView mv = new ModelAndView();
552
        Taxon taxon = getCdmBaseInstance(Taxon.class, uuid, response, (List<String>)null);
553
        Map<String, List<?>> synonymy = new Hashtable<String, List<?>>();
554
        synonymy.put("homotypicSynonymsByHomotypicGroup", service.getHomotypicSynonymsByHomotypicGroup(taxon, SYNONYMY_INIT_STRATEGY));
555
        synonymy.put("heterotypicSynonymyGroups", service.getHeterotypicSynonymyGroups(taxon, SYNONYMY_INIT_STRATEGY));
556
        mv.addObject(synonymy);
557
        return mv;
558
    }
559

    
560
    /**
561
     * Get the set of accepted {@link Taxon} entities for a given
562
     * {@link TaxonBase} entity identified by the <code>{taxon-uuid}</code>.
563
     * <p>
564
     * URI: <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}&#x002F;accepted</b>
565
     *
566
     * @param request
567
     * @param response
568
     * @return a Set of {@link Taxon} entities which are initialized
569
     *         using the following initialization strategy:
570
     *         {@link #SYNONYMY_INIT_STRATEGY}
571
     * @throws IOException
572
     */
573
    @RequestMapping(value = "accepted/{classification_uuid}", method = RequestMethod.GET)
574
    public Set<TaxonBase> getAccepted(
575
                @PathVariable("uuid") UUID uuid,
576
                @PathVariable("classification_uuid") UUID classification_uuid,
577
                HttpServletRequest request,
578
                HttpServletResponse response)
579
                throws IOException {
580

    
581
        if(request != null){
582
            logger.info("getAccepted() " + requestPathAndQuery(request));
583
        }
584

    
585
        TaxonBase tb = service.load(uuid, SYNONYMY_WITH_NODES_INIT_STRATEGY);
586
        if(tb == null){
587
            response.sendError(HttpServletResponse.SC_NOT_FOUND, "A taxon with the uuid " + uuid + " does not exist");
588
            return null;
589
        }
590

    
591
        HashSet<TaxonBase> resultset = new HashSet<TaxonBase>();
592

    
593
        if (tb instanceof Taxon){
594
            Taxon taxon = (Taxon) tb;
595
            Set<TaxonNode> nodes = taxon.getTaxonNodes();
596
            for (TaxonNode taxonNode : nodes) {
597
                if (taxonNode.getClassification().compareTo(classification_uuid) == 0){
598
                    resultset.add(tb);
599
                }
600
            }
601
            if (resultset.size() > 1){
602
                //error!! A taxon is not allow to have more taxonnodes for a given classification
603
                response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
604
                "A taxon with the uuid " + uuid + " has more than one taxon node for the given classification" + classification_uuid);
605
            }
606
        }else{
607
            Synonym syn = (Synonym) tb;
608
            for(TaxonBase accepted : syn.getAcceptedTaxa()){
609
                tb = service.load(accepted.getUuid(), SIMPLE_TAXON_WITH_NODES_INIT_STRATEGY);
610
                if (tb instanceof Taxon){
611
                    Taxon taxon = (Taxon) tb;
612
                    Set<TaxonNode> nodes = taxon.getTaxonNodes();
613
                    for (TaxonNode taxonNode : nodes) {
614
                        if (taxonNode.getClassification().compareTo(classification_uuid) == 0){
615
                            resultset.add(tb);
616
                        }
617
                    }
618
                    if (resultset.size() > 1){
619
                        //error!! A taxon is not allow to have more taxonnodes for a given classification
620
                        response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
621
                        "A taxon with the uuid " + uuid + " has more than one taxon node for the given classification" + classification_uuid);
622
                    }
623
                }else{
624
                    //ERROR!! perhaps missapplied name????
625
                    //syn.getRelationType((Taxon)accepted);
626
                }
627
            }
628
        }
629
/**
630
 * OLD CODE!!
631
        if(tb instanceof Taxon){
632
            //the taxon already is accepted
633
            //FIXME take the current view into account once views are implemented!!!
634
            resultset.add((Taxon)tb);
635
        } else {
636
            Synonym syn = (Synonym)tb;
637
            for(TaxonBase accepted : syn.getAcceptedTaxa()){
638
                accepted = service.load(accepted.getUuid(), SIMPLE_TAXON_INIT_STRATEGY);
639
                resultset.add(accepted);
640
            }
641
        }
642
*/
643
        return resultset;
644
    }
645

    
646
    /**
647
     * Get the list of {@link TaxonRelationship}s for the given
648
     * {@link TaxonBase} instance identified by the <code>{taxon-uuid}</code>.
649
     * <p>
650
     * URI: <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}&#x002F;taxonRelationships</b>
651
     *
652
     * @param request
653
     * @param response
654
     * @return a List of {@link TaxonRelationship} entities which are initialized
655
     *         using the following initialization strategy:
656
     *         {@link #TAXONRELATIONSHIP_INIT_STRATEGY}
657
     * @throws IOException
658
     */
659
    @RequestMapping(
660
            value = {"taxonRelationships"},
661
            method = RequestMethod.GET)
662
    public List<TaxonRelationship> doGetTaxonRelations(@PathVariable("uuid") UUID uuid,
663
            HttpServletRequest request, HttpServletResponse response)throws IOException {
664

    
665
        logger.info("doGetTaxonRelations()" + requestPathAndQuery(request));
666
        Taxon taxon = getCdmBaseInstance(Taxon.class, uuid, response, (List<String>)null);
667
        List<TaxonRelationship> toRelationships = service.listToTaxonRelationships(taxon, null, null, null, null, TAXONRELATIONSHIP_INIT_STRATEGY);
668
        List<TaxonRelationship> fromRelationships = service.listFromTaxonRelationships(taxon, null, null, null, null, TAXONRELATIONSHIP_INIT_STRATEGY);
669

    
670
        List<TaxonRelationship> allRelationships = new ArrayList<TaxonRelationship>(toRelationships.size() + fromRelationships.size());
671
        allRelationships.addAll(toRelationships);
672
        allRelationships.addAll(fromRelationships);
673

    
674
        return allRelationships;
675
    }
676

    
677
    /**
678
     * Get the list of {@link NameRelationship}s of the Name associated with the
679
     * {@link TaxonBase} instance identified by the <code>{taxon-uuid}</code>.
680
     * <p>
681
     * URI: <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}&#x002F;nameRelationships</b>
682
     *
683
     * @param request
684
     * @param response
685
     * @return a List of {@link NameRelationship} entities which are initialized
686
     *         using the following initialization strategy:
687
     *         {@link #NAMERELATIONSHIP_INIT_STRATEGY}
688
     * @throws IOException
689
     */
690
    @RequestMapping(
691
            value = {"toNameRelationships"},
692
            method = RequestMethod.GET)
693
    public List<NameRelationship> doGetToNameRelations(@PathVariable("uuid") UUID uuid,
694
            HttpServletRequest request, HttpServletResponse response)throws IOException {
695
        logger.info("doGetNameRelations()" + request.getRequestURI());
696
        TaxonBase taxonBase = getCdmBaseInstance(TaxonBase.class, uuid, response, (List<String>)null);
697
        List<NameRelationship> list = nameService.listNameRelationships(taxonBase.getName(), Direction.relatedTo, null, null, 0, null, NAMERELATIONSHIP_INIT_STRATEGY);
698
        //List<NameRelationship> list = nameService.listToNameRelationships(taxonBase.getName(), null, null, null, null, NAMERELATIONSHIP_INIT_STRATEGY);
699
        return list;
700
    }
701

    
702
    /**
703
     * Get the list of {@link NameRelationship}s of the Name associated with the
704
     * {@link TaxonBase} instance identified by the <code>{taxon-uuid}</code>.
705
     * <p>
706
     * URI: <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}&#x002F;nameRelationships</b>
707
     *
708
     * @param request
709
     * @param response
710
     * @return a List of {@link NameRelationship} entities which are initialized
711
     *         using the following initialization strategy:
712
     *         {@link #NAMERELATIONSHIP_INIT_STRATEGY}
713
     * @throws IOException
714
     */
715
    @RequestMapping(
716
            value = {"fromNameRelationships"},
717
            method = RequestMethod.GET)
718
    public List<NameRelationship> doGetFromNameRelations(@PathVariable("uuid") UUID uuid,
719
            HttpServletRequest request, HttpServletResponse response)throws IOException {
720
        logger.info("doGetNameFromNameRelations()" + requestPathAndQuery(request));
721

    
722
        TaxonBase taxonbase = getCdmBaseInstance(TaxonBase.class, uuid, response, SIMPLE_TAXON_INIT_STRATEGY);
723
        List<NameRelationship> list = nameService.listNameRelationships(taxonbase.getName(), Direction.relatedFrom, null, null, 0, null, NAMERELATIONSHIP_INIT_STRATEGY);
724
        //List<NameRelationship> list = nameService.listFromNameRelationships(taxonbase.getName(), null, null, null, null, NAMERELATIONSHIP_INIT_STRATEGY);
725
        return list;
726
    }
727

    
728
    /**
729
     * Get the list of {@link TypeDesignationBase}s of the
730
     * {@link TaxonBase} instance identified by the <code>{taxon-uuid}</code>.
731
     * <p>
732
     * URI: <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}&#x002F;nameTypeDesignations</b>
733
     *
734
     * @param request
735
     * @param response
736
     * @return a List of {@link TypeDesignationBase} entities which are initialized
737
     *         using the following initialization strategy:
738
     *         {@link #TYPEDESIGNATION_INIT_STRATEGY}
739
     * @throws IOException
740
     * @Deprecated use &#x002F;name&#x002F;{uuid}&#x002F;typeDesignations & &#x002F;derivedunitfacade&#x002F;{uuid} instead
741
     * also see http://dev.e-taxonomy.eu/trac/ticket/2280
742
     */
743
    @Deprecated
744
    @RequestMapping(
745
            value = {"nameTypeDesignations"},
746
            method = RequestMethod.GET)
747
    public List<TypeDesignationBase> doGetNameTypeDesignations(@PathVariable("uuid") UUID uuid,
748
            HttpServletRequest request, HttpServletResponse response)throws IOException {
749
        logger.info("doGetNameTypeDesignations()" + request.getRequestURI());
750
        Taxon taxon = getCdmBaseInstance(Taxon.class, uuid, response, SIMPLE_TAXON_INIT_STRATEGY);
751
        Pager<TypeDesignationBase> p = nameService.getTypeDesignations(taxon.getName(), null, null, null, TYPEDESIGNATION_INIT_STRATEGY);
752
        return p.getRecords();
753
    }
754

    
755
    @RequestMapping(value = "taxonNodes", method = RequestMethod.GET)
756
    public Set<TaxonNode>  doGetTaxonNodes(
757
            @PathVariable("uuid") UUID uuid,
758
            HttpServletRequest request,
759
            HttpServletResponse response) throws IOException {
760
        logger.info("doGetTaxonNodes" + requestPathAndQuery(request));
761
        TaxonBase taxon = service.load(uuid, TAXONNODE_INIT_STRATEGY);
762
        if(taxon instanceof Taxon){
763
            return ((Taxon)taxon).getTaxonNodes();
764
        } else {
765
            HttpStatusMessage.UUID_REFERENCES_WRONG_TYPE.send(response);
766
            return null;
767
        }
768
    }
769

    
770
    /**
771
     * Get the list of {@link TaxonDescription}s of the
772
     * {@link Taxon} instance identified by the <code>{taxon-uuid}</code>.
773
     * <p>
774
     * URI: <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}&#x002F;descriptions</b>
775
     *
776
     * @param request
777
     * @param response
778
     * @return a List of {@link TaxonDescription} entities which are initialized
779
     *         using the following initialization strategy:
780
     *         {@link #TAXONDESCRIPTION_INIT_STRATEGY}
781
     * @throws IOException
782
     */
783
    @RequestMapping(
784
            value = {"descriptions"},
785
            method = RequestMethod.GET)
786
    public List<TaxonDescription> doGetDescriptions(
787
            @PathVariable("uuid") UUID uuid,
788
            @RequestParam(value = "markerTypes", required = false) UuidList markerTypeUUIDs,
789
            HttpServletRequest request,
790
            HttpServletResponse response)throws IOException {
791
        if(request != null){
792
            logger.info("doGetDescriptions()" + requestPathAndQuery(request));
793
        }
794
        List<DefinedTermBase> markerTypeTerms = null;
795
        Set<UUID> sMarkerTypeUUIDs = null;
796

    
797
        if(markerTypeUUIDs != null && !markerTypeUUIDs.isEmpty()){
798
            sMarkerTypeUUIDs = new HashSet<UUID>(markerTypeUUIDs);
799
            markerTypeTerms = termService.find(sMarkerTypeUUIDs);
800
        } else if(markerTypeUUIDs != null && markerTypeUUIDs.isEmpty()){
801
            markerTypeTerms = new ArrayList<DefinedTermBase>();
802
        }
803
        Set<MarkerType> markerTypes = new HashSet<MarkerType>();
804
        List<TaxonDescription> descriptions = new ArrayList<TaxonDescription>();
805
        if (markerTypeTerms != null) {
806
            for (DefinedTermBase markerTypeTerm : markerTypeTerms) {
807
                markerTypes.add((MarkerType)markerTypeTerm);
808
            }
809
        }
810
        Taxon t = getCdmBaseInstance(Taxon.class, uuid, response, (List<String>)null);
811
        if (markerTypeTerms == null) {
812

    
813
            Pager<TaxonDescription> p = descriptionService.pageTaxonDescriptions(t, null, null, null, null, TAXONDESCRIPTION_INIT_STRATEGY);
814
            descriptions = p.getRecords();
815
        }
816

    
817
        else if (markerTypeTerms != null && markerTypeTerms.isEmpty()) {
818
            descriptions = descriptionService.listTaxonDescriptions(t, null, null, markerTypes, null, null, TAXONDESCRIPTION_INIT_STRATEGY);
819

    
820
        }
821
        else {
822
            descriptions = descriptionService.listTaxonDescriptions(t, null, null, markerTypes, null, null, TAXONDESCRIPTION_INIT_STRATEGY);
823
            /*for (TaxonDescription description: descriptions) {
824
                for (IdentifiableSource source :description.getSources()) {
825
                    if (source.getOriginalNameString() != null) {
826
                        description.
827
                    }
828

    
829
                }
830

    
831

    
832
            }*/
833
        }
834
        return descriptions;
835
    }
836

    
837
    @RequestMapping(value = "useDescriptions", method = RequestMethod.GET)
838
    public List<TaxonDescription> doGetUseDescriptions(
839
            @PathVariable("uuid") UUID uuid,
840
            HttpServletRequest request,
841
            HttpServletResponse response) throws IOException {
842
        logger.info("doGetDescriptionElements() - " + requestPathAndQuery(request));
843

    
844
        //ModelAndView mv = new ModelAndView();
845
        Taxon t = getCdmBaseInstance(Taxon.class, uuid, response, (List<String>)null);
846

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

    
850
       //find(UUID.fromString("2e6e42d9-e92a-41f4-899b-03c0ac64f059"));
851
       Set<MarkerType> markerTypes =  new HashSet<MarkerType>();
852
       markerTypes.add(useMarkerType);
853
       List<TaxonDescription> descriptionElements = descriptionService.listTaxonDescriptions(t, null, null, markerTypes, null, null, TAXONDESCRIPTION_INIT_STRATEGY);
854
        //getDescriptionElements(description, features, type, pageSize, pageNumber, propertyPaths)  load(uuid);
855

    
856
        /*if(!(description instanceof TaxonDescription)){
857
            HttpStatusMessage.UUID_REFERENCES_WRONG_TYPE.send(response);
858
            // will terminate thread
859
        }*/
860

    
861
        //boolean hasStructuredData = service.        hasStructuredData(description);
862

    
863
        //mv.addObject(hasStructuredData);
864

    
865
        return descriptionElements;
866
    }
867

    
868
    @RequestMapping(value = "descriptions/elementsByType/{classSimpleName}", method = RequestMethod.GET)
869
    public ModelAndView doGetDescriptionElementsByType(
870
            @PathVariable("uuid") UUID uuid,
871
            @PathVariable("classSimpleName") String classSimpleName,
872
            @RequestParam(value = "markerTypes", required = false) UuidList markerTypeUUIDs,
873
            @RequestParam(value = "count", required = false, defaultValue = "false") Boolean doCount,
874
            HttpServletRequest request,
875
            HttpServletResponse response) throws IOException {
876
        logger.info("doGetDescriptionElementsByType() - " + requestPathAndQuery(request));
877

    
878
        ModelAndView mv = new ModelAndView();
879

    
880
        List<DescriptionElementBase> allElements = new ArrayList<DescriptionElementBase>();
881
        List<DescriptionElementBase> elements;
882
        int count = 0;
883

    
884
        List<String> initStrategy = doCount ? null : DESCRIPTION_ELEMENT_INIT_STRATEGY;
885

    
886
        List<TaxonDescription> taxonDescriptions = doGetDescriptions(uuid, markerTypeUUIDs, request, response);
887
        try {
888
            Class type;
889
            type = Class.forName("eu.etaxonomy.cdm.model.description."
890
                    + classSimpleName);
891
            if (taxonDescriptions != null) {
892
                for (TaxonDescription description : taxonDescriptions) {
893
                    elements = descriptionService.listDescriptionElements(description, null, type, null, 0, initStrategy);
894
                    allElements.addAll(elements);
895
                    count += elements.size();
896
                }
897

    
898
            }
899
        } catch (ClassNotFoundException e) {
900
            HttpStatusMessage.fromString(e.getLocalizedMessage()).send(response);
901
        }
902
        if(doCount){
903
            mv.addObject(count);
904
        } else {
905
            mv.addObject(allElements);
906
        }
907
        return mv;
908
    }
909

    
910
//	@RequestMapping(value = "specimens", method = RequestMethod.GET)
911
//	public ModelAndView doGetSpecimens(
912
//			@PathVariable("uuid") UUID uuid,
913
//			HttpServletRequest request,
914
//			HttpServletResponse response) throws IOException, ClassNotFoundException {
915
//		logger.info("doGetSpecimens() - " + request.getRequestURI());
916
//
917
//		ModelAndView mv = new ModelAndView();
918
//
919
//		List<DerivedUnitFacade> derivedUnitFacadeList = new ArrayList<DerivedUnitFacade>();
920
//
921
//		// find speciemens in the TaxonDescriptions
922
//		List<TaxonDescription> taxonDescriptions = doGetDescriptions(uuid, request, response);
923
//		if (taxonDescriptions != null) {
924
//
925
//			for (TaxonDescription description : taxonDescriptions) {
926
//				derivedUnitFacadeList.addAll( occurrenceService.listDerivedUnitFacades(description, null) );
927
//			}
928
//		}
929
//		// TODO find speciemens in the NameDescriptions ??
930
//
931
//		// TODO also find type specimens
932
//
933
//		mv.addObject(derivedUnitFacadeList);
934
//
935
//		return mv;
936
//	}
937

    
938
    /**
939
     * Get the {@link Media} attached to the {@link Taxon} instance
940
     * identified by the <code>{taxon-uuid}</code>.
941
     *
942
     * Usage &#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-
943
     * uuid}&#x002F;media&#x002F;{mime type
944
     * list}&#x002F;{size}[,[widthOrDuration}][,{height}]&#x002F;
945
     *
946
     * Whereas
947
     * <ul>
948
     * <li><b>{mime type list}</b>: a comma separated list of mime types, in the
949
     * order of preference. The forward slashes contained in the mime types must
950
     * be replaced by a colon. Regular expressions can be used. Each media
951
     * associated with this given taxon is being searched whereas the first
952
     * matching mime type matching a representation always rules.</li>
953
     * <li><b>{size},{widthOrDuration},{height}</b>: <i>not jet implemented</i>
954
     * valid values are an integer or the asterisk '*' as a wildcard</li>
955
     * </ul>
956
     *
957
     * @param request
958
     * @param response
959
     * @return a List of {@link Media} entities which are initialized
960
     *         using the following initialization strategy:
961
     *         {@link #TAXONDESCRIPTION_INIT_STRATEGY}
962
     * @throws IOException
963
     */
964
    @RequestMapping(
965
        value = {"media"},
966
        method = RequestMethod.GET)
967
    public List<Media> doGetMedia(
968
            @PathVariable("uuid") UUID uuid,
969
            @RequestParam(value = "type", required = false) Class<? extends MediaRepresentationPart> type,
970
            @RequestParam(value = "mimeTypes", required = false) String[] mimeTypes,
971
            @RequestParam(value = "relationships", required = false) UuidList relationshipUuids,
972
            @RequestParam(value = "relationshipsInvers", required = false) UuidList relationshipInversUuids,
973
            @RequestParam(value = "includeTaxonDescriptions", required = true) Boolean  includeTaxonDescriptions,
974
            @RequestParam(value = "includeOccurrences", required = true) Boolean  includeOccurrences,
975
            @RequestParam(value = "includeTaxonNameDescriptions", required = true) Boolean  includeTaxonNameDescriptions,
976
            @RequestParam(value = "widthOrDuration", required = false) Integer  widthOrDuration,
977
            @RequestParam(value = "height", required = false) Integer height,
978
            @RequestParam(value = "size", required = false) Integer size,
979
            HttpServletRequest request, HttpServletResponse response) throws IOException {
980

    
981
        logger.info("doGetMedia() " + requestPathAndQuery(request));
982

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

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

    
987
        List<Media> returnMedia = getMediaForTaxon(taxon, includeRelationships,
988
                includeTaxonDescriptions, includeOccurrences, includeTaxonNameDescriptions,
989
                type, mimeTypes, widthOrDuration, height, size);
990
        return returnMedia;
991
    }
992

    
993
    @RequestMapping(
994
            value = {"subtree/media"},
995
            method = RequestMethod.GET)
996
        public List<Media> doGetSubtreeMedia(
997
                @PathVariable("uuid") UUID uuid,
998
                @RequestParam(value = "type", required = false) Class<? extends MediaRepresentationPart> type,
999
                @RequestParam(value = "mimeTypes", required = false) String[] mimeTypes,
1000
                @RequestParam(value = "relationships", required = false) UuidList relationshipUuids,
1001
                @RequestParam(value = "relationshipsInvers", required = false) UuidList relationshipInversUuids,
1002
                @RequestParam(value = "includeTaxonDescriptions", required = true) Boolean  includeTaxonDescriptions,
1003
                @RequestParam(value = "includeOccurrences", required = true) Boolean  includeOccurrences,
1004
                @RequestParam(value = "includeTaxonNameDescriptions", required = true) Boolean  includeTaxonNameDescriptions,
1005
                @RequestParam(value = "widthOrDuration", required = false) Integer  widthOrDuration,
1006
                @RequestParam(value = "height", required = false) Integer height,
1007
                @RequestParam(value = "size", required = false) Integer size,
1008
                HttpServletRequest request, HttpServletResponse response)throws IOException {
1009

    
1010
        logger.info("doGetSubtreeMedia() " + requestPathAndQuery(request));
1011

    
1012
        Taxon taxon = getCdmBaseInstance(Taxon.class, uuid, response, TAXON_WITH_NODES_INIT_STRATEGY);
1013

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

    
1016
        List<Media> returnMedia = getMediaForTaxon(taxon, includeRelationships,
1017
                includeTaxonDescriptions, includeOccurrences, includeTaxonNameDescriptions,
1018
                type, mimeTypes, widthOrDuration, height, size);
1019
        TaxonNode node;
1020
        //looking for all medias of genus
1021
        if (taxon.getTaxonNodes().size()>0){
1022
            Set<TaxonNode> nodes = taxon.getTaxonNodes();
1023
            Iterator<TaxonNode> iterator = nodes.iterator();
1024
            //TaxonNode holen
1025
            node = iterator.next();
1026
            //Check if TaxonNode belongs to the current tree
1027

    
1028
            node = classificationService.loadTaxonNode(node, TAXONNODE_WITHTAXON_INIT_STRATEGY);
1029
            List<TaxonNode> children = node.getChildNodes();
1030
            Taxon childTaxon;
1031
            for (TaxonNode child : children){
1032
                childTaxon = child.getTaxon();
1033
                childTaxon = (Taxon)taxonService.load(childTaxon.getUuid(), null);
1034
                returnMedia.addAll(getMediaForTaxon(childTaxon, includeRelationships,
1035
                        includeTaxonDescriptions, includeOccurrences, includeTaxonNameDescriptions,
1036
                        type, mimeTypes, widthOrDuration, height, size));
1037
            }
1038
        }
1039
        return returnMedia;
1040
    }
1041

    
1042
    /**
1043
     *
1044
     * @param taxon
1045
     * @param includeRelationships
1046
     * @param type
1047
     * @param mimeTypes
1048
     * @param widthOrDuration
1049
     * @param height
1050
     * @param size
1051
     * @return
1052
     */
1053
    private List<Media> getMediaForTaxon(Taxon taxon, Set<TaxonRelationshipEdge> includeRelationships,
1054
            Boolean includeTaxonDescriptions, Boolean includeOccurrences, Boolean includeTaxonNameDescriptions,
1055
            Class<? extends MediaRepresentationPart> type, String[] mimeTypes, Integer widthOrDuration, Integer height,
1056
            Integer size) {
1057

    
1058
        List<Media> taxonGalleryMedia = service.listMedia(taxon, includeRelationships, false, includeTaxonDescriptions,
1059
                includeOccurrences, includeTaxonNameDescriptions, TAXONDESCRIPTION_MEDIA_INIT_STRATEGY);
1060

    
1061
        Map<Media, MediaRepresentation> mediaRepresentationMap = MediaUtils.findPreferredMedia(taxonGalleryMedia, type,
1062
                mimeTypes, null, widthOrDuration, height, size);
1063

    
1064
        List<Media> filteredMedia = new ArrayList<Media>(mediaRepresentationMap.size());
1065
        for (Media media : mediaRepresentationMap.keySet()) {
1066
            media.getRepresentations().clear();
1067
            media.addRepresentation(mediaRepresentationMap.get(media));
1068
            filteredMedia.add(media);
1069
        }
1070

    
1071
        return filteredMedia;
1072
    }
1073

    
1074
// ---------------------- code snippet preserved for possible later use --------------------
1075
//	@RequestMapping(
1076
//			value = {"/*/portal/taxon/*/descriptions"},
1077
//			method = RequestMethod.GET)
1078
//	public List<TaxonDescription> doGetDescriptionsbyFeatureTree(HttpServletRequest request, HttpServletResponse response)throws IOException {
1079
//		TaxonBase tb = getCdmBase(request, response, null, Taxon.class);
1080
//		if(tb instanceof Taxon){
1081
//			//T O D O this is a quick and dirty implementation -> generalize
1082
//			UUID featureTreeUuid = readValueUuid(request, featureTreeUuidPattern);
1083
//
1084
//			FeatureTree featureTree = descriptionService.getFeatureTreeByUuid(featureTreeUuid);
1085
//			Pager<TaxonDescription> p = descriptionService.getTaxonDescriptions((Taxon)tb, null, null, null, null, TAXONDESCRIPTION_INIT_STRATEGY);
1086
//			List<TaxonDescription> descriptions = p.getRecords();
1087
//
1088
//			if(!featureTree.isDescriptionSeparated()){
1089
//
1090
//				TaxonDescription superDescription = TaxonDescription.NewInstance();
1091
//				//put all descriptionElements in superDescription and make it invisible
1092
//				for(TaxonDescription description: descriptions){
1093
//					for(DescriptionElementBase element: description.getElements()){
1094
//						superDescription.addElement(element);
1095
//					}
1096
//				}
1097
//				List<TaxonDescription> separatedDescriptions = new ArrayList<TaxonDescription>(descriptions.size());
1098
//				separatedDescriptions.add(superDescription);
1099
//				return separatedDescriptions;
1100
//			}else{
1101
//				return descriptions;
1102
//			}
1103
//		} else {
1104
//			response.sendError(HttpServletResponse.SC_NOT_FOUND, "invalid type; Taxon expected but " + tb.getClass().getSimpleName() + " found.");
1105
//			return null;
1106
//		}
1107
//	}
1108

    
1109
}
(52-52/56)