Project

General

Profile

Download (32.2 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.util.TaxonRelationshipEdge;
41
import eu.etaxonomy.cdm.database.UpdatableRoutingDataSource;
42
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
43
import eu.etaxonomy.cdm.model.common.CdmBase;
44
import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
45
import eu.etaxonomy.cdm.model.common.RelationshipBase.Direction;
46
import eu.etaxonomy.cdm.model.location.NamedArea;
47
import eu.etaxonomy.cdm.model.media.Media;
48
import eu.etaxonomy.cdm.model.media.MediaRepresentationPart;
49
import eu.etaxonomy.cdm.model.name.NameRelationship;
50
import eu.etaxonomy.cdm.model.taxon.Synonym;
51
import eu.etaxonomy.cdm.model.taxon.Taxon;
52
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
53
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
54
import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;
55
import eu.etaxonomy.cdm.persistence.dao.initializer.EntityInitStrategy;
56
import eu.etaxonomy.cdm.persistence.query.MatchMode;
57
import eu.etaxonomy.cdm.remote.controller.util.ControllerUtils;
58
import eu.etaxonomy.cdm.remote.controller.util.IMediaToolbox;
59
import eu.etaxonomy.cdm.remote.editor.CdmTypePropertyEditor;
60
import eu.etaxonomy.cdm.remote.editor.DefinedTermBaseList;
61
import eu.etaxonomy.cdm.remote.editor.MatchModePropertyEditor;
62
import eu.etaxonomy.cdm.remote.editor.NamedAreaPropertyEditor;
63
import eu.etaxonomy.cdm.remote.editor.TermBaseListPropertyEditor;
64
import eu.etaxonomy.cdm.remote.editor.UUIDListPropertyEditor;
65
import eu.etaxonomy.cdm.remote.editor.UuidList;
66
import io.swagger.annotations.Api;
67

    
68
/**
69
 * The TaxonPortalController class is a Spring MVC Controller.
70
 * <p>
71
 * The syntax of the mapped service URIs contains the the {datasource-name} path element.
72
 * The available {datasource-name}s are defined in a configuration file which
73
 * is loaded by the {@link UpdatableRoutingDataSource}. If the
74
 * UpdatableRoutingDataSource is not being used in the actual application
75
 * context any arbitrary {datasource-name} may be used.
76
 * <p>
77
 * Methods mapped at type level, inherited from super classes ({@link BaseController}):
78
 * <blockquote>
79
 * URI: <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}</b>
80
 *
81
 * Get the {@link TaxonBase} instance identified by the <code>{taxon-uuid}</code>.
82
 * The returned Taxon is initialized by
83
 * the following strategy {@link #TAXON_INIT_STRATEGY}
84
 * </blockquote>
85
 *
86
 * @author a.kohlbecker
87
 * @since 20.07.2009
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
            "relationsFromThisTaxon.toTaxon.secSource.citation.authorship",
117
            "relationsFromThisTaxon.toTaxon.secSource.citation.inReference.authorship",
118
            "relationsToThisTaxon.fromTaxon.secSource.citation.authorship",
119
            "relationsToThisTaxon.fromTaxon.secSource.citation.inReference.authorship",
120
            // the name
121
            "name.$",
122
            "name.nomenclaturalSource.citation.authorship",
123
            "name.nomenclaturalSource.citation.inReference.authorship",
124
            "name.rank.representations",
125
            "name.status.type.representations",
126
            "name.status.source.citation",
127
            "sec.authorship"
128
//            "descriptions" // TODO remove
129

    
130
            }));
131

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

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

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

    
162
            "name.typeDesignations",
163

    
164
            "name.homotypicalGroup.$",
165
            "name.homotypicalGroup.typifiedNames.$",
166
            "name.homotypicalGroup.typifiedNames.nomenclaturalSource.citation.authorship",
167
            "name.homotypicalGroup.typifiedNames.nomenclaturalSource.citation.inReference.authorship",
168
//            "name.homotypicalGroup.typifiedNames.taxonBases.$"
169
    }));
170

    
171

    
172
    private static final EntityInitStrategy TAXONRELATIONSHIP_INIT_STRATEGY = new EntityInitStrategy(Arrays.asList(new String []{
173
            "$",
174
            "type.inverseRepresentations",
175
            "fromTaxon.sec",
176
            "fromTaxon.name",
177
            "toTaxon.sec",
178
            "toTaxon.name"
179
    }));
180

    
181
    public static final EntityInitStrategy NAMERELATIONSHIP_INIT_STRATEGY = new EntityInitStrategy(Arrays.asList(new String []{
182
            "$",
183
            "type.inverseRepresentations",
184
            "source.citation",
185
            "toName.$",
186
            "toName.nomenclaturalSource.citation.authorship",
187
            "toName.nomenclaturalSource.citation.inReference.authorship",
188
            "fromName.$",
189
            "fromName.nomenclaturalSource.citation.authorship",
190
            "fromName.nomenclaturalSource.citation.inReference.authorship",
191

    
192
    }));
193

    
194
    protected static final EntityInitStrategy TAXONDESCRIPTION_INIT_STRATEGY = DescriptionPortalController.DESCRIPTION_INIT_STRATEGY;
195

    
196
    protected static final EntityInitStrategy DESCRIPTION_ELEMENT_INIT_STRATEGY = new EntityInitStrategy(Arrays.asList(new String []{
197
            "$",
198
            "sources.citation.authorship",
199
            "sources.citation.inReference.authorship",
200
            "sources.nameUsedInSource",
201
            "multilanguageText",
202
            "media",
203
    }));
204

    
205

    
206
//	private static final List<String> NAMEDESCRIPTION_INIT_STRATEGY = Arrays.asList(new String []{
207
//			"uuid",
208
//			"feature",
209
//			"elements.$",
210
//			"elements.multilanguageText",
211
//			"elements.media",
212
//	});
213

    
214
    protected static final EntityInitStrategy TAXONDESCRIPTION_MEDIA_INIT_STRATEGY = new EntityInitStrategy(Arrays.asList(new String []{
215
            "elements.media"
216

    
217
    }));
218

    
219
    private static final EntityInitStrategy TYPEDESIGNATION_INIT_STRATEGY = new EntityInitStrategy(Arrays.asList(new String []{
220
            "typeSpecimen.$",
221
            "citation.authorship.$",
222
            "typeName",
223
            "typeStatus"
224
    }));
225

    
226
    protected static final EntityInitStrategy TAXONNODE_WITH_CHILDNODES_INIT_STRATEGY = new EntityInitStrategy(Arrays.asList(new String []{
227
            "childNodes.taxon",
228
    }));
229

    
230
    protected static final EntityInitStrategy TAXONNODE_INIT_STRATEGY = new EntityInitStrategy(Arrays.asList(new String []{
231
            "taxonNodes.classification",
232
            "taxonNodes.parent",
233
            "taxonNodes.statusNote.*",
234
            "taxonNodes.taxon.name",
235
            "taxonNodes.taxon.secSource.citation",
236
            "taxonNodes.source.citation.authorship",
237
            "taxonNodes.source.citation.inReference.authorship",
238
            "acceptedTaxon.taxonNodes.classification",
239
    }));
240

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

    
243
    @Override
244
    protected <CDM_BASE extends CdmBase> List<String> complementInitStrategy(Class<CDM_BASE> clazz,
245
            List<String> pathProperties) {
246

    
247
        if(pathProperties != null) {
248
            List<String> complemented = new ArrayList<>(pathProperties);
249
            if(pathProperties.contains("name")) {
250
                // pathProperties for web service request for portal/taxon/{uuid}/name
251
                complemented.add("name.nomenclaturalSource.citation.authorship");
252
                complemented.add("name.nomenclaturalSource.citation.inReference.authorship");
253
                return complemented;
254
            }
255
        }
256
        return pathProperties;
257
    }
258

    
259
    public TaxonPortalController(){
260
        super();
261
        setInitializationStrategy(TAXON_INIT_STRATEGY.getPropertyPaths());
262
    }
263

    
264
    @Autowired
265
    @Override
266
    public void setService(ITaxonService service) {
267
        this.service = service;
268
    }
269

    
270
    @InitBinder
271
    @Override
272
    public void initBinder(WebDataBinder binder) {
273
        super.initBinder(binder);
274
        binder.registerCustomEditor(NamedArea.class, new NamedAreaPropertyEditor());
275
        binder.registerCustomEditor(MatchMode.class, new MatchModePropertyEditor());
276
        binder.registerCustomEditor(Class.class, new CdmTypePropertyEditor());
277
        binder.registerCustomEditor(UuidList.class, new UUIDListPropertyEditor());
278
        binder.registerCustomEditor(DefinedTermBaseList.class, new TermBaseListPropertyEditor<>(termService));
279
    }
280

    
281
    /**
282
     * Get the synonymy for a taxon identified by the <code>{taxon-uuid}</code>.
283
     * The synonymy consists
284
     * of two parts: The group of homotypic synonyms of the taxon and the
285
     * heterotypic synonymy groups of the taxon. The synonymy is ordered
286
     * historically by the type designations and by the publication date of the
287
     * nomenclatural reference
288
     * <p>
289
     * URI:
290
     * <b>&#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-uuid}&#x002F;synonymy</b>
291
     *
292
     *
293
     * @param request
294
     * @param response
295
     * @return a Map with two entries which are mapped by the following keys:
296
     *         "homotypicSynonymsByHomotypicGroup", "heterotypicSynonymyGroups",
297
     *         containing lists of {@link Synonym}s which // TODO Auto-generated catch block
298
                    e.printStackTrace();are initialized using the
299
     *         following initialization strategy: {@link #SYNONYMY_INIT_STRATEGY}
300
     *
301
     * @throws IOException
302
     */
303
    @RequestMapping(
304
            value = {"synonymy"},
305
            method = RequestMethod.GET)
306
    public ModelAndView doGetSynonymy(@PathVariable("uuid") UUID taxonUuid,
307
            @RequestParam(value = "subtree", required = false) UUID subtreeUuid,
308
            HttpServletRequest request,
309
            HttpServletResponse response)throws IOException {
310

    
311
        boolean includeUnpublished = NO_UNPUBLISHED;
312
        if(request != null){
313
            logger.info("doGetSynonymy() " + requestPathAndQuery(request));
314
        }
315
        ModelAndView mv = new ModelAndView();
316

    
317
        Taxon taxon = getCdmBaseInstance(Taxon.class, taxonUuid, response, getTaxonNodeInitStrategy().getPropertyPaths());
318
        TaxonNode subtree = getSubtreeOrError(subtreeUuid, taxonNodeService, response);
319
        taxon = checkExistsSubtreeAndAccess(taxon, subtree, NO_UNPUBLISHED, response);
320

    
321
        Map<String, List<?>> synonymy = new Hashtable<>();
322

    
323
        //new
324
        List<List<Synonym>> synonymyGroups = service.getSynonymsByHomotypicGroup(taxon, SYNONYMY_INIT_STRATEGY.getPropertyPaths());
325
        if(!includeUnpublished){
326
            synonymyGroups = removeUnpublishedSynonyms(synonymyGroups);
327
        }
328

    
329
        synonymy.put("homotypicSynonymsByHomotypicGroup", synonymyGroups.get(0));
330
        synonymyGroups.remove(0);
331
        synonymy.put("heterotypicSynonymyGroups", synonymyGroups);
332

    
333
        //old
334
//        synonymy.put("homotypicSynonymsByHomotypicGroup", service.getHomotypicSynonymsByHomotypicGroup(taxon, SYNONYMY_INIT_STRATEGY));
335
//        synonymy.put("heterotypicSynonymyGroups", service.getHeterotypicSynonymyGroups(taxon, SYNONYMY_INIT_STRATEGY));
336

    
337
        mv.addObject(synonymy);
338
        return mv;
339
    }
340

    
341

    
342
    /**
343
     * @param synonymyGroups
344
     */
345
    private List<List<Synonym>> removeUnpublishedSynonyms(List<List<Synonym>> synonymyGroups) {
346
        List<List<Synonym>> result = new ArrayList<>();
347
        boolean isHomotypicToAccepted = true;
348

    
349
        for (List<Synonym> oldList : synonymyGroups){
350
            List<Synonym> newList = new ArrayList<>();
351
            for (Synonym oldSyn : oldList){
352
                if (oldSyn.isPublish()){
353
                    newList.add(oldSyn);
354
                }
355
            }
356
            if (isHomotypicToAccepted || !newList.isEmpty()){
357
                result.add(newList);
358
            }
359
            isHomotypicToAccepted = false;
360
        }
361
        return result;
362
    }
363

    
364
    /**
365
     * {@inheritDoc}
366
     */
367
    @Override
368
    protected List<String> getTaxonDescriptionInitStrategy() {
369
        return TAXONDESCRIPTION_INIT_STRATEGY.getPropertyPaths();
370
    }
371

    
372
    @Override
373
    protected List<String> getTaxonDescriptionElementInitStrategy() {
374
        return DESCRIPTION_ELEMENT_INIT_STRATEGY.getPropertyPaths();
375
    }
376

    
377
    @Override
378
    protected  EntityInitStrategy getTaxonNodeInitStrategy() {
379
        return TAXONNODE_INIT_STRATEGY;
380
    }
381

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

    
401
        boolean includeUnpublished = NO_UNPUBLISHED;
402
        logger.info("doGetTaxonRelations()" + requestPathAndQuery(request));
403
        Taxon taxon = getCdmBaseInstance(Taxon.class, uuid, response, (List<String>)null);
404
        taxon = checkExistsAndAccess(taxon, includeUnpublished, response);
405

    
406
        List<TaxonRelationship> toRelationships = service.listToTaxonRelationships(taxon, null,
407
                includeUnpublished, null, null, null, TAXONRELATIONSHIP_INIT_STRATEGY.getPropertyPaths());
408
        List<TaxonRelationship> fromRelationships = service.listFromTaxonRelationships(taxon, null,
409
                includeUnpublished, null, null, null, TAXONRELATIONSHIP_INIT_STRATEGY.getPropertyPaths());
410

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

    
415
        return allRelationships;
416
    }
