Project

General

Profile

Download (16.8 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2015 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
package eu.etaxonomy.cdm.api.service.dto;
10

    
11
import java.io.Serializable;
12
import java.util.AbstractMap;
13
import java.util.ArrayList;
14
import java.util.Collection;
15
import java.util.Comparator;
16
import java.util.EnumSet;
17
import java.util.HashSet;
18
import java.util.List;
19
import java.util.Set;
20
import java.util.TreeSet;
21
import java.util.stream.Collectors;
22

    
23
import eu.etaxonomy.cdm.common.CdmUtils;
24
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
25
import eu.etaxonomy.cdm.model.agent.AgentBase;
26
import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
27
import eu.etaxonomy.cdm.model.common.CdmBase;
28
import eu.etaxonomy.cdm.model.common.IdentifiableSource;
29
import eu.etaxonomy.cdm.model.description.DescriptionBase;
30
import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
31
import eu.etaxonomy.cdm.model.description.Feature;
32
import eu.etaxonomy.cdm.model.description.SpecimenDescription;
33
import eu.etaxonomy.cdm.model.description.TextData;
34
import eu.etaxonomy.cdm.model.media.Media;
35
import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignation;
36
import eu.etaxonomy.cdm.model.occurrence.DerivationEvent;
37
import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
38
import eu.etaxonomy.cdm.model.occurrence.FieldUnit;
39
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
40
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationType;
41
import eu.etaxonomy.cdm.model.term.DefinedTerm;
42
import eu.etaxonomy.cdm.model.term.TermBase;
43
import eu.etaxonomy.cdm.ref.TypedEntityReference;
44

    
45

    
46
public abstract class SpecimenOrObservationBaseDTO extends TypedEntityReference<SpecimenOrObservationBase<?>>{
47

    
48
    private static final long serialVersionUID = -7597690654462090732L;
49

    
50
    private int id;
51
    private TreeSet<AbstractMap.SimpleEntry<String, String>> characterData;
52
    private DerivationTreeSummaryDTO derivationTreeSummary;
53
    protected String taxonName;
54

    
55
    protected String summaryLabel;
56
    protected boolean hasDetailImage;
57
    private boolean hasCharacterData;
58
    private boolean hasDna;
59
    private boolean hasSpecimenScan;
60

    
61
    private SpecimenOrObservationType recordBase;
62
    private TermBase kindOfUnit;
63
    private String collectorsString;
64
    private String individualCount;
65
    private Set<DerivedUnitDTO> derivatives;
66
    private Set<AnnotationDTO> annotations = new HashSet<>();
67

    
68
    private Set<SpecimenTypeDesignationDTO> specimenTypeDesignations;
69

    
70
    private EventDTO<DerivationEvent> derivationEvent;
71

    
72
    // TODO use DTO !!!
73
    private Set<IdentifiableSource> sources;
74

    
75
    private List<MediaDTO> listOfMedia = new ArrayList<>();
76

    
77
    private DefinedTerm sex;
78

    
79
    private DefinedTerm lifeStage;
80

    
81
    private List<DeterminationEventDTO>determinations;
82

    
83
    protected SpecimenOrObservationBaseDTO(SpecimenOrObservationBase<?> specimenOrObservation) {
84
        super(HibernateProxyHelper.getClassWithoutInitializingProxy(specimenOrObservation), specimenOrObservation.getUuid(), specimenOrObservation.getTitleCache());
85
        this.id = specimenOrObservation.getId();
86
        Set<Media> collectedMedia = collectMedia(specimenOrObservation);
87
        addMediaAsDTO(collectedMedia);
88
        setKindOfUnit(specimenOrObservation.getKindOfUnit());
89
        setSex(specimenOrObservation.getSex());
90
        setIndividualCount(specimenOrObservation.getIndividualCount());
91
        lifeStage = specimenOrObservation.getLifeStage();
92
        FieldUnit fieldUnit = null;
93
        if (specimenOrObservation instanceof FieldUnit){
94
            fieldUnit = (FieldUnit)specimenOrObservation;
95
        }else{
96
            fieldUnit = getFieldUnit((DerivedUnit)specimenOrObservation);
97
        }
98
        if (fieldUnit != null){
99
            AgentBase<?> collector = null;
100
            if (fieldUnit.getGatheringEvent() != null){
101
                collector = fieldUnit.getGatheringEvent().getCollector();
102
            }
103
            String fieldNumberString = CdmUtils.Nz(fieldUnit.getFieldNumber());
104
            if (collector != null){
105
                if (collector.isInstanceOf(TeamOrPersonBase.class)){
106
                    collectorsString = CdmBase.deproxy(collector, TeamOrPersonBase.class).getCollectorTitleCache();
107
                }else{
108
                    collectorsString = collector.getTitleCache();  //institutions
109
                }
110
            }
111
            collectorsString = CdmUtils.concat(" - ", collectorsString, fieldNumberString);
112
        }
113
        setDeterminations(specimenOrObservation.getDeterminations().stream()
114
                .map(det -> DeterminationEventDTO.from(det))
115
                .collect(Collectors.toList())
116
                );
117
        if (specimenOrObservation instanceof DerivedUnit){
118
            DerivedUnit derivedUnit = (DerivedUnit)specimenOrObservation;
119
            if (derivedUnit.getSpecimenTypeDesignations() != null){
120
                setSpecimenTypeDesignations(derivedUnit.getSpecimenTypeDesignations());
121
            }
122
        }
123
    }
124

    
125
    /**
126
     * finds the field unit of the derived unit or null if no field unit exist
127
     * @param specimenOrObservation
128
     * @return
129
     */
130
    private FieldUnit getFieldUnit(DerivedUnit specimenOrObservation) {
131
        if (specimenOrObservation.getDerivedFrom() != null && !specimenOrObservation.getDerivedFrom().getOriginals().isEmpty()){
132
            for (SpecimenOrObservationBase<?> specimen: specimenOrObservation.getDerivedFrom().getOriginals()){
133
                if (specimen instanceof FieldUnit){
134
                    return (FieldUnit)specimen;
135
                }else if (specimen instanceof DerivedUnit){
136
                    getFieldUnit(HibernateProxyHelper.deproxy(specimen,DerivedUnit.class));
137
                }
138
            }
139
        }
140
        return null;
141
    }
142

    
143
    public String getCollectorsString() {
144
        return collectorsString;
145
    }
146
    public void setCollectorsString(String collectorsString) {
147
        this.collectorsString = collectorsString;
148
    }
149

    
150
    public Set<SpecimenTypeDesignationDTO> getSpecimenTypeDesignations() {
151
        return specimenTypeDesignations;
152
    }
153

    
154
    public void setSpecimenTypeDesignations(Set<SpecimenTypeDesignation> specimenTypeDesignations) {
155
        this.specimenTypeDesignations = new HashSet<>();
156
        for (SpecimenTypeDesignation typeDes: specimenTypeDesignations){
157
            if (typeDes != null){
158
                this.specimenTypeDesignations.add(new SpecimenTypeDesignationDTO(typeDes));
159
            }
160
        }
161
    }
162

    
163
    public Set<IdentifiableSource> getSources() {
164
        return sources;
165
    }
166

    
167
    public void setSources(Set<IdentifiableSource> sources) {
168
        this.sources = sources;
169
    }
170

    
171
    public DerivationTreeSummaryDTO getDerivationTreeSummary() {
172
        return derivationTreeSummary;
173
    }
174
    public void setDerivationTreeSummary(DerivationTreeSummaryDTO derivationTreeSummary) {
175
        this.derivationTreeSummary = derivationTreeSummary;
176
        if(derivationTreeSummary != null) {
177
            setHasSpecimenScan(isHasSpecimenScan() || !derivationTreeSummary.getSpecimenScans().isEmpty());
178
            setHasDetailImage(isHasDetailImage() || !derivationTreeSummary.getDetailImages().isEmpty());
179
            setHasDna(isHasDna() || !derivationTreeSummary.getMolecularDataList().isEmpty());
180
        }
181
    }
182

    
183
    public TreeSet<AbstractMap.SimpleEntry<String, String>> getCharacterData() {
184
        return characterData;
185
    }
186
    public void addCharacterData(String character, String state){
187
      if(characterData==null){
188
          characterData = new TreeSet<>(new PairComparator());
189
      }
190
      characterData.add(new AbstractMap.SimpleEntry<>(character, state));
191
      this.setHasCharacterData(!this.characterData.isEmpty());
192
    }
193

    
194
    private class PairComparator implements Comparator<AbstractMap.SimpleEntry<String,String>>, Serializable {
195

    
196
        private static final long serialVersionUID = -8589392050761963540L;
197

    
198
        @Override
199
        public int compare(AbstractMap.SimpleEntry<String, String> o1, AbstractMap.SimpleEntry<String, String> o2) {
200
            if(o1==null && o2!=null){
201
                return -1;
202
            }
203
            if(o1!=null && o2==null){
204
                return 1;
205
            }
206
            if(o1!=null && o2!=null){
207
                return o1.getKey().compareTo(o2.getKey());
208
            }
209
            return 0;
210
        }
211
    }
212

    
213
    public boolean isHasCharacterData() {
214
        return hasCharacterData;
215
    }
216
    public void setHasCharacterData(boolean hasCharacterData) {
217
        this.hasCharacterData = hasCharacterData;
218
    }
219

    
220
    public boolean isHasDna() {
221
        return hasDna;
222
    }
223
    public void setHasDna(boolean hasDna) {
224
        this.hasDna = hasDna;
225
    }
226

    
227
    public boolean isHasDetailImage() {
228
        return hasDetailImage;
229
    }
230
    public void setHasDetailImage(boolean hasDetailImage) {
231
        this.hasDetailImage = hasDetailImage;
232
    }
233

    
234
    public boolean isHasSpecimenScan() {
235
        return hasSpecimenScan;
236
    }
237
    public void setHasSpecimenScan(boolean hasSpecimenScan) {
238
        this.hasSpecimenScan = hasSpecimenScan;
239
    }
240
    /**
241
     * @return The summary of all DerivedUnit identifiers with the label of
242
     * this SpecimenOrObservationBase.
243
     * This label is usually being user for citing the unit in publications.
244
     */
245
    public String getSummaryLabel() {
246
        return summaryLabel;
247
    }
248

    
249
    /**
250
     * Summary of all DerivedUnit identifiers with the label of this SpecimenOrObservationBase.
251
     * This label is usually being user for citing the unit in publications.
252
     */
253
    public void setSummaryLabel(String summaryLabel) {
254
        this.summaryLabel = summaryLabel;
255
    }
256

    
257
    public SpecimenOrObservationType getRecordBase() {
258
        return recordBase;
259
    }
260
    public void setRecordBase(SpecimenOrObservationType specimenOrObservationType) {
261
        this.recordBase = specimenOrObservationType;
262
    }
263

    
264
    public Set<DerivedUnitDTO> getDerivatives() {
265
        if (this.derivatives == null){
266
            this.derivatives = new HashSet<>();
267
        }
268
        return derivatives;
269
    }
270

    
271
    public void setDerivatives(Set<DerivedUnitDTO> derivatives) {
272
        this.derivatives = derivatives;
273
        updateTreeDependantData(derivatives);
274
    }
275

    
276
    public void addDerivative(DerivedUnitDTO derivate){
277
        if (this.derivatives == null){
278
            this.derivatives = new HashSet<>();
279
        }
280
        this.derivatives.add(derivate);
281
        Set<DerivedUnitDTO> derivatives = new HashSet<>();
282
        derivatives.add(derivate);
283
        updateTreeDependantData(derivatives);
284
    }
285
    public void addAllDerivatives(Set<DerivedUnitDTO> derivatives){
286
        if (this.derivatives == null){
287
            this.derivatives = new HashSet<>();
288
        }
289
        this.derivatives.addAll(derivatives);
290
        updateTreeDependantData(derivatives);
291
    }
292
    
293
    
294

    
295
    /**
296
     * To be overwritten by implementing classes to
297
     * update data which depends on the derivation tree
298
     */
299
    protected abstract void updateTreeDependantData(Set<DerivedUnitDTO> derivatives) ;
300

    
301
    /**
302
     * Recursively collects all derivatives from this.
303
     */
304
    public Collection<DerivedUnitDTO> collectDerivatives() {
305
        return collectDerivatives(new HashSet<>());
306
    }
307

    
308
    /**
309
     * private partner method to {@link #collectDerivatives()} for recursive calls.
310
     *
311
     * @param dtos
312
     */
313
    private Collection<DerivedUnitDTO> collectDerivatives(Set<DerivedUnitDTO> dtos) {
314
        dtos.addAll(getDerivatives());
315
        if(derivatives != null) {
316
            for(SpecimenOrObservationBaseDTO subDto : derivatives) {
317
                dtos.addAll(subDto.collectDerivatives(dtos));
318
            }
319
        }
320
        return dtos;
321
    }
322

    
323
    public EventDTO<DerivationEvent> getDerivationEvent() {
324
        return derivationEvent;
325
    }
326
    public void setDerivationEvent(EventDTO<DerivationEvent> derivationEvent) {
327
        this.derivationEvent = derivationEvent;
328
    }
329

    
330
    public List<MediaDTO> getListOfMedia() {
331
        return listOfMedia;
332
    }
333
    public void setListOfMedia(List<MediaDTO> listOfMedia) {
334
        this.listOfMedia = listOfMedia;
335
    }
336

    
337
    protected Set<Media> collectMedia(SpecimenOrObservationBase<?> specimenOrObservation){
338
        Set<Media> collectedMedia = new HashSet<>();
339
        Set<SpecimenDescription> descriptions = specimenOrObservation.getSpecimenDescriptionImageGallery();
340
        for (DescriptionBase<?> desc : descriptions){
341
            if (desc instanceof SpecimenDescription){
342
                SpecimenDescription specimenDesc = (SpecimenDescription)desc;
343
                for (DescriptionElementBase element : specimenDesc.getElements()){
344
                    if (element.isInstanceOf(TextData.class)&& element.getFeature().equals(Feature.IMAGE())) {
345
                        for (Media media :element.getMedia()){
346
                            collectedMedia.add(media);
347
                        }
348
                    }
349
                }
350
            }
351
        }
352
        return collectedMedia;
353
    }
354

    
355
    private void addMediaAsDTO(Set<Media> media) {
356
        for(Media m : media) {
357
            List<MediaDTO> dtos = MediaDTO.fromEntity(m);
358
            getListOfMedia().addAll(dtos);
359
        }
360
    }
361

    
362
    /**
363
     * @param sob
364
     *      The Unit to assemble the derivatives information for
365
     * @param maxDepth
366
     *   The maximum number of derivation events levels up to which derivatives are to be assembled.
367
     *   <code>NULL</code> means infinitely.
368
     * @param includeTypes
369
     *      Allows for positive filtering by {@link SpecimenOrObservationType}.
370
     *      Filter is disabled when <code>NULL</code>. This only affects the derivatives assembled in the
371
     *      {@link #derivatives} list. The <code>unitLabelsByCollection</code> are always collected for the
372
     *      whole bouquet of derivatives.
373
     * @param unitLabelsByCollection
374
     *      A map to record the unit labels (most significant identifier + collection code) per collection.
375
     *      Optional parameter, may be <code>NULL</code>.
376
     * @return
377
     */
378
    protected Set<DerivedUnitDTO> assembleDerivatives(SpecimenOrObservationBase<?> sob,
379
            Integer maxDepth, EnumSet<SpecimenOrObservationType> includeTypes) {
380

    
381
        boolean doDescend = maxDepth == null || maxDepth > 0;
382
        Integer nextLevelMaxDepth = maxDepth != null ? maxDepth - 1 : null;
383
        Set<DerivedUnitDTO> derivateDTOs = new HashSet<>();
384
        // collectDerivedUnitsMaxdepth => 0 to avoid aggregation of sub ordinate
385
        // derivatives at each level
386
        Integer collectDerivedUnitsMaxdepth = 0;
387
        for (DerivedUnit derivedUnit : sob.collectDerivedUnits(collectDerivedUnitsMaxdepth)) {
388
            if(!derivedUnit.isPublish()){
389
                continue;
390
            }
391

    
392
            if (doDescend && (includeTypes == null || includeTypes.contains(derivedUnit.getRecordBasis()))) {
393
                SpecimenOrObservationBaseDTO derivedUnitDTO = SpecimenOrObservationDTOFactory.fromEntity(derivedUnit, nextLevelMaxDepth);
394
                if (derivedUnitDTO instanceof DerivedUnitDTO) {
395
                	derivateDTOs.add((DerivedUnitDTO)derivedUnitDTO);
396
                }
397
                setHasCharacterData(isHasCharacterData() || derivedUnitDTO.isHasCharacterData());
398
                // NOTE! the flags setHasDetailImage, setHasDna, setHasSpecimenScan are also set in
399
                // setDerivateDataDTO(), see below
400
                setHasDetailImage(isHasDetailImage() || derivedUnitDTO.isHasDetailImage());
401
                setHasDna(isHasDna() || derivedUnitDTO.isHasDna());
402
                setHasSpecimenScan(isHasSpecimenScan() || derivedUnitDTO.isHasSpecimenScan());
403
                setHasCharacterData(isHasCharacterData() || derivedUnitDTO.isHasCharacterData());
404
            }
405
        }
406
        return derivateDTOs;
407
    }
408

    
409
    public TermBase getKindOfUnit() {
410
        return kindOfUnit;
411
    }
412
    public void setKindOfUnit(TermBase kindOfUnit) {
413
        this.kindOfUnit = HibernateProxyHelper.deproxy(kindOfUnit);
414
    }
415

    
416
    public DefinedTerm getSex() {
417
        return sex;
418
    }
419
    public void setSex(DefinedTerm sex) {
420
        this.sex = sex;
421
    }
422

    
423
    public DefinedTerm getLifeStage() {
424
        return lifeStage;
425
    }
426
    public void setLifeStage(DefinedTerm lifeStage) {
427
        this.lifeStage = lifeStage;
428
    }
429

    
430
    public int getId() {
431
        return id;
432
    }
433

    
434
    public String getIndividualCount() {
435
        return individualCount;
436
    }
437
    public void setIndividualCount(String individualCount) {
438
        this.individualCount = individualCount;
439
    }
440

    
441
    public List<DeterminationEventDTO> getDeterminations() {
442
        return determinations;
443
    }
444

    
445
    public void setDeterminations(List<DeterminationEventDTO> determinations) {
446
        this.determinations = determinations;
447
    }
448

    
449
    public Set<AnnotationDTO> getAnnotations() {
450
        return annotations;
451
    }
452

    
453
    protected void addAnnotation(AnnotationDTO annotation) {
454
        this.annotations.add(annotation);
455
    }
456
}
(36-36/47)