Project

General

Profile

Download (31.6 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2007 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9

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

    
12
import java.io.IOException;
13
import java.util.ArrayList;
14
import java.util.Arrays;
15
import java.util.Hashtable;
16
import java.util.Iterator;
17
import java.util.List;
18
import java.util.Map;
19
import java.util.Set;
20
import java.util.UUID;
21

    
22
import javax.servlet.http.HttpServletRequest;
23
import javax.servlet.http.HttpServletResponse;
24

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

    
36
import eu.etaxonomy.cdm.api.service.INameService;
37
import eu.etaxonomy.cdm.api.service.ITaxonNodeService;
38
import eu.etaxonomy.cdm.api.service.ITaxonService;
39
import eu.etaxonomy.cdm.api.service.ITermService;
40
import eu.etaxonomy.cdm.api.service.util.TaxonRelationshipEdge;
41
import eu.etaxonomy.cdm.database.UpdatableRoutingDataSource;
42
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
43
import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
44
import eu.etaxonomy.cdm.model.common.RelationshipBase.Direction;
45
import eu.etaxonomy.cdm.model.location.NamedArea;
46
import eu.etaxonomy.cdm.model.media.Media;
47
import eu.etaxonomy.cdm.model.media.MediaRepresentationPart;
48
import eu.etaxonomy.cdm.model.name.NameRelationship;
49
import eu.etaxonomy.cdm.model.taxon.Synonym;
50
import eu.etaxonomy.cdm.model.taxon.Taxon;
51
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
52
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
53
import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;
54
import eu.etaxonomy.cdm.persistence.dao.initializer.EntityInitStrategy;
55
import eu.etaxonomy.cdm.persistence.query.MatchMode;
56
import eu.etaxonomy.cdm.remote.controller.util.ControllerUtils;
57
import eu.etaxonomy.cdm.remote.controller.util.IMediaToolbox;
58
import eu.etaxonomy.cdm.remote.editor.CdmTypePropertyEditor;
59
import eu.etaxonomy.cdm.remote.editor.DefinedTermBaseList;
60
import eu.etaxonomy.cdm.remote.editor.MatchModePropertyEditor;
61
import eu.etaxonomy.cdm.remote.editor.NamedAreaPropertyEditor;
62
import eu.etaxonomy.cdm.remote.editor.TermBaseListPropertyEditor;
63
import eu.etaxonomy.cdm.remote.editor.UUIDListPropertyEditor;
64
import eu.etaxonomy.cdm.remote.editor.UuidList;
65
import io.swagger.annotations.Api;
66

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

    
94
    public static final Logger logger = Logger.getLogger(TaxonPortalController.class);
95

    
96
    @Autowired
97
    private INameService nameService;
98

    
99
    @Autowired
100
    private ITaxonNodeService taxonNodeService;
101

    
102
    @Autowired
103
    private ITaxonService taxonService;
104

    
105
    @Autowired
106
    private ITermService termService;
107

    
108
    @Autowired
109
    private IMediaToolbox mediaToolbox;
110

    
111

    
112
    public static final EntityInitStrategy TAXON_INIT_STRATEGY = new EntityInitStrategy(Arrays.asList(new String []{
113
            "$",
114
            "sources",
115
            "statusNote",
116
            // taxon relations
117
//            "relationsToThisName.fromTaxon.name",
118
            // the name
119
            "name.$",
120
            "name.nomenclaturalSource.citation.authorship",
121
            "name.nomenclaturalSource.citation.inReference",
122
            "name.rank.representations",
123
            "name.status.type.representations",
124
            "sec.authorship"
125
//            "descriptions" // TODO remove
126

    
127
            }));
128

    
129
    public static final EntityInitStrategy TAXON_WITH_CHILDNODES_INIT_STRATEGY = new EntityInitStrategy(Arrays.asList(new String []{
130
            "taxonNodes.$",
131
            "taxonNodes.classification.$",
132
            "taxonNodes.childNodes.$"
133
            }));
134

    
135
    public static final EntityInitStrategy SIMPLE_TAXON_INIT_STRATEGY = new EntityInitStrategy(Arrays.asList(new String []{
136
            "$",
137
            // the name
138
            "name.$",
139
            "name.rank.representations",
140
            "name.status.type.representations",
141
            "name.nomenclaturalSource.citation.authorship",
142
            "name.nomenclaturalSource.citation.inReference.authorship",
143
            "taxonNodes.classification",
144
            "sec.authorship"
145
            }));
146

    
147
    public static final EntityInitStrategy SYNONYMY_INIT_STRATEGY = new EntityInitStrategy(Arrays.asList(new String []{
148
            // initialize homotypical and heterotypical groups; needs synonyms
149
            "synonyms.$",
150
            "synonyms.name.status.type.representations",
151
            "synonyms.name.nomenclaturalSource.citation.authorship",
152
            "synonyms.name.nomenclaturalSource.citation.inReference",
153
//            "synonyms.name.homotypicalGroup.typifiedNames.$",
154
//            "synonyms.name.homotypicalGroup.typifiedNames.taxonBases.$",
155
            "synonyms.name.combinationAuthorship.$",
156

    
157
            "name.typeDesignations",
158

    
159
            "name.homotypicalGroup.$",
160
            "name.homotypicalGroup.typifiedNames.$",
161
            "name.homotypicalGroup.typifiedNames.nomenclaturalSource.citation.authorship",
162
            "name.homotypicalGroup.typifiedNames.nomenclaturalSource.citation.inReference",
163
//            "name.homotypicalGroup.typifiedNames.taxonBases.$"
164
    }));
165

    
166

    
167
    private static final EntityInitStrategy TAXONRELATIONSHIP_INIT_STRATEGY = new EntityInitStrategy(Arrays.asList(new String []{
168
            "$",
169
            "type.inverseRepresentations",
170
            "fromTaxon.sec",
171
            "fromTaxon.name",
172
            "toTaxon.sec",
173
            "toTaxon.name"
174
    }));
175

    
176
    public static final EntityInitStrategy NAMERELATIONSHIP_INIT_STRATEGY = new EntityInitStrategy(Arrays.asList(new String []{
177
            "$",
178
            "type.inverseRepresentations",
179
            "citation",
180
            "toName.$",
181
            "toName.nomenclaturalSource.citation.authorship",
182
            "toName.nomenclaturalSource.citation.inReference",
183
            "fromName.$",
184
            "fromName.nomenclaturalSource.citation.authorship",
185
            "fromName.nomenclaturalSource.citation.inReference",
186

    
187
    }));
188

    
189
    protected static final EntityInitStrategy TAXONDESCRIPTION_INIT_STRATEGY = DescriptionPortalController.DESCRIPTION_INIT_STRATEGY;
190

    
191
    protected static final EntityInitStrategy DESCRIPTION_ELEMENT_INIT_STRATEGY = new EntityInitStrategy(Arrays.asList(new String []{
192
            "$",
193
            "sources.citation.authorship",
194
            "sources.nameUsedInSource",
195
            "multilanguageText",
196
            "media",
197
    }));
198

    
199

    
200
//	private static final List<String> NAMEDESCRIPTION_INIT_STRATEGY = Arrays.asList(new String []{
201
//			"uuid",
202
//			"feature",
203
//			"elements.$",
204
//			"elements.multilanguageText",
205
//			"elements.media",
206
//	});
207

    
208
    protected static final EntityInitStrategy TAXONDESCRIPTION_MEDIA_INIT_STRATEGY = new EntityInitStrategy(Arrays.asList(new String []{
209
            "elements.media"
210

    
211
    }));
212

    
213
    private static final EntityInitStrategy TYPEDESIGNATION_INIT_STRATEGY = new EntityInitStrategy(Arrays.asList(new String []{
214
            "typeSpecimen.$",
215
            "citation.authorship.$",
216
            "typeName",
217
            "typeStatus"
218
    }));
219

    
220
    protected static final EntityInitStrategy TAXONNODE_WITH_CHILDNODES_INIT_STRATEGY = new EntityInitStrategy(Arrays.asList(new String []{
221
            "childNodes.taxon",
222
    }));
223

    
224
    protected static final EntityInitStrategy TAXONNODE_INIT_STRATEGY = new EntityInitStrategy(Arrays.asList(new String []{
225
            "taxonNodes.classification",
226
            "taxonNodes.statusNote.*",
227
            "taxonNodes.source.citation",
228
            "acceptedTaxon.taxonNodes.classification",
229
    }));
230

    
231
    private static final String termTreeUuidPattern = "^/taxon(?:(?:/)([^/?#&\\.]+))+.*";
232

    
233

    
234
    public TaxonPortalController(){
235
        super();
236
        setInitializationStrategy(TAXON_INIT_STRATEGY.getPropertyPaths());
237
    }
238

    
239
    @Autowired
240
    @Override
241
    public void setService(ITaxonService service) {
242
        this.service = service;
243
    }
244

    
245
    @InitBinder
246
    @Override
247
    public void initBinder(WebDataBinder binder) {
248
        super.initBinder(binder);
249
        binder.registerCustomEditor(NamedArea.class, new NamedAreaPropertyEditor());
250
        binder.registerCustomEditor(MatchMode.class, new MatchModePropertyEditor());
251
        binder.registerCustomEditor(Class.class, new CdmTypePropertyEditor());
252
        binder.registerCustomEditor(UuidList.class, new UUIDListPropertyEditor());
253
        binder.registerCustomEditor(DefinedTermBaseList.class, new TermBaseListPropertyEditor<>(termService));
254
    }
255

    
256
    /**
257
     * Get the synonymy for a taxon identified by the <code>{taxon-uuid}</code>.
258
     * The synonymy consists
259
     * of two parts: The group of homotypic synonyms of the taxon and the
260
     * heterotypic synonymy groups of the taxon. The synonymy is ordered
261
     * historically by the type designations and by the publication date of the
262
     * nomenclatural reference
263
     * <p>
264
     * URI:
265
     * <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}&#x002F;synonymy</b>
266
     *
267
     *
268
     * @param request
269
     * @param response
270
     * @return a Map with two entries which are mapped by the following keys:
271
     *         "homotypicSynonymsByHomotypicGroup", "heterotypicSynonymyGroups",
272
     *         containing lists of {@link Synonym}s which // TODO Auto-generated catch block
273
                    e.printStackTrace();are initialized using the
274
     *         following initialization strategy: {@link #SYNONYMY_INIT_STRATEGY}
275
     *
276
     * @throws IOException
277
     */
278
    @RequestMapping(
279
            value = {"synonymy"},
280
            method = RequestMethod.GET)
281
    public ModelAndView doGetSynonymy(@PathVariable("uuid") UUID taxonUuid,
282
            @RequestParam(value = "subtree", required = false) UUID subtreeUuid,
283
            HttpServletRequest request,
284
            HttpServletResponse response)throws IOException {
285

    
286
        boolean includeUnpublished = NO_UNPUBLISHED;
287
        if(request != null){
288
            logger.info("doGetSynonymy() " + requestPathAndQuery(request));
289
        }
290
        ModelAndView mv = new ModelAndView();
291

    
292
        Taxon taxon = getCdmBaseInstance(Taxon.class, taxonUuid, response, getTaxonNodeInitStrategy().getPropertyPaths());
293
        TaxonNode subtree = getSubtreeOrError(subtreeUuid, taxonNodeService, response);
294
        taxon = checkExistsSubtreeAndAccess(taxon, subtree, NO_UNPUBLISHED, response);
295

    
296
        Map<String, List<?>> synonymy = new Hashtable<>();
297

    
298
        //new
299
        List<List<Synonym>> synonymyGroups = service.getSynonymsByHomotypicGroup(taxon, SYNONYMY_INIT_STRATEGY.getPropertyPaths());
300
        if(!includeUnpublished){
301
            synonymyGroups = removeUnpublishedSynonyms(synonymyGroups);
302
        }
303

    
304
        synonymy.put("homotypicSynonymsByHomotypicGroup", synonymyGroups.get(0));
305
        synonymyGroups.remove(0);
306
        synonymy.put("heterotypicSynonymyGroups", synonymyGroups);
307

    
308
        //old
309
//        synonymy.put("homotypicSynonymsByHomotypicGroup", service.getHomotypicSynonymsByHomotypicGroup(taxon, SYNONYMY_INIT_STRATEGY));
310
//        synonymy.put("heterotypicSynonymyGroups", service.getHeterotypicSynonymyGroups(taxon, SYNONYMY_INIT_STRATEGY));
311

    
312
        mv.addObject(synonymy);
313
        return mv;
314
    }
315

    
316

    
317
    /**
318
     * @param synonymyGroups
319
     */
320
    private List<List<Synonym>> removeUnpublishedSynonyms(List<List<Synonym>> synonymyGroups) {
321
        List<List<Synonym>> result = new ArrayList<>();
322
        boolean isHomotypicToAccepted = true;
323

    
324
        for (List<Synonym> oldList : synonymyGroups){
325
            List<Synonym> newList = new ArrayList<>();
326
            for (Synonym oldSyn : oldList){
327
                if (oldSyn.isPublish()){
328
                    newList.add(oldSyn);
329
                }
330
            }
331
            if (isHomotypicToAccepted || !newList.isEmpty()){
332
                result.add(newList);
333
            }
334
            isHomotypicToAccepted = false;
335
        }
336
        return result;
337
    }
338

    
339
    /**
340
     * {@inheritDoc}
341
     */
342
    @Override
343
    protected List<String> getTaxonDescriptionInitStrategy() {
344
        return TAXONDESCRIPTION_INIT_STRATEGY.getPropertyPaths();
345
    }
346

    
347
    @Override
348
    protected List<String> getTaxonDescriptionElementInitStrategy() {
349
        return DESCRIPTION_ELEMENT_INIT_STRATEGY.getPropertyPaths();
350
    }
351

    
352
    @Override
353
    protected  EntityInitStrategy getTaxonNodeInitStrategy() {
354
        return TAXONNODE_INIT_STRATEGY;
355
    }
356

    
357
    /**
358
     * Get the list of {@link TaxonRelationship}s for the given
359
     * {@link TaxonBase} instance identified by the <code>{taxon-uuid}</code>.
360
     * <p>
361
     * URI: <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}&#x002F;taxonRelationships</b>
362
     *
363
     * @param request
364
     * @param response
365
     * @return a List of {@link TaxonRelationship} entities which are initialized
366
     *         using the following initialization strategy:
367
     *         {@link #TAXONRELATIONSHIP_INIT_STRATEGY}
368
     * @throws IOException
369
     */
370
    @RequestMapping(
371
            value = {"taxonRelationships"},
372
            method = RequestMethod.GET)
373
    public List<TaxonRelationship> doGetTaxonRelations(@PathVariable("uuid") UUID uuid,
374
            HttpServletRequest request, HttpServletResponse response)throws IOException {
375

    
376
        boolean includeUnpublished = NO_UNPUBLISHED;
377
        logger.info("doGetTaxonRelations()" + requestPathAndQuery(request));
378
        Taxon taxon = getCdmBaseInstance(Taxon.class, uuid, response, (List<String>)null);
379
        taxon = checkExistsAndAccess(taxon, includeUnpublished, response);
380

    
381
        List<TaxonRelationship> toRelationships = service.listToTaxonRelationships(taxon, null,
382
                includeUnpublished, null, null, null, TAXONRELATIONSHIP_INIT_STRATEGY.getPropertyPaths());
383
        List<TaxonRelationship> fromRelationships = service.listFromTaxonRelationships(taxon, null,
384
                includeUnpublished, null, null, null, TAXONRELATIONSHIP_INIT_STRATEGY.getPropertyPaths());
385

    
386
        List<TaxonRelationship> allRelationships = new ArrayList<>(toRelationships.size() + fromRelationships.size());
387
        allRelationships.addAll(toRelationships);
388
        allRelationships.addAll(fromRelationships);
389

    
390
        return allRelationships;
391
    }
392

    
393
    /**
394
     * Get the list of {@link NameRelationship}s of the Name associated with the
395
     * {@link TaxonBase} instance identified by the <code>{taxon-uuid}</code>.
396
     * <p>
397
     * URI: <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}&#x002F;nameRelationships</b>
398
     *
399
     * @param request
400
     * @param response
401
     * @return a List of {@link NameRelationship} entities which are initialized
402
     *         using the following initialization strategy:
403
     *         {@link #NAMERELATIONSHIP_INIT_STRATEGY}
404
     * @throws IOException
405
     */
406
    @RequestMapping(
407
            value = {"toNameRelationships"},
408
            method = RequestMethod.GET)
409
    public List<NameRelationship> doGetToNameRelations(@PathVariable("uuid") UUID uuid,
410
            HttpServletRequest request, HttpServletResponse response)throws IOException {
411
        logger.info("doGetNameRelations()" + request.getRequestURI());
412
        boolean includeUnpublished = NO_UNPUBLISHED;
413

    
414
        TaxonBase<?> taxonBase = getCdmBaseInstance(TaxonBase.class, uuid, response, (List<String>)null);
415
        taxonBase = checkExistsAndAccess(taxonBase, includeUnpublished, response);
416

    
417
        List<NameRelationship> list = nameService.listNameRelationships(taxonBase.getName(), Direction.relatedTo, null, null, 0, null, NAMERELATIONSHIP_INIT_STRATEGY.getPropertyPaths());
418
        return list;
419
    }
420

    
421
    /**
422
     * Get the list of {@link NameRelationship}s of the Name associated with the
423
     * {@link TaxonBase} instance identified by the <code>{taxon-uuid}</code>.
424
     * <p>
425
     * URI: <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}&#x002F;nameRelationships</b>
426
     *
427
     * @param request
428
     * @param response
429
     * @return a List of {@link NameRelationship} entities which are initialized
430
     *         using the following initialization strategy:
431
     *         {@link #NAMERELATIONSHIP_INIT_STRATEGY}
432
     * @throws IOException
433
     */
434
    @RequestMapping(
435
            value = {"fromNameRelationships"},
436
            method = RequestMethod.GET)
437
    public List<NameRelationship> doGetFromNameRelations(@PathVariable("uuid") UUID uuid,
438
            HttpServletRequest request, HttpServletResponse response)throws IOException {
439
        logger.info("doGetNameFromNameRelations()" + requestPathAndQuery(request));
440

    
441
        boolean includeUnpublished = NO_UNPUBLISHED;
442

    
443
        TaxonBase<?> taxonBase = getCdmBaseInstance(TaxonBase.class, uuid, response, SIMPLE_TAXON_INIT_STRATEGY.getPropertyPaths());
444
        taxonBase = checkExistsAndAccess(taxonBase, includeUnpublished, response);
445

    
446
        List<NameRelationship> list = nameService.listNameRelationships(taxonBase.getName(), Direction.relatedFrom, null, null, 0, null, NAMERELATIONSHIP_INIT_STRATEGY.getPropertyPaths());
447

    
448
        return list;
449
    }
450

    
451

    
452
//	@RequestMapping(value = "specimens", method = RequestMethod.GET)
453
//	public ModelAndView doGetSpecimens(
454
//			@PathVariable("uuid") UUID uuid,
455
//			HttpServletRequest request,
456
//			HttpServletResponse response) throws IOException, ClassNotFoundException {
457
//		logger.info("doGetSpecimens() - " + request.getRequestURI());
458
//
459
//		ModelAndView mv = new ModelAndView();
460
//
461
//		List<DerivedUnitFacade> derivedUnitFacadeList = new ArrayList<>();
462
//
463
//		// find speciemens in the TaxonDescriptions
464
//		List<TaxonDescription> taxonDescriptions = doGetDescriptions(uuid, request, response);
465
//		if (taxonDescriptions != null) {
466
//
467
//			for (TaxonDescription description : taxonDescriptions) {
468
//				derivedUnitFacadeList.addAll( occurrenceService.listDerivedUnitFacades(description, null) );
469
//			}
470
//		}
471
//		// TODO find specimens in the NameDescriptions ??
472
//
473
//		// TODO also find type specimens
474
//
475
//		mv.addObject(derivedUnitFacadeList);
476
//
477
//		return mv;
478
//	}
479

    
480
    /**
481
     * Get the {@link Media} attached to the {@link Taxon} instance
482
     * identified by the <code>{taxon-uuid}</code>.
483
     *
484
     * Usage &#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-
485
     * uuid}&#x002F;media&#x002F;{mime type
486
     * list}&#x002F;{size}[,[widthOrDuration}][,{height}]&#x002F;
487
     *
488
     * Whereas
489
     * <ul>
490
     * <li><b>{mime type list}</b>: a comma separated list of mime types, in the
491
     * order of preference. The forward slashes contained in the mime types must
492
     * be replaced by a colon. Regular expressions can be used. Each media
493
     * associated with this given taxon is being searched whereas the first
494
     * matching mime type matching a representation always rules.</li>
495
     * <li><b>{size},{widthOrDuration},{height}</b>: <i>not jet implemented</i>
496
     * valid values are an integer or the asterisk '*' as a wildcard</li>
497
     * </ul>
498
     *
499
     * @param request
500
     * @param response
501
     * @return a List of {@link Media} entities which are initialized
502
     *         using the following initialization strategy:
503
     *         {@link #TAXONDESCRIPTION_INIT_STRATEGY}
504
     * @throws IOException
505
     */
506
    @RequestMapping(
507
        value = {"media"},
508
        method = RequestMethod.GET)
509
    public List<Media> doGetMedia(
510
            @PathVariable("uuid") UUID uuid,
511
            @RequestParam(value = "type", required = false) Class<? extends MediaRepresentationPart> type,
512
            @RequestParam(value = "mimeTypes", required = false) String[] mimeTypes,
513
            @RequestParam(value = "relationships", required = false) UuidList relationshipUuids,
514
            @RequestParam(value = "relationshipsInvers", required = false) UuidList relationshipInversUuids,
515
            @RequestParam(value = "includeTaxonDescriptions", required = true) Boolean  includeTaxonDescriptions,
516
            @RequestParam(value = "includeOccurrences", required = true) Boolean  includeOccurrences,
517
            @RequestParam(value = "includeTaxonNameDescriptions", required = true) Boolean  includeTaxonNameDescriptions,
518
            @RequestParam(value = "widthOrDuration", required = false) Integer  widthOrDuration,
519
            @RequestParam(value = "height", required = false) Integer height,
520
            @RequestParam(value = "size", required = false) Integer size,
521
            HttpServletRequest request, HttpServletResponse response) throws IOException {
522

    
523
        logger.info("doGetMedia() " + requestPathAndQuery(request));
524

    
525
        List<String> initStrategy = null;
526

    
527
        EntityMediaContext<Taxon> taxonMediaContext = loadMediaForTaxonAndRelated(uuid, relationshipUuids,
528
                relationshipInversUuids, includeTaxonDescriptions, includeOccurrences, includeTaxonNameDescriptions,
529
                response, initStrategy, MediaPortalController.MEDIA_INIT_STRATEGY.getPropertyPaths());
530

    
531
        List<Media> mediafilteredForPreferredRepresentations = mediaToolbox.processAndFilterPreferredMediaRepresentations(type, mimeTypes, widthOrDuration, height, size,
532
                taxonMediaContext.media);
533

    
534
        return mediafilteredForPreferredRepresentations;
535
    }
536

    
537
    /**
538
     * @param uuid
539
     * @param type
540
     * @param mimeTypes
541
     * @param relationshipUuids
542
     * @param relationshipInversUuids
543
     * @param includeTaxonDescriptions
544
     * @param includeOccurrences
545
     * @param includeTaxonNameDescriptions
546
     * @param widthOrDuration
547
     * @param height
548
     * @param size
549
     * @param response
550
     * @param initStrategy
551
     * @return
552
     * @throws IOException
553
     * @Deprecated To be replaced by other loadMediaForTaxonAndRelated method
554
     */
555
    @Deprecated
556
    public  EntityMediaContext<Taxon> loadMediaForTaxonAndRelated(UUID uuid,
557
            UuidList relationshipUuids, UuidList relationshipInversUuids,
558
            Boolean includeTaxonDescriptions, Boolean includeOccurrences, Boolean includeTaxonNameDescriptions,
559
            HttpServletResponse response,
560
            List<String> taxonInitStrategy) throws IOException {
561
        return loadMediaForTaxonAndRelated(uuid, relationshipUuids, relationshipInversUuids,
562
                includeTaxonDescriptions, includeOccurrences, includeTaxonNameDescriptions, response, taxonInitStrategy, null);
563
    }
564

    
565
    /**
566
     * @param uuid
567
     * @param type
568
     * @param mimeTypes
569
     * @param relationshipUuids
570
     * @param relationshipInversUuids
571
     * @param includeTaxonDescriptions
572
     * @param includeOccurrences
573
     * @param includeTaxonNameDescriptions
574
     * @param widthOrDuration
575
     * @param height
576
     * @param size
577
     * @param response
578
     * @param initStrategy
579
     * @return
580
     * @throws IOException
581
     */
582
    public  EntityMediaContext<Taxon> loadMediaForTaxonAndRelated(UUID uuid,
583
            UuidList relationshipUuids, UuidList relationshipInversUuids,
584
            Boolean includeTaxonDescriptions, Boolean includeOccurrences, Boolean includeTaxonNameDescriptions,
585
            HttpServletResponse response,
586
            List<String> taxonInitStrategy, List<String> mediaInitStrategy) throws IOException {
587

    
588
        boolean includeUnpublished = NO_UNPUBLISHED;
589

    
590

    
591
        Taxon taxon = getCdmBaseInstance(Taxon.class, uuid, response, taxonInitStrategy);
592
        taxon = checkExistsAndAccess(taxon, includeUnpublished, response);
593

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

    
596
        List<Media> media = listMediaForTaxon(taxon, includeRelationships,
597
                includeTaxonDescriptions, includeOccurrences, includeTaxonNameDescriptions, mediaInitStrategy);
598

    
599
        EntityMediaContext<Taxon> entityMediaContext = new EntityMediaContext<Taxon>(taxon, media);
600

    
601
        return entityMediaContext;
602
    }
603

    
604
    @RequestMapping(
605
            value = {"subtree/media"},
606
            method = RequestMethod.GET)
607
    public List<Media> doGetSubtreeMedia(
608
            @PathVariable("uuid") UUID uuid,
609
            @RequestParam(value = "type", required = false) Class<? extends MediaRepresentationPart> type,
610
            @RequestParam(value = "mimeTypes", required = false) String[] mimeTypes,
611
            @RequestParam(value = "relationships", required = false) UuidList relationshipUuids,
612
            @RequestParam(value = "relationshipsInvers", required = false) UuidList relationshipInversUuids,
613
            @RequestParam(value = "includeTaxonDescriptions", required = true) Boolean  includeTaxonDescriptions,
614
            @RequestParam(value = "includeOccurrences", required = true) Boolean  includeOccurrences,
615
            @RequestParam(value = "includeTaxonNameDescriptions", required = true) Boolean  includeTaxonNameDescriptions,
616
            @RequestParam(value = "widthOrDuration", required = false) Integer  widthOrDuration,
617
            @RequestParam(value = "height", required = false) Integer height,
618
            @RequestParam(value = "size", required = false) Integer size,
619
            HttpServletRequest request, HttpServletResponse response)throws IOException {
620

    
621

    
622
        boolean includeUnpublished = NO_UNPUBLISHED;
623

    
624
        logger.info("doGetSubtreeMedia() " + requestPathAndQuery(request));
625

    
626
        List<String> initStrategy = TAXON_WITH_CHILDNODES_INIT_STRATEGY.getPropertyPaths();
627

    
628
        Taxon taxon = getCdmBaseInstance(Taxon.class, uuid, response, initStrategy);
629
        taxon = checkExistsAndAccess(taxon, includeUnpublished, response);
630

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

    
633
        List<Media> media = listMediaForTaxon(taxon, includeRelationships,
634
                includeTaxonDescriptions, includeOccurrences, includeTaxonNameDescriptions, null);
635
        media = addTaxonomicChildrenMedia(includeTaxonDescriptions, includeOccurrences, includeTaxonNameDescriptions, taxon,
636
                includeRelationships, media);
637

    
638
        List<Media> mediafilteredForPreferredRepresentations = mediaToolbox.processAndFilterPreferredMediaRepresentations(type, mimeTypes, widthOrDuration, height, size,
639
                media);
640

    
641
        return mediafilteredForPreferredRepresentations;
642
    }
643

    
644
    /**
645
     * @param includeTaxonDescriptions
646
     * @param includeOccurrences
647
     * @param includeTaxonNameDescriptions
648
     * @param taxon
649
     * @param includeRelationships
650
     * @param media
651
     */
652
    public List<Media> addTaxonomicChildrenMedia(Boolean includeTaxonDescriptions, Boolean includeOccurrences,
653
            Boolean includeTaxonNameDescriptions, Taxon taxon, Set<TaxonRelationshipEdge> includeRelationships,
654
            List<Media> media) {
655

    
656
        //TODO use treeindex
657
        //looking for all medias of direct children
658
        TaxonNode node;
659
        if (taxon.getTaxonNodes().size()>0){
660
            Set<TaxonNode> nodes = taxon.getTaxonNodes();
661
            Iterator<TaxonNode> iterator = nodes.iterator();
662
            //TaxonNode holen
663
            node = iterator.next();
664
            //Check if TaxonNode belongs to the current tree
665

    
666
            node = taxonNodeService.load(node.getUuid(), TAXONNODE_WITH_CHILDNODES_INIT_STRATEGY.getPropertyPaths());
667
            List<TaxonNode> children = node.getChildNodes();
668
            Taxon childTaxon;
669
            for (TaxonNode child : children){
670
                childTaxon = child.getTaxon();
671
                if(childTaxon != null) {
672
                    childTaxon = (Taxon)taxonService.load(childTaxon.getUuid(), NO_UNPUBLISHED, null);
673
                    media.addAll(listMediaForTaxon(childTaxon, includeRelationships,
674
                            includeTaxonDescriptions, includeOccurrences, includeTaxonNameDescriptions, MediaPortalController.MEDIA_INIT_STRATEGY.getPropertyPaths()));
675
                }
676
            }
677
        }
678
        return media;
679
    }
680

    
681
    /**
682
     *
683
     * @param taxon
684
     * @param includeRelationships
685
     * @param type
686
     * @param mimeTypes
687
     * @param widthOrDuration
688
     * @param height
689
     * @param size
690
     * @return
691
     */
692
    private List<Media> listMediaForTaxon(Taxon taxon, Set<TaxonRelationshipEdge> includeRelationships,
693
            Boolean includeTaxonDescriptions, Boolean includeOccurrences, Boolean includeTaxonNameDescriptions, List<String> propertyPath) {
694

    
695
        List<Media> media = service.listMedia(taxon, includeRelationships,
696
                false, includeTaxonDescriptions, includeOccurrences, includeTaxonNameDescriptions, propertyPath);
697

    
698
        return media;
699
    }
700

    
701

    
702
    public class EntityMediaContext<T extends IdentifiableEntity> {
703

    
704
        T entity;
705
        List<Media> media;
706
        /**
707
         * @param entity
708
         * @param media
709
         */
710
        public EntityMediaContext(T entity, List<Media> media) {
711

    
712
            this.entity = HibernateProxyHelper.deproxy(entity);
713
            this.media = media;
714
        }
715
        public T getEntity() {
716
            return entity;
717
        }
718
        public List<Media> getMedia() {
719
            return media;
720
        }
721
        /**
722
         * @param addTaxonomicChildrenMedia
723
         */
724
        public void setMedia(List<Media> media) {
725
            this.media = media;
726

    
727
        }
728

    
729

    
730

    
731
    }
732

    
733
// ---------------------- code snippet preserved for possible later use --------------------
734
//	@RequestMapping(
735
//			value = {"//*/portal/taxon/*/descriptions"}, // mapped as absolute path, see CdmAntPathMatcher
736
//			method = RequestMethod.GET)
737
//	public List<TaxonDescription> doGetDescriptionsbyFeatureTree(HttpServletRequest request, HttpServletResponse response)throws IOException {
738
//		TaxonBase tb = getCdmBase(request, response, null, Taxon.class);
739
//		if(tb instanceof Taxon){
740
//			//T O D O this is a quick and dirty implementation -> generalize
741
//			UUID featureTreeUuid = readValueUuid(request, termTreeUuidPattern);
742
//
743
//			FeatureTree featureTree = descriptionService.getFeatureTreeByUuid(featureTreeUuid);
744
//			Pager<TaxonDescription> p = descriptionService.getTaxonDescriptions((Taxon)tb, null, null, null, null, TAXONDESCRIPTION_INIT_STRATEGY);
745
//			List<TaxonDescription> descriptions = p.getRecords();
746
//
747
//			if(!featureTree.isDescriptionSeparated()){
748
//
749
//				TaxonDescription superDescription = TaxonDescription.NewInstance();
750
//				//put all descriptionElements in superDescription and make it invisible
751
//				for(TaxonDescription description: descriptions){
752
//					for(DescriptionElementBase element: description.getElements()){
753
//						superDescription.addElement(element);
754
//					}
755
//				}
756
//				List<TaxonDescription> separatedDescriptions = new ArrayList<TaxonDescription>(descriptions.size());
757
//				separatedDescriptions.add(superDescription);
758
//				return separatedDescriptions;
759
//			}else{
760
//				return descriptions;
761
//			}
762
//		} else {
763
//			response.sendError(HttpServletResponse.SC_NOT_FOUND, "invalid type; Taxon expected but " + tb.getClass().getSimpleName() + " found.");
764
//			return null;
765
//		}
766
//	}
767

    
768
}
(61-61/75)