417

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

    
439
        TaxonBase<?> taxonBase = getCdmBaseInstance(TaxonBase.class, uuid, response, (List<String>)null);
440
        taxonBase = checkExistsAndAccess(taxonBase, includeUnpublished, response);
441

    
442
        List<NameRelationship> list = nameService.listNameRelationships(taxonBase.getName(), Direction.relatedTo, null, null, 0, null, NAMERELATIONSHIP_INIT_STRATEGY.getPropertyPaths());
443
        return list;
444
    }
445

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

    
466
        boolean includeUnpublished = NO_UNPUBLISHED;
467

    
468
        TaxonBase<?> taxonBase = getCdmBaseInstance(TaxonBase.class, uuid, response, SIMPLE_TAXON_INIT_STRATEGY.getPropertyPaths());
469
        taxonBase = checkExistsAndAccess(taxonBase, includeUnpublished, response);
470

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

    
473
        return list;
474
    }
475

    
476

    
477
//	@RequestMapping(value = "specimens", method = RequestMethod.GET)
478
//	public ModelAndView doGetSpecimens(
479
//			@PathVariable("uuid") UUID uuid,
480
//			HttpServletRequest request,
481
//			HttpServletResponse response) throws IOException, ClassNotFoundException {
482
//		logger.info("doGetSpecimens() - " + request.getRequestURI());
483
//
484
//		ModelAndView mv = new ModelAndView();
485
//
486
//		List<DerivedUnitFacade> derivedUnitFacadeList = new ArrayList<>();
487
//
488
//		// find speciemens in the TaxonDescriptions
489
//		List<TaxonDescription> taxonDescriptions = doGetDescriptions(uuid, request, response);
490
//		if (taxonDescriptions != null) {
491
//
492
//			for (TaxonDescription description : taxonDescriptions) {
493
//				derivedUnitFacadeList.addAll( occurrenceService.listDerivedUnitFacades(description, null) );
494
//			}
495
//		}
496
//		// TODO find specimens in the NameDescriptions ??
497
//
498
//		// TODO also find type specimens
499
//
500
//		mv.addObject(derivedUnitFacadeList);
501
//
502
//		return mv;
503
//	}
504

    
505
    /**
506
     * Get the {@link Media} attached to the {@link Taxon} instance
507
     * identified by the <code>{taxon-uuid}</code>.
508
     *
509
     * Usage &#x002F;{datasource-name}&#x002F;portal&#x002F;taxon&#x002F;{taxon-
510
     * uuid}&#x002F;media&#x002F;{mime type
511
     * list}&#x002F;{size}[,[widthOrDuration}][,{height}]&#x002F;
512
     *
513
     * Whereas
514
     * <ul>
515
     * <li><b>{mime type list}</b>: a comma separated list of mime types, in the
516
     * order of preference. The forward slashes contained in the mime types must
517
     * be replaced by a colon. Regular expressions can be used. Each media
518
     * associated with this given taxon is being searched whereas the first
519
     * matching mime type matching a representation always rules.</li>
520
     * <li><b>{size},{widthOrDuration},{height}</b>: <i>not jet implemented</i>
521
     * valid values are an integer or the asterisk '*' as a wildcard</li>
522
     * </ul>
523
     *
524
     * @param request
525
     * @param response
526
     * @return a List of {@link Media} entities which are initialized
527
     *         using the following initialization strategy:
528
     *         {@link #TAXONDESCRIPTION_INIT_STRATEGY}
529
     * @throws IOException
530
     */
531
    @RequestMapping(
532
        value = {"media"},
533
        method = RequestMethod.GET)
534
    public List<Media> doGetMedia(
535
            @PathVariable("uuid") UUID uuid,
536
            @RequestParam(value = "type", required = false) Class<? extends MediaRepresentationPart> type,
537
            @RequestParam(value = "mimeTypes", required = false) String[] mimeTypes,
538
            @RequestParam(value = "relationships", required = false) UuidList relationshipUuids,
539
            @RequestParam(value = "relationshipsInvers", required = false) UuidList relationshipInversUuids,
540
            @RequestParam(value = "includeTaxonDescriptions", required = true) Boolean  includeTaxonDescriptions,
541
            @RequestParam(value = "includeOccurrences", required = true) Boolean  includeOccurrences,
542
            @RequestParam(value = "includeTaxonNameDescriptions", required = true) Boolean  includeTaxonNameDescriptions,
543
            @RequestParam(value = "widthOrDuration", required = false) Integer  widthOrDuration,
544
            @RequestParam(value = "height", required = false) Integer height,
545
            @RequestParam(value = "size", required = false) Integer size,
546
            HttpServletRequest request, HttpServletResponse response) throws IOException {
547

    
548
        logger.info("doGetMedia() " + requestPathAndQuery(request));
549

    
550
        List<String> initStrategy = null;
551

    
552
        EntityMediaContext<Taxon> taxonMediaContext = loadMediaForTaxonAndRelated(uuid, relationshipUuids,
553
                relationshipInversUuids, includeTaxonDescriptions, includeOccurrences, includeTaxonNameDescriptions,
554
                response, initStrategy, MediaPortalController.MEDIA_INIT_STRATEGY.getPropertyPaths());
555

    
556
        List<Media> mediafilteredForPreferredRepresentations = mediaToolbox.processAndFilterPreferredMediaRepresentations(type, mimeTypes, widthOrDuration, height, size,
557
                taxonMediaContext.media);
558

    
559
        return mediafilteredForPreferredRepresentations;
560
    }
561

    
562
    /**
563
     * @Deprecated To be replaced by other loadMediaForTaxonAndRelated method
564
     */
565
    @Deprecated
566
    public  EntityMediaContext<Taxon> loadMediaForTaxonAndRelated(UUID uuid,
567
            UuidList relationshipUuids, UuidList relationshipInversUuids,
568
            Boolean includeTaxonDescriptions, Boolean includeOccurrences, Boolean includeTaxonNameDescriptions,
569
            HttpServletResponse response,
570
            List<String> taxonInitStrategy) throws IOException {
571
        return loadMediaForTaxonAndRelated(uuid, relationshipUuids, relationshipInversUuids,
572
                includeTaxonDescriptions, includeOccurrences, includeTaxonNameDescriptions, response, taxonInitStrategy, null);
573
    }
574

    
575
    public  EntityMediaContext<Taxon> loadMediaForTaxonAndRelated(UUID uuid,
576
            UuidList relationshipUuids, UuidList relationshipInversUuids,
577
            Boolean includeTaxonDescriptions, Boolean includeOccurrences, Boolean includeTaxonNameDescriptions,
578
            HttpServletResponse response,
579
            List<String> taxonInitStrategy, List<String> mediaInitStrategy) throws IOException {
580

    
581
        boolean includeUnpublished = NO_UNPUBLISHED;
582

    
583
        Taxon taxon = getCdmBaseInstance(Taxon.class, uuid, response, taxonInitStrategy);
584
        taxon = checkExistsAndAccess(taxon, includeUnpublished, response);
585

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

    
588
        List<Media> media = listMediaForTaxon(taxon, includeRelationships,
589
                includeTaxonDescriptions, includeOccurrences, includeTaxonNameDescriptions, mediaInitStrategy);
590

    
591
        EntityMediaContext<Taxon> entityMediaContext = new EntityMediaContext<>(taxon, media);
592

    
593
        return entityMediaContext;
594
    }
595

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

    
613

    
614
        boolean includeUnpublished = NO_UNPUBLISHED;
615

    
616
        logger.info("doGetSubtreeMedia() " + requestPathAndQuery(request));
617

    
618
        List<String> initStrategy = TAXON_WITH_CHILDNODES_INIT_STRATEGY.getPropertyPaths();
619

    
620
        Taxon taxon = getCdmBaseInstance(Taxon.class, uuid, response, initStrategy);
621
        taxon = checkExistsAndAccess(taxon, includeUnpublished, response);
622

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

    
625
        List<Media> media = listMediaForTaxon(taxon, includeRelationships,
626
                includeTaxonDescriptions, includeOccurrences, includeTaxonNameDescriptions, null);
627
        media = addTaxonomicChildrenMedia(includeTaxonDescriptions, includeOccurrences, includeTaxonNameDescriptions, taxon,
628
                includeRelationships, media);
629

    
630
        List<Media> mediafilteredForPreferredRepresentations = mediaToolbox.processAndFilterPreferredMediaRepresentations(type, mimeTypes, widthOrDuration, height, size,
631
                media);
632

    
633
        return mediafilteredForPreferredRepresentations;
634
    }
635

    
636
    /**
637
     * @param includeTaxonDescriptions
638
     * @param includeOccurrences
639
     * @param includeTaxonNameDescriptions
640
     * @param taxon
641
     * @param includeRelationships
642
     * @param media
643
     */
