Project

General

Profile

Download (31.5 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.nomenclaturalReference.authorship",
121
            "name.nomenclaturalReference.inReference",
122
            "name.rank.representations",
123
            "name.status.type.representations"
124
//            "descriptions" // TODO remove
125

    
126
            }));
127

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

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

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

    
155
            "name.typeDesignations",
156

    
157
            "name.homotypicalGroup.$",
158
            "name.homotypicalGroup.typifiedNames.$",
159
            "name.homotypicalGroup.typifiedNames.nomenclaturalReference.authorship",
160
            "name.homotypicalGroup.typifiedNames.nomenclaturalReference.inReference",
161
//            "name.homotypicalGroup.typifiedNames.taxonBases.$"
162
    }));
163

    
164

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

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

    
185
    }));
186

    
187
    protected static final EntityInitStrategy TAXONDESCRIPTION_INIT_STRATEGY = DescriptionPortalController.DESCRIPTION_INIT_STRATEGY;
188

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

    
197

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

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

    
209
    }));
210

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

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

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

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

    
231

    
232
    public TaxonPortalController(){
233
        super();
234
        setInitializationStrategy(TAXON_INIT_STRATEGY.getPropertyPaths());
235
    }
236

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

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

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

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

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

    
294
        Map<String, List<?>> synonymy = new Hashtable<>();
295

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

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

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

    
310
        mv.addObject(synonymy);
311
        return mv;
312
    }
313

    
314

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

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

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

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

    
350
    @Override
351
    protected  EntityInitStrategy getTaxonNodeInitStrategy() {
352
        return TAXONNODE_INIT_STRATEGY;
353
    }
354

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

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

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

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

    
388
        return allRelationships;
389
    }
390

    
391
    /**
392
     * Get the list of {@link NameRelationship}s of the Name associated with the
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;nameRelationships</b>
396
     *
397
     * @param request
398
     * @param response
399
     * @return a List of {@link NameRelationship} entities which are initialized
400
     *         using the following initialization strategy:
401
     *         {@link #NAMERELATIONSHIP_INIT_STRATEGY}
402
     * @throws IOException
403
     */
404
    @RequestMapping(
405
            value = {"toNameRelationships"},
406
            method = RequestMethod.GET)
407
    public List<NameRelationship> doGetToNameRelations(@PathVariable("uuid") UUID uuid,
408
            HttpServletRequest request, HttpServletResponse response)throws IOException {
409
        logger.info("doGetNameRelations()" + request.getRequestURI());
410
        boolean includeUnpublished = NO_UNPUBLISHED;
411

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

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

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

    
439
        boolean includeUnpublished = NO_UNPUBLISHED;
440

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

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

    
446
        return list;
447
    }
448

    
449

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

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

    
521
        logger.info("doGetMedia() " + requestPathAndQuery(request));
522

    
523
        List<String> initStrategy = null;
524

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

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

    
532
        return mediafilteredForPreferredRepresentations;
533
    }
534

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

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

    
586
        boolean includeUnpublished = NO_UNPUBLISHED;
587

    
588

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

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

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

    
597
        EntityMediaContext<Taxon> entityMediaContext = new EntityMediaContext<Taxon>(taxon, media);
598

    
599
        return entityMediaContext;
600
    }
601

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

    
619

    
620
        boolean includeUnpublished = NO_UNPUBLISHED;
621

    
622
        logger.info("doGetSubtreeMedia() " + requestPathAndQuery(request));
623

    
624
        List<String> initStrategy = TAXON_WITH_CHILDNODES_INIT_STRATEGY.getPropertyPaths();
625

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

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

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

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

    
639
        return mediafilteredForPreferredRepresentations;
640
    }
641

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

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

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

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

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

    
696
        return media;
697
    }
698

    
699

    
700
    public class EntityMediaContext<T extends IdentifiableEntity> {
701

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

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

    
725
        }
726

    
727

    
728

    
729
    }
730

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

    
766
}
(61-61/75)