Project

General

Profile

Download (32.3 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.logging.log4j.LogManager;import org.apache.logging.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 = LogManager.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
            "secSource.nameUsedInSource.$",
128
            "secSource.citation.authorship.$",
129
            "secSource.citation.inReference.authorship.$"
130
//            "descriptions" // TODO remove
131

    
132
            }));
133

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

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

    
155
    public static final EntityInitStrategy SYNONYMY_INIT_STRATEGY = new EntityInitStrategy(Arrays.asList(new String []{
156
            // initialize homotypical and heterotypical groups; needs synonyms
157
            "synonyms.$",
158
            "synonyms.name.status.type.representations",
159
            "synonyms.name.status.source.citation",
160
            "synonyms.name.nomenclaturalSource.citation.authorship",
161
            "synonyms.name.nomenclaturalSource.citation.inReference.authorship",
162
//            "synonyms.name.homotypicalGroup.typifiedNames.$",
163
//            "synonyms.name.homotypicalGroup.typifiedNames.taxonBases.$",
164
            "synonyms.name.combinationAuthorship.$",
165
            "synonyms.secSource.citation.authorship.$",
166
            "synonyms.secSource.citation.inReference.authorship.$",
167
            "synonyms.secSource.nameUsedInSource.$",
168
            "name.typeDesignations",
169

    
170
            "name.homotypicalGroup.$",
171
            "name.homotypicalGroup.typifiedNames.$",
172
            "name.homotypicalGroup.typifiedNames.nomenclaturalSource.citation.authorship",
173
            "name.homotypicalGroup.typifiedNames.nomenclaturalSource.citation.inReference.authorship",
174
//            "name.homotypicalGroup.typifiedNames.taxonBases.$"
175
    }));
176

    
177

    
178
    private static final EntityInitStrategy TAXONRELATIONSHIP_INIT_STRATEGY = new EntityInitStrategy(Arrays.asList(new String []{
179
            "$",
180
            "type.inverseRepresentations",
181
            "fromTaxon.sec",
182
            "fromTaxon.name",
183
            "toTaxon.sec",
184
            "toTaxon.name"
185
    }));
186

    
187
    public static final EntityInitStrategy NAMERELATIONSHIP_INIT_STRATEGY = new EntityInitStrategy(Arrays.asList(new String []{
188
            "$",
189
            "type.inverseRepresentations",
190
            "source.citation",
191
            "toName.$",
192
            "toName.nomenclaturalSource.citation.authorship",
193
            "toName.nomenclaturalSource.citation.inReference.authorship",
194
            "fromName.$",
195
            "fromName.nomenclaturalSource.citation.authorship",
196
            "fromName.nomenclaturalSource.citation.inReference.authorship",
197

    
198
    }));
199

    
200
    protected static final EntityInitStrategy TAXONDESCRIPTION_INIT_STRATEGY = DescriptionPortalController.DESCRIPTION_INIT_STRATEGY;
201

    
202
    protected static final EntityInitStrategy DESCRIPTION_ELEMENT_INIT_STRATEGY = new EntityInitStrategy(Arrays.asList(new String []{
203
            "$",
204
            "sources.citation.authorship",
205
            "sources.citation.inReference.authorship",
206
            "sources.nameUsedInSource",
207
            "multilanguageText",
208
            "media",
209
    }));
210

    
211

    
212
//	private static final List<String> NAMEDESCRIPTION_INIT_STRATEGY = Arrays.asList(new String []{
213
//			"uuid",
214
//			"feature",
215
//			"elements.$",
216
//			"elements.multilanguageText",
217
//			"elements.media",
218
//	});
219

    
220
    protected static final EntityInitStrategy TAXONDESCRIPTION_MEDIA_INIT_STRATEGY = new EntityInitStrategy(Arrays.asList(new String []{
221
            "elements.media"
222

    
223
    }));
224

    
225
    private static final EntityInitStrategy TYPEDESIGNATION_INIT_STRATEGY = new EntityInitStrategy(Arrays.asList(new String []{
226
            "typeSpecimen.$",
227
            "citation.authorship.$",
228
            "typeName",
229
            "typeStatus"
230
    }));