644
    public List<Media> addTaxonomicChildrenMedia(Boolean includeTaxonDescriptions, Boolean includeOccurrences,
645
            Boolean includeTaxonNameDescriptions, Taxon taxon, Set<TaxonRelationshipEdge> includeRelationships,
646
            List<Media> media) {
647

    
648
        //TODO use treeindex
649
        //looking for all medias of direct children
650
        TaxonNode node;
651
        if (taxon.getTaxonNodes().size()>0){
652
            Set<TaxonNode> nodes = taxon.getTaxonNodes();
653
            Iterator<TaxonNode> iterator = nodes.iterator();
654
            //TaxonNode holen
655
            node = iterator.next();
656
            //Check if TaxonNode belongs to the current tree
657

    
658
            node = taxonNodeService.load(node.getUuid(), TAXONNODE_WITH_CHILDNODES_INIT_STRATEGY.getPropertyPaths());
659
            List<TaxonNode> children = node.getChildNodes();
660
            Taxon childTaxon;
661
            for (TaxonNode child : children){
662
                childTaxon = child.getTaxon();
663
                if(childTaxon != null) {
664
                    childTaxon = (Taxon)taxonService.load(childTaxon.getUuid(), NO_UNPUBLISHED, null);
665
                    media.addAll(listMediaForTaxon(childTaxon, includeRelationships,
666
                            includeTaxonDescriptions, includeOccurrences, includeTaxonNameDescriptions, MediaPortalController.MEDIA_INIT_STRATEGY.getPropertyPaths()));
667
                }
668
            }
669
        }
670
        return media;
671
    }
672

    
673
    /**
674
     *
675
     * @param taxon
676
     * @param includeRelationships
677
     * @param type
678
     * @param mimeTypes
679
     * @param widthOrDuration
680
     * @param height
681
     * @param size
682
     * @return
683
     */
684
    private List<Media> listMediaForTaxon(Taxon taxon, Set<TaxonRelationshipEdge> includeRelationships,
685
            Boolean includeTaxonDescriptions, Boolean includeOccurrences, Boolean includeTaxonNameDescriptions, List<String> propertyPath) {
686

    
687
        List<Media> media = service.listMedia(taxon, includeRelationships,
688
                false, includeTaxonDescriptions, includeOccurrences, includeTaxonNameDescriptions, propertyPath);
689

    
690
        return media;
691
    }
692

    
693

    
694
    public class EntityMediaContext<T extends IdentifiableEntity> {
695

    
696
        T entity;
697
        List<Media> media;
698
        /**
699
         * @param entity
700
         * @param media
701
         */
702
        public EntityMediaContext(T entity, List<Media> media) {
703

    
704
            this.entity = HibernateProxyHelper.deproxy(entity);
705
            this.media = media;
706
        }
707
        public T getEntity() {
708
            return entity;
709
        }
710
        public List<Media> getMedia() {
711
            return media;
712
        }
713
        /**
714
         * @param addTaxonomicChildrenMedia
715
         */
716
        public void setMedia(List<Media> media) {
717
            this.media = media;
718

    
719
        }
720

    
721

    
722

    
723
    }
724

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

    
760
}
(62-62/76)