Project

General

Profile

Download (15.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.util.ArrayList;
12
import java.util.Collection;
13
import java.util.Collections;
14
import java.util.EnumSet;
15
import java.util.HashMap;
16
import java.util.HashSet;
17
import java.util.List;
18
import java.util.Map;
19
import java.util.Set;
20
import java.util.regex.Pattern;
21

    
22
import eu.etaxonomy.cdm.common.CdmUtils;
23
import eu.etaxonomy.cdm.common.URI;
24
import eu.etaxonomy.cdm.format.CdmFormatterFactory;
25
import eu.etaxonomy.cdm.format.ICdmFormatter.FormatKey;
26
import eu.etaxonomy.cdm.format.description.DefaultCategoricalDescriptionBuilder;
27
import eu.etaxonomy.cdm.format.description.DefaultQuantitativeDescriptionBuilder;
28
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
29
import eu.etaxonomy.cdm.model.common.Language;
30
import eu.etaxonomy.cdm.model.description.CategoricalData;
31
import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
32
import eu.etaxonomy.cdm.model.description.QuantitativeData;
33
import eu.etaxonomy.cdm.model.media.Media;
34
import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignation;
35
import eu.etaxonomy.cdm.model.name.TaxonName;
36
import eu.etaxonomy.cdm.model.name.TypeDesignationStatusBase;
37
import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
38
import eu.etaxonomy.cdm.model.occurrence.MediaSpecimen;
39
import eu.etaxonomy.cdm.model.occurrence.OccurrenceStatus;
40
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
41
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationType;
42
import eu.etaxonomy.cdm.model.taxon.Taxon;
43
import eu.etaxonomy.cdm.ref.TypedEntityReference;
44

    
45
/**
46
 * @author pplitzner
47
 * @since Mar 26, 2015
48
 */
49
public class DerivedUnitDTO extends SpecimenOrObservationBaseDTO{
50

    
51
    private static final long serialVersionUID = 2345864166579381295L;
52

    
53
    private String accessionNumber;
54
    private String specimenShortTitle;
55
    private TypedEntityReference<TaxonName> storedUnder;
56
    private URI preferredStableUri;
57

    
58
    private List<TypedEntityReference<Taxon>> associatedTaxa;
59
    private Map<String, List<String>> types;
60

    
61
    private String originalLabelInfo;
62
    private String exsiccatum;
63
    private String mostSignificantIdentifier;
64

    
65
    private CollectionDTO collection;
66

    
67
    private String catalogNumber;
68

    
69
    private String barcode;
70

    
71
    private String preservationMethod;
72
    private List<DerivedUnitStatusDto> status; 
73

    
74
    /**
75
     * Constructs a new DerivedUnitDTO. All derivatives of the passed <code>DerivedUnit entity</code> will be collected and
76
     * added as DerivedUnitDTO to the {@link SpecimenOrObservationBaseDTO#getDerivatives() derivative DTOs}.
77
     *
78
     * @param entity
79
     *   The entity to create the dto for
80
     *
81
     * @return <code>null</code> or the new DerivedUnitDTO
82
     */
83
    public static DerivedUnitDTO fromEntity(DerivedUnit entity){
84
        return fromEntity(entity, null, null);
85
    }
86

    
87
    /**
88
     * Constructs a new DerivedUnitDTO. All derivatives of the passed <code>DerivedUnit entity</code> will be collected and
89
     * added as DerivedUnitDTO to the {@link SpecimenOrObservationBaseDTO#getDerivatives() derivative DTOs}.
90
     *
91
     * @param entity
92
     *   The entity to create the dto for
93
     * @param maxDepth
94
     *   The maximum number of derivation events levels up to which derivatives are to be collected.
95
     *   <code>NULL</code> means infinitely.
96
     * @param specimenOrObservationTypeFilter
97
     *     Set of SpecimenOrObservationType to be included into the collection of {@link #getDerivatives() derivative DTOs}
98
     * @return
99
     *  The DTO
100
     */
101
    @SuppressWarnings("rawtypes")
102
    public static DerivedUnitDTO fromEntity(DerivedUnit entity, Integer maxDepth,
103
            EnumSet<SpecimenOrObservationType> specimenOrObservationTypeFilter){
104

    
105
        if(entity == null) {
106
            return null;
107
        }
108
        DerivedUnitDTO dto =  new DerivedUnitDTO(entity);
109

    
110
        // ---- assemble derivation tree summary
111
        //      this data should be sufficient in clients for showing the unit in a list view
112
        dto.setDerivationTreeSummary(DerivationTreeSummaryDTO.fromEntity(entity, dto.getSpecimenShortTitle()));
113

    
114
        // ---- assemble derivatives
115
        //      this data is is often only required for clients in order to show the details of the derivation tree
116
        dto.addAllDerivatives(dto.assembleDerivatives(entity, maxDepth, specimenOrObservationTypeFilter));
117

    
118
        // ---- annotations
119
        dto.collectOriginals(entity, new HashSet<SpecimenOrObservationBase>())
120
            .forEach(o -> o.getAnnotations()
121
                    .forEach(a -> dto.addAnnotation(AnnotationDTO.fromEntity(a))
122
                            )
123
                    );
124
        
125
        return dto;
126
    }
127

    
128
    /**
129
     * Collects all originals from the given <code>entity</code> to the root of the
130
     * derivation graph including the <code>entity</code> itself.
131
     *
132
     * @param entity
133
     *            The DerivedUnit to start the collecting walk
134
     */
135
    private Set<SpecimenOrObservationBase> collectOriginals(SpecimenOrObservationBase entity, Set<SpecimenOrObservationBase> originalsToRoot) {
136
        originalsToRoot.add(entity);
137
        SpecimenOrObservationBase entityDeproxied = HibernateProxyHelper.deproxy(entity);
138
        if (entityDeproxied instanceof DerivedUnit) {
139
            ((DerivedUnit)entityDeproxied).getOriginals().forEach(o -> collectOriginals(o, originalsToRoot));
140
        }
141
        return originalsToRoot;
142
    }
143

    
144
    /**
145
     * @param derivedUnit
146
     */
147
    public DerivedUnitDTO(DerivedUnit derivedUnit) {
148
        super(derivedUnit);
149

    
150
        // experimental feature, not yet exposed in method signature
151
        boolean cleanAccessionNumber = false;
152
        accessionNumber = derivedUnit.getAccessionNumber();
153
        preferredStableUri = derivedUnit.getPreferredStableUri();
154
        if (derivedUnit.getCollection() != null){
155
            setCollectioDTO(CollectionDTO.fromCollection(HibernateProxyHelper.deproxy(derivedUnit.getCollection())));
156
            if(cleanAccessionNumber && getCollection().getCode() != null) {
157
                accessionNumber = accessionNumber.replaceFirst("^" + Pattern.quote(getCollection().getCode()) + "-", "");
158
            }
159
        }
160
        setBarcode(derivedUnit.getBarcode());
161
        setCatalogNumber(derivedUnit.getCatalogNumber());
162
        setDerivationEvent(DerivationEventDTO.fromEntity(derivedUnit.getDerivedFrom()));
163
        if (derivedUnit.getPreservation()!= null){
164
            setPreservationMethod(derivedUnit.getPreservation().getMaterialMethodText());
165
        }
166
        setRecordBase(derivedUnit.getRecordBasis());
167
        setSources(derivedUnit.getSources());
168
        setSpecimenTypeDesignations(derivedUnit.getSpecimenTypeDesignations());
169

    
170
        // -------------------------------------------------------------
171

    
172
        mostSignificantIdentifier = derivedUnit.getMostSignificantIdentifier();
173

    
174
        //specimenShortTitle
175
        setSpecimenShortTitle(composeSpecimenShortTitle(derivedUnit));
176

    
177

    
178
        //preferred stable URI
179
        setPreferredStableUri(derivedUnit.getPreferredStableUri());
180

    
181
        // label
182
        setSummaryLabel(derivedUnit.getTitleCache());
183

    
184
        // character state data
185
        if(derivedUnit.characterData() != null) {
186
            Collection<DescriptionElementBase> characterDataForSpecimen = derivedUnit.characterData();
187
            for (DescriptionElementBase descriptionElementBase : characterDataForSpecimen) {
188
                String character = descriptionElementBase.getFeature().getLabel();
189
                ArrayList<Language> languages = new ArrayList<>(Collections.singleton(Language.DEFAULT()));
190
                if (descriptionElementBase instanceof QuantitativeData) {
191
                    QuantitativeData quantitativeData = (QuantitativeData) descriptionElementBase;
192
                    DefaultQuantitativeDescriptionBuilder builder = new DefaultQuantitativeDescriptionBuilder();
193
                    String state = builder.build(quantitativeData, languages).getText(Language.DEFAULT());
194
                    addCharacterData(character, state);
195
                }
196
                else if(descriptionElementBase instanceof CategoricalData){
197
                    CategoricalData categoricalData = (CategoricalData) descriptionElementBase;
198
                    DefaultCategoricalDescriptionBuilder builder = new DefaultCategoricalDescriptionBuilder();
199
                    String state = builder.build(categoricalData, languages).getText(Language.DEFAULT());
200
                    addCharacterData(character, state);
201
                }
202
            }
203
        }
204

    
205
        // check type designations
206
        Collection<SpecimenTypeDesignation> specimenTypeDesignations = derivedUnit.getSpecimenTypeDesignations();
207
        for (SpecimenTypeDesignation specimenTypeDesignation : specimenTypeDesignations) {
208
            TypeDesignationStatusBase<?> typeStatus = specimenTypeDesignation.getTypeStatus();
209
            Set<TaxonName> typifiedNames = specimenTypeDesignation.getTypifiedNames();
210
            List<String> typedTaxaNames = new ArrayList<>();
211
            for (TaxonName taxonName : typifiedNames) {
212
                typedTaxaNames.add(taxonName.getTitleCache());
213
            }
214
            addTypes(typeStatus!=null?typeStatus.getLabel():"", typedTaxaNames);
215
        }
216
        Collection<OccurrenceStatus> occurrenceStatus = derivedUnit.getStatus();
217
        
218
        if (occurrenceStatus != null && !occurrenceStatus.isEmpty()) {
219
        	this.status = new ArrayList<>();
220
        
221
	        for (OccurrenceStatus specimenStatus : occurrenceStatus) {
222
	            DerivedUnitStatusDto dto = new DerivedUnitStatusDto(specimenStatus.getType().getLabel());
223
	            dto.setStatusSource(SourceDTO.fromDescriptionElementSource(specimenStatus.getSource()) ) ;
224
	            this.status.add(dto);
225
	        }
226
        }
227
        this.setDerivationTreeSummary(DerivationTreeSummaryDTO.fromEntity(derivedUnit, this.getSpecimenShortTitle()));
228
        
229
        
230
        if(derivedUnit.getStoredUnder() != null) {
231
            storedUnder = TypedEntityReference.fromEntity(derivedUnit.getStoredUnder());
232
        }
233
        originalLabelInfo = derivedUnit.getOriginalLabelInfo();
234
        exsiccatum = derivedUnit.getExsiccatum();
235

    
236
    }
237

    
238
    protected String composeSpecimenShortTitle(DerivedUnit derivedUnit) {
239
        FormatKey collectionKey = FormatKey.COLLECTION_CODE;
240
        String specimenShortTitle = CdmFormatterFactory.format(derivedUnit, collectionKey);
241
        if (CdmUtils.isBlank(specimenShortTitle)) {
242
            collectionKey = FormatKey.COLLECTION_NAME;
243
        }
244
        if(CdmUtils.isNotBlank(derivedUnit.getMostSignificantIdentifier())){
245
            specimenShortTitle = CdmFormatterFactory.format(derivedUnit, new FormatKey[] {
246
                    collectionKey,
247
                    FormatKey.SPACE,
248
                    FormatKey.MOST_SIGNIFICANT_IDENTIFIER
249
                    });
250
            if(!specimenShortTitle.isEmpty() && derivedUnit instanceof MediaSpecimen) {
251
                Media media = ((MediaSpecimen)derivedUnit).getMediaSpecimen();
252
                if(media != null && !CdmUtils.isBlank(media.getTitleCache()) ) {
253
                    if(media.getTitle() != null && !media.getTitle().getText().isEmpty()) {
254
                        specimenShortTitle += " (" + media.getTitle().getText() + ")";
255
                    }
256
                }
257
            }
258
        }
259
        if(CdmUtils.isBlank(specimenShortTitle)){
260
            specimenShortTitle = derivedUnit.getTitleCache();
261
        }
262
        if(CdmUtils.isBlank(specimenShortTitle)){  //should not be necessary as titleCache should never be empty
263
            specimenShortTitle = derivedUnit.getUuid().toString();
264
        }
265
        return specimenShortTitle;
266
    }
267

    
268
    @Override
269
    protected Set<Media> collectMedia(SpecimenOrObservationBase<?> specimenOrObservation){
270
        Set<Media> collectedMedia = super.collectMedia(specimenOrObservation);
271
        if(specimenOrObservation instanceof MediaSpecimen) {
272
            if(((MediaSpecimen)specimenOrObservation).getMediaSpecimen() != null) {
273
            collectedMedia.add(((MediaSpecimen)specimenOrObservation).getMediaSpecimen());
274
            }
275
        }
276
        return collectedMedia;
277
    }
278

    
279

    
280
    public String getAccessionNumber() {
281
        return accessionNumber;
282
    }
283
    public void setAccessionNumber(String accessionNumber) {
284
        this.accessionNumber = accessionNumber;
285
    }
286

    
287
    public Map<String, List<String>> getTypes() {
288
        return types;
289
    }
290
    public void addTypes(String typeStatus, List<String> typedTaxa){
291
        if(types==null){
292
            types = new HashMap<>();
293
        }
294
        types.put(typeStatus, typedTaxa);
295
    }
296

    
297
    public List<TypedEntityReference<Taxon>> getAssociatedTaxa() {
298
        return associatedTaxa;
299
    }
300
    public void addAssociatedTaxon(Taxon taxon){
301
        if(associatedTaxa==null){
302
            associatedTaxa = new ArrayList<>();
303
        }
304
        associatedTaxa.add(TypedEntityReference.fromEntity(taxon));
305
    }
306

    
307
    public void setPreferredStableUri(URI preferredStableUri) {
308
        this.preferredStableUri = preferredStableUri;
309
    }
310
    public URI getPreferredStableUri() {
311
        return preferredStableUri;
312
    }
313

    
314
    public String getSpecimenShortTitle() {
315
        return specimenShortTitle;
316
    }
317
    public void setSpecimenShortTitle(String specimenIdentifier) {
318
        this.specimenShortTitle = specimenIdentifier;
319
    }
320

    
321
    public String getMostSignificantIdentifier() {
322
        return mostSignificantIdentifier;
323
    }
324
    public void setMostSignificantIdentifier(String mostSignificantIdentifier) {
325
        this.mostSignificantIdentifier = mostSignificantIdentifier;
326
    }
327

    
328
    public TypedEntityReference<TaxonName> getStoredUnder() {
329
        return storedUnder;
330
    }
331
    public void setStoredUnder(TypedEntityReference<TaxonName> storedUnder) {
332
        this.storedUnder = storedUnder;
333
    }
334

    
335
    public String getOriginalLabelInfo() {
336
        return originalLabelInfo;
337
    }
338
    public void setOriginalLabelInfo(String originalLabelInfo) {
339
        this.originalLabelInfo = originalLabelInfo;
340
    }
341

    
342
    public String getExsiccatum() {
343
        return exsiccatum;
344
    }
345
    public void setExsiccatum(String exsiccatum) {
346
        this.exsiccatum = exsiccatum;
347
    }
348

    
349
    public String getCatalogNumber() {
350
        return catalogNumber;
351
    }
352
    public void setCatalogNumber(String catalogNumber) {
353
        this.catalogNumber = catalogNumber;
354
    }
355

    
356
    public String getBarcode() {
357
        return barcode;
358
    }
359
    public void setBarcode(String barcode) {
360
        this.barcode = barcode;
361
    }
362

    
363
    public String getPreservationMethod() {
364
        return preservationMethod;
365
    }
366
    public void setPreservationMethod(String preservationMethod) {
367
        this.preservationMethod = preservationMethod;
368
    }
369

    
370
    public CollectionDTO getCollection() {
371
        return collection;
372
    }
373
    public void setCollectioDTO(CollectionDTO collection) {
374
        this.collection = collection;
375
    }
376

    
377
    public List<DerivedUnitStatusDto> getStatus() {
378
		return status;
379
	}
380

    
381
	public void setStatus(List<DerivedUnitStatusDto> status) {
382
		this.status = status;
383
	}
384

    
385
	@Override
386
    protected void updateTreeDependantData(Set<DerivedUnitDTO> derivatives) {
387
		for (DerivedUnitDTO derivative: derivatives) {
388
			this.setHasDna(this.isHasDna() || derivative.isHasDna() || !derivative.getDerivationTreeSummary().getMolecularDataList().isEmpty());
389
			this.setHasDetailImage(this.isHasDetailImage() || derivative.isHasDetailImage() || !derivative.getDerivationTreeSummary().getDetailImages().isEmpty());
390
			this.setHasSpecimenScan(isHasSpecimenScan()|| derivative.isHasSpecimenScan());
391
			this.setHasCharacterData(isHasCharacterData()||derivative.isHasCharacterData());
392
		}
393
		
394
        // TODO DerivationTreeSummaryDTO should be updated here once it is refactored so that it can operate on dtos
395
    }
396
}
(10-10/47)