231

    
232
    protected static final EntityInitStrategy TAXONNODE_WITH_CHILDNODES_INIT_STRATEGY = new EntityInitStrategy(Arrays.asList(new String []{
233
            "childNodes.taxon",
234
    }));
235

    
236
    protected static final EntityInitStrategy TAXONNODE_INIT_STRATEGY = new EntityInitStrategy(Arrays.asList(new String []{
237
            "taxonNodes.classification",
238
            "taxonNodes.parent",
239
            "taxonNodes.statusNote.*",
240
            "taxonNodes.taxon.name",
241
            "taxonNodes.taxon.secSource.citation",
242
            "taxonNodes.taxon.secSource.nameUsedInSource.$",
243
            "taxonNodes.taxon.secSource.citation.authorship.$",
244
            "taxonNodes.taxon.secSource.citation.inReference.authorship.$",
245
            "taxonNodes.source.citation.authorship",
246
            "taxonNodes.source.citation.inReference.authorship",
247
            "acceptedTaxon.taxonNodes.classification",
248
            "secSource.nameUsedInSource"
249
            
250
    }));
251

    
252
    @Override
253
    protected <CDM_BASE extends CdmBase> List<String> complementInitStrategy(Class<CDM_BASE> clazz,
254
            List<String> pathProperties) {
255

    
256
        if(pathProperties != null) {
257
            List<String> complemented = new ArrayList<>(pathProperties);
258
            if(pathProperties.contains("name")) {
259
                // pathProperties for web service request for portal/taxon/{uuid}/name
260
                complemented.add("name.nomenclaturalSource.citation.authorship");
261
                complemented.add("name.nomenclaturalSource.citation.inReference.authorship");
262
                return complemented;
263
            }
264
        }
265
        return pathProperties;
266
    }
267

    
268
    public TaxonPortalController(){
269
        super();
270
        setInitializationStrategy(TAXON_INIT_STRATEGY.getPropertyPaths());
271
    }
272

    
273
    @Autowired
274
    @Override
275
    public void setService(ITaxonService service) {
276
        this.service = service;
277
    }
278

    
279
    @InitBinder
280
    @Override
281
    public void initBinder(WebDataBinder binder) {
282
        super.initBinder(binder);
283
        binder.registerCustomEditor(NamedArea.class, new NamedAreaPropertyEditor());
284
        binder.registerCustomEditor(MatchMode.class, new MatchModePropertyEditor());
285
        binder.registerCustomEditor(Class.class, new CdmTypePropertyEditor());
286
        binder.registerCustomEditor(UuidList.class, new UUIDListPropertyEditor());
287
        binder.registerCustomEditor(DefinedTermBaseList.class, new TermBaseListPropertyEditor<>(termService));
288
    }
289

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

    
320
        boolean includeUnpublished = NO_UNPUBLISHED;
321
        if(request != null){
322
            logger.info("doGetSynonymy() " + requestPathAndQuery(request));
323
        }
324
        ModelAndView mv = new ModelAndView();
325

    
326
        Taxon taxon = getCdmBaseInstance(Taxon.class, taxonUuid, response, getTaxonNodeInitStrategy().getPropertyPaths());
327
        TaxonNode subtree = getSubtreeOrError(subtreeUuid, taxonNodeService, response);
328
        taxon = checkExistsSubtreeAndAccess(taxon, subtree, NO_UNPUBLISHED, response);
329

    
330
        Map<String, List<?>> synonymy = new Hashtable<>();
331

    
332
        //new
333
        List<List<Synonym>> synonymyGroups = service.getSynonymsByHomotypicGroup(taxon, SYNONYMY_INIT_STRATEGY.getPropertyPaths());
334
        if(!includeUnpublished){
335
            synonymyGroups = removeUnpublishedSynonyms(synonymyGroups);
336
        }
337

    
338
        synonymy.put("homotypicSynonymsByHomotypicGroup", synonymyGroups.get(0));
339
        synonymyGroups.remove(0);
340
        synonymy.put("heterotypicSynonymyGroups", synonymyGroups);
341

    
342
        //old
343
//        synonymy.put("homotypicSynonymsByHomotypicGroup", service.getHomotypicSynonymsByHomotypicGroup(taxon, SYNONYMY_INIT_STRATEGY));
344
//        synonymy.put("heterotypicSynonymyGroups", service.getHeterotypicSynonymyGroups(taxon, SYNONYMY_INIT_STRATEGY));
345

    
346
        mv.addObject(synonymy);
347
        return mv;
348
    }
349

    
350

    
351
    /**
352
     * @param synonymyGroups
353
     */
354
    private List<List<Synonym>> removeUnpublishedSynonyms(List<List<Synonym>> synonymyGroups) {
355
        List<List<Synonym>> result = new ArrayList<>();
356
        boolean isHomotypicToAccepted = true;
357

    
358
        for (List<Synonym> oldList : synonymyGroups){
359
            List<Synonym> newList = new ArrayList<>();
360
            for (Synonym oldSyn : oldList){
361
                if (oldSyn.isPublish()){
362
                    newList.add(oldSyn);
363
                }
364
            }
365
            if (isHomotypicToAccepted || !newList.isEmpty()){
366
                result.add(newList);
367
            }
368
            isHomotypicToAccepted = false;
369
        }
370
        return result;
371
    }
372

    
373
    /**
374
     * {@inheritDoc}
375
     */
376
    @Override
377
    protected List<String> getTaxonDescriptionInitStrategy() {
378
        return TAXONDESCRIPTION_INIT_STRATEGY.getPropertyPaths();
379
    }
380

    
381
    @Override
382
    protected List<String> getTaxonDescriptionElementInitStrategy() {
383
        return DESCRIPTION_ELEMENT_INIT_STRATEGY.getPropertyPaths();
384
    }
385

    
386
    @Override
387
    protected  EntityInitStrategy getTaxonNodeInitStrategy() {
388
        return TAXONNODE_INIT_STRATEGY;
389
    }
390

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

    
410
        boolean includeUnpublished = NO_UNPUBLISHED;
411
        logger.info("doGetTaxonRelations()" + requestPathAndQuery(request));
412
        Taxon taxon = getCdmBaseInstance(Taxon.class, uuid, response, (List<String>)null);
413
        taxon = checkExistsAndAccess(taxon, includeUnpublished, response);
414

    
415
        List<TaxonRelationship> toRelationships = service.listToTaxonRelationships(taxon, null,
416
                includeUnpublished, null, null, null, TAXONRELATIONSHIP_INIT_STRATEGY.getPropertyPaths());
417
        List<TaxonRelationship> fromRelationships = service.listFromTaxonRelationships(taxon, null,
418
                includeUnpublished, null, null, null, TAXONRELATIONSHIP_INIT_STRATEGY.getPropertyPaths());
419

    
420
        List<TaxonRelationship> allRelationships = new ArrayList<>(toRelationships.size() + fromRelationships.size());
421
        allRelationships.addAll(toRelationships);
422
        allRelationships.addAll(fromRelationships);
423

    
424
        return allRelationships;
425
    }
426

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

    
448
        TaxonBase<?> taxonBase = getCdmBaseInstance(TaxonBase.class, uuid, response, (List<String>)null);
449
        taxonBase = checkExistsAndAccess(taxonBase, includeUnpublished, response);
450

    
451
        List<NameRelationship> list = nameService.listNameRelationships(taxonBase.getName(), Direction.relatedTo, null, null, 0, null, NAMERELATIONSHIP_INIT_STRATEGY.getPropertyPaths());
452
        return list;
453
    }
454

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

    
475
        boolean includeUnpublished = NO_UNPUBLISHED;
476

    
477
        TaxonBase<?> taxonBase = getCdmBaseInstance(TaxonBase.class, uuid, response, SIMPLE_TAXON_INIT_STRATEGY.getPropertyPaths());
478
        taxonBase = checkExistsAndAccess(taxonBase, includeUnpublished, response);
479

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

    
482
        return list;
483
    }
484

    
485

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

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

    
557
        logger.info("doGetMedia() " + requestPathAndQuery(request));
558

    
559
        List<String> initStrategy = null;
560

    
561
        EntityMediaContext<Taxon> taxonMediaContext = loadMediaForTaxonAndRelated(uuid, relationshipUuids,
562
                relationshipInversUuids, includeTaxonDescriptions, includeOccurrences, includeTaxonNameDescriptions,
563
                response, initStrategy, MediaPortalController.MEDIA_INIT_STRATEGY.getPropertyPaths());
564

    
565
        List<Media> mediafilteredForPreferredRepresentations = mediaToolbox.processAndFilterPreferredMediaRepresentations(type, mimeTypes, widthOrDuration, height, size,
566
                taxonMediaContext.media);
567

    
568
        return mediafilteredForPreferredRepresentations;
569
    }
570

    
571
    /**
572
     * @Deprecated To be replaced by other loadMediaForTaxonAndRelated method
573
     */
574
    @Deprecated
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) throws IOException {
580
        return loadMediaForTaxonAndRelated(uuid, relationshipUuids, relationshipInversUuids,
581
                includeTaxonDescriptions, includeOccurrences, includeTaxonNameDescriptions, response, taxonInitStrategy, null);
582
    }
583

    
584
    public  EntityMediaContext<Taxon> loadMediaForTaxonAndRelated(UUID taxonUuid,
585
            UuidList relationshipUuids, UuidList relationshipInversUuids,
586
            Boolean includeTaxonDescriptions, Boolean includeOccurrences, Boolean includeTaxonNameDescriptions,
587
            HttpServletResponse response,
588
            List<String> taxonInitStrategy, List<String> mediaInitStrategy) throws IOException {
589

    
590
        boolean includeUnpublished = NO_UNPUBLISHED;
591

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

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

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

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

    
602
        return entityMediaContext;
603
    }
604

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

    
676
        List<Media> media = service.listMedia(taxon, includeRelationships,
677
                false, includeTaxonDescriptions, includeOccurrences, includeTaxonNameDescriptions, propertyPath);
678

    
679
        return media;
680
    }
681

    
682
    public class EntityMediaContext<T extends IdentifiableEntity> {
683

    
684
        private T entity;
685
        private List<Media> media;
686

    
687
        public EntityMediaContext(T entity, List<Media> media) {
688
            this.entity = HibernateProxyHelper.deproxy(entity);
689
            this.media = media;
690
        }
691

    
692
        public T getEntity() {
693
            return entity;
694
        }
695
        public List<Media> getMedia() {
696
            return media;
697
        }
698

    
699
        /**
700
         * @param addTaxonomicChildrenMedia
701
         */
702
        public void setMedia(List<Media> media) {
703
            this.media = media;
704

    
705
        }
706
    }
707

    
708
// ---------------------- code snippet preserved for possible later use --------------------
709
//	@RequestMapping(
710
//			value = {"//*/portal/taxon/*/descriptions"}, // mapped as absolute path, see CdmAntPathMatcher
711
//			method = RequestMethod.GET)
712
//	public List<TaxonDescription> doGetDescriptionsbyFeatureTree(HttpServletRequest request, HttpServletResponse response)throws IOException {
713
//		TaxonBase tb = getCdmBase(request, response, null, Taxon.class);
714
//		if(tb instanceof Taxon){
715
//			//T O D O this is a quick and dirty implementation -> generalize
716
//			UUID featureTreeUuid = readValueUuid(request, termTreeUuidPattern);
717
//
718
//			FeatureTree featureTree = descriptionService.getFeatureTreeByUuid(featureTreeUuid);
719
//			Pager<TaxonDescription> p = descriptionService.getTaxonDescriptions((Taxon)tb, null, null, null, null, TAXONDESCRIPTION_INIT_STRATEGY);
720
//			List<TaxonDescription> descriptions = p.getRecords();
721
//
722
//			if(!featureTree.isDescriptionSeparated()){
723
//
724
//				TaxonDescription superDescription = TaxonDescription.NewInstance();
725
//				//put all descriptionElements in superDescription and make it invisible
726
//				for(TaxonDescription description: descriptions){
727
//					for(DescriptionElementBase element: description.getElements()){
728
//						superDescription.addElement(element);
729
//					}
730
//				}
731
//				List<TaxonDescription> separatedDescriptions = new ArrayList<TaxonDescription>(descriptions.size());
732
//				separatedDescriptions.add(superDescription);
733
//				return separatedDescriptions;
734
//			}else{
735
//				return descriptions;
736
//			}
737
//		} else {
738
//			response.sendError(HttpServletResponse.SC_NOT_FOUND, "invalid type; Taxon expected but " + tb.getClass().getSimpleName() + " found.");
739
//			return null;
740
//		}
741
//	}
742

    
743
}
(62-62/76)