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.HashMap;
|
15
|
import java.util.List;
|
16
|
import java.util.Map;
|
17
|
import java.util.Set;
|
18
|
import java.util.regex.Pattern;
|
19
|
|
20
|
import eu.etaxonomy.cdm.common.CdmUtils;
|
21
|
import eu.etaxonomy.cdm.common.URI;
|
22
|
import eu.etaxonomy.cdm.format.CdmFormatterFactory;
|
23
|
import eu.etaxonomy.cdm.format.ICdmFormatter.FormatKey;
|
24
|
import eu.etaxonomy.cdm.format.description.DefaultCategoricalDescriptionBuilder;
|
25
|
import eu.etaxonomy.cdm.format.description.DefaultQuantitativeDescriptionBuilder;
|
26
|
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
|
27
|
import eu.etaxonomy.cdm.model.common.Language;
|
28
|
import eu.etaxonomy.cdm.model.description.CategoricalData;
|
29
|
import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
|
30
|
import eu.etaxonomy.cdm.model.description.IndividualsAssociation;
|
31
|
import eu.etaxonomy.cdm.model.description.QuantitativeData;
|
32
|
import eu.etaxonomy.cdm.model.description.TaxonDescription;
|
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.DerivationEvent;
|
38
|
import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
|
39
|
import eu.etaxonomy.cdm.model.occurrence.DeterminationEvent;
|
40
|
import eu.etaxonomy.cdm.model.occurrence.FieldUnit;
|
41
|
import eu.etaxonomy.cdm.model.occurrence.MediaSpecimen;
|
42
|
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
|
43
|
import eu.etaxonomy.cdm.model.taxon.Taxon;
|
44
|
import eu.etaxonomy.cdm.ref.TypedEntityReference;
|
45
|
|
46
|
/**
|
47
|
* @author pplitzner
|
48
|
* @since Mar 26, 2015
|
49
|
*/
|
50
|
public class DerivedUnitDTO extends SpecimenOrObservationBaseDTO{
|
51
|
|
52
|
private static final long serialVersionUID = 2345864166579381295L;
|
53
|
|
54
|
private String accessionNumber;
|
55
|
private String specimenIdentifier;
|
56
|
private TypedEntityReference<TaxonName> storedUnder;
|
57
|
private URI preferredStableUri;
|
58
|
|
59
|
private List<TypedEntityReference<Taxon>> associatedTaxa;
|
60
|
private Map<String, List<String>> types;
|
61
|
|
62
|
private List<TypedEntityReference<TaxonName>> determinedNames;
|
63
|
|
64
|
private String originalLabelInfo;
|
65
|
private String exsiccatum;
|
66
|
private String mostSignificantIdentifier;
|
67
|
|
68
|
/**
|
69
|
* Constructs a new DerivedUnitDTO. All derivatives of the passed <code>DerivedUnit entity</code> will be collected and
|
70
|
* added as DerivedUnitDTO to the {@link SpecimenOrObservationBaseDTO#getDerivatives() derivative DTOs}.
|
71
|
*
|
72
|
* @param entity
|
73
|
* The entity to create the dto for
|
74
|
*
|
75
|
* @return <code>null</code> or the new DerivedUnitDTO
|
76
|
*/
|
77
|
public static DerivedUnitDTO fromEntity(DerivedUnit entity){
|
78
|
return fromEntity(entity, null);
|
79
|
}
|
80
|
/**
|
81
|
* @param entity
|
82
|
* The entity to create the dto for
|
83
|
* @param individualsAssociations
|
84
|
* <b>WARNING</b> This parameter will be removed in future versions. IndividualsAssociation should better be retrieved in a separate
|
85
|
* action, since individualsAssociations are not accessible from the DerivedUnit side. A service level method call is needed to
|
86
|
* retrieve them, so it would be required to access the OccurrenceServiceImpl from inside of this DTO factory method, which is
|
87
|
* bad OO design. The other option is implemented here, requires all calling Objects to pass the IndividualsAssociations as parameter.
|
88
|
* @return <code>null</code> or the new DerivedUnitDTO
|
89
|
* @deprecated see comment on the parameter <code>individualsAssociations</code>
|
90
|
*/
|
91
|
@Deprecated
|
92
|
public static DerivedUnitDTO fromEntity(DerivedUnit entity, Collection<IndividualsAssociation> individualsAssociations){
|
93
|
if(entity == null) {
|
94
|
return null;
|
95
|
}
|
96
|
DerivedUnitDTO dto = new DerivedUnitDTO(entity);
|
97
|
|
98
|
// individuals associations
|
99
|
if(individualsAssociations != null) {
|
100
|
for (IndividualsAssociation individualsAssociation : individualsAssociations) {
|
101
|
if (individualsAssociation.getInDescription() != null) {
|
102
|
if (individualsAssociation.getInDescription().isInstanceOf(TaxonDescription.class)) {
|
103
|
TaxonDescription taxonDescription = HibernateProxyHelper.deproxy(individualsAssociation.getInDescription(), TaxonDescription.class);
|
104
|
Taxon taxon = taxonDescription.getTaxon();
|
105
|
if (taxon != null) {
|
106
|
dto.addAssociatedTaxon(taxon);
|
107
|
}
|
108
|
}
|
109
|
}
|
110
|
}
|
111
|
}
|
112
|
return dto;
|
113
|
}
|
114
|
|
115
|
|
116
|
/**
|
117
|
* @param derivedUnit
|
118
|
*/
|
119
|
public DerivedUnitDTO(DerivedUnit derivedUnit) {
|
120
|
super(derivedUnit);
|
121
|
// experimental feature, not yet exposed in method signature
|
122
|
boolean cleanAccessionNumber = false;
|
123
|
accessionNumber = derivedUnit.getAccessionNumber();
|
124
|
preferredStableUri = derivedUnit.getPreferredStableUri();
|
125
|
if (derivedUnit.getCollection() != null){
|
126
|
setCollectioDTo(new CollectionDTO(HibernateProxyHelper.deproxy(derivedUnit.getCollection())));
|
127
|
if(cleanAccessionNumber && getCollection().getCode() != null) {
|
128
|
accessionNumber = accessionNumber.replaceFirst("^" + Pattern.quote(getCollection().getCode()) + "-", "");
|
129
|
}
|
130
|
}
|
131
|
setBarcode(derivedUnit.getBarcode());
|
132
|
setCatalogNumber(derivedUnit.getCatalogNumber());
|
133
|
setCollectorsNumber(derivedUnit.getCollectorsNumber());
|
134
|
if (derivedUnit.getDerivedFrom() != null){
|
135
|
setDerivationEvent(new DerivationEventDTO(HibernateProxyHelper.deproxy(derivedUnit.getDerivedFrom(), DerivationEvent.class )));
|
136
|
}
|
137
|
if (derivedUnit.getPreservation()!= null){
|
138
|
setPreservationMethod(derivedUnit.getPreservation().getMaterialMethodText());
|
139
|
}
|
140
|
setRecordBase(derivedUnit.getRecordBasis());
|
141
|
setSources(derivedUnit.getSources());
|
142
|
setSpecimenTypeDesignations(derivedUnit.getSpecimenTypeDesignations());
|
143
|
addDeterminedNames(derivedUnit.getDeterminations());
|
144
|
|
145
|
// -------------------------------------------------------------
|
146
|
|
147
|
mostSignificantIdentifier = derivedUnit.getMostSignificantIdentifier();
|
148
|
|
149
|
//specimen identifier
|
150
|
FormatKey collectionKey = FormatKey.COLLECTION_CODE;
|
151
|
String specimenIdentifier = CdmFormatterFactory.format(derivedUnit, collectionKey);
|
152
|
if (CdmUtils.isBlank(specimenIdentifier)) {
|
153
|
collectionKey = FormatKey.COLLECTION_NAME;
|
154
|
}
|
155
|
if(CdmUtils.isNotBlank(derivedUnit.getMostSignificantIdentifier())){
|
156
|
specimenIdentifier = CdmFormatterFactory.format(derivedUnit, new FormatKey[] {
|
157
|
collectionKey, FormatKey.SPACE, FormatKey.OPEN_BRACKET,
|
158
|
FormatKey.MOST_SIGNIFICANT_IDENTIFIER, FormatKey.CLOSE_BRACKET });
|
159
|
}
|
160
|
if(CdmUtils.isBlank(specimenIdentifier)){
|
161
|
specimenIdentifier = derivedUnit.getTitleCache();
|
162
|
}
|
163
|
if(CdmUtils.isBlank(specimenIdentifier)){
|
164
|
specimenIdentifier = derivedUnit.getUuid().toString();
|
165
|
}
|
166
|
setSpecimenIdentifier(specimenIdentifier);
|
167
|
|
168
|
|
169
|
//preferred stable URI
|
170
|
setPreferredStableUri(derivedUnit.getPreferredStableUri());
|
171
|
|
172
|
// citation
|
173
|
Collection<FieldUnit> fieldUnits = derivedUnit.collectFieldUnits();
|
174
|
if (fieldUnits.size() == 1) {
|
175
|
setCitation(fieldUnits.iterator().next().getTitleCache());
|
176
|
}
|
177
|
else{
|
178
|
setCitation("No Citation available. This specimen either has no or multiple field units.");
|
179
|
}
|
180
|
|
181
|
// character state data
|
182
|
if(derivedUnit.characterData() != null) {
|
183
|
Collection<DescriptionElementBase> characterDataForSpecimen = derivedUnit.characterData();
|
184
|
for (DescriptionElementBase descriptionElementBase : characterDataForSpecimen) {
|
185
|
String character = descriptionElementBase.getFeature().getLabel();
|
186
|
ArrayList<Language> languages = new ArrayList<>(Collections.singleton(Language.DEFAULT()));
|
187
|
if (descriptionElementBase instanceof QuantitativeData) {
|
188
|
QuantitativeData quantitativeData = (QuantitativeData) descriptionElementBase;
|
189
|
DefaultQuantitativeDescriptionBuilder builder = new DefaultQuantitativeDescriptionBuilder();
|
190
|
String state = builder.build(quantitativeData, languages).getText(Language.DEFAULT());
|
191
|
addCharacterData(character, state);
|
192
|
}
|
193
|
else if(descriptionElementBase instanceof CategoricalData){
|
194
|
CategoricalData categoricalData = (CategoricalData) descriptionElementBase;
|
195
|
DefaultCategoricalDescriptionBuilder builder = new DefaultCategoricalDescriptionBuilder();
|
196
|
String state = builder.build(categoricalData, languages).getText(Language.DEFAULT());
|
197
|
addCharacterData(character, state);
|
198
|
}
|
199
|
}
|
200
|
}
|
201
|
// check type designations
|
202
|
Collection<SpecimenTypeDesignation> specimenTypeDesignations = derivedUnit.getSpecimenTypeDesignations();
|
203
|
for (SpecimenTypeDesignation specimenTypeDesignation : specimenTypeDesignations) {
|
204
|
TypeDesignationStatusBase<?> typeStatus = specimenTypeDesignation.getTypeStatus();
|
205
|
Set<TaxonName> typifiedNames = specimenTypeDesignation.getTypifiedNames();
|
206
|
List<String> typedTaxaNames = new ArrayList<>();
|
207
|
for (TaxonName taxonName : typifiedNames) {
|
208
|
typedTaxaNames.add(taxonName.getTitleCache());
|
209
|
}
|
210
|
addTypes(typeStatus!=null?typeStatus.getLabel():"", typedTaxaNames);
|
211
|
}
|
212
|
|
213
|
// assemble sub derivatives
|
214
|
setDerivateDataDTO(DerivateDataDTO.fromEntity(derivedUnit, getSpecimenIdentifier()));
|
215
|
|
216
|
if(derivedUnit.getStoredUnder() != null) {
|
217
|
storedUnder = TypedEntityReference.fromEntity(derivedUnit.getStoredUnder());
|
218
|
}
|
219
|
originalLabelInfo = derivedUnit.getOriginalLabelInfo();
|
220
|
exsiccatum = derivedUnit.getExsiccatum();
|
221
|
|
222
|
}
|
223
|
|
224
|
@Override
|
225
|
protected Set<Media> collectMedia(SpecimenOrObservationBase<?> specimenOrObservation){
|
226
|
Set<Media> collectedMedia = super.collectMedia(specimenOrObservation);
|
227
|
if(specimenOrObservation instanceof MediaSpecimen) {
|
228
|
if(((MediaSpecimen)specimenOrObservation).getMediaSpecimen() != null) {
|
229
|
collectedMedia.add(((MediaSpecimen)specimenOrObservation).getMediaSpecimen());
|
230
|
}
|
231
|
}
|
232
|
return collectedMedia;
|
233
|
}
|
234
|
|
235
|
|
236
|
public String getAccessionNumber() {
|
237
|
return accessionNumber;
|
238
|
}
|
239
|
public void setAccessionNumber(String accessionNumber) {
|
240
|
this.accessionNumber = accessionNumber;
|
241
|
}
|
242
|
|
243
|
public Map<String, List<String>> getTypes() {
|
244
|
return types;
|
245
|
}
|
246
|
public void addTypes(String typeStatus, List<String> typedTaxa){
|
247
|
if(types==null){
|
248
|
types = new HashMap<String, List<String>>();
|
249
|
}
|
250
|
types.put(typeStatus, typedTaxa);
|
251
|
}
|
252
|
|
253
|
public List<TypedEntityReference<Taxon>> getAssociatedTaxa() {
|
254
|
return associatedTaxa;
|
255
|
}
|
256
|
public void addAssociatedTaxon(Taxon taxon){
|
257
|
if(associatedTaxa==null){
|
258
|
associatedTaxa = new ArrayList<>();
|
259
|
}
|
260
|
associatedTaxa.add(TypedEntityReference.fromEntity(taxon));
|
261
|
}
|
262
|
|
263
|
public List<TypedEntityReference<TaxonName>> getDeterminedNames() {
|
264
|
return determinedNames;
|
265
|
}
|
266
|
public void addDeterminedNames(Set<DeterminationEvent> determinations){
|
267
|
if(determinedNames==null){
|
268
|
determinedNames = new ArrayList<>();
|
269
|
}
|
270
|
TaxonName preferredName = null;
|
271
|
for (DeterminationEvent event:determinations){
|
272
|
if (event.getPreferredFlag()){
|
273
|
preferredName = event.getTaxonName();
|
274
|
}
|
275
|
}
|
276
|
if (preferredName != null){
|
277
|
determinedNames.add(TypedEntityReference.fromEntity(preferredName));
|
278
|
}else{
|
279
|
for (DeterminationEvent event:determinations){
|
280
|
determinedNames.add(TypedEntityReference.fromEntity(event.getTaxonName()));
|
281
|
}
|
282
|
}
|
283
|
}
|
284
|
|
285
|
public void setPreferredStableUri(URI preferredStableUri) {
|
286
|
this.preferredStableUri = preferredStableUri;
|
287
|
}
|
288
|
|
289
|
public URI getPreferredStableUri() {
|
290
|
return preferredStableUri;
|
291
|
}
|
292
|
public String getSpecimenIdentifier() {
|
293
|
return specimenIdentifier;
|
294
|
}
|
295
|
public void setSpecimenIdentifier(String specimenIdentifier) {
|
296
|
this.specimenIdentifier = specimenIdentifier;
|
297
|
}
|
298
|
public String getMostSignificantIdentifier() {
|
299
|
return mostSignificantIdentifier;
|
300
|
}
|
301
|
public void setMostSignificantIdentifier(String mostSignificantIdentifier) {
|
302
|
this.mostSignificantIdentifier = mostSignificantIdentifier;
|
303
|
}
|
304
|
public TypedEntityReference<TaxonName> getStoredUnder() {
|
305
|
return storedUnder;
|
306
|
}
|
307
|
public void setStoredUnder(TypedEntityReference<TaxonName> storedUnder) {
|
308
|
this.storedUnder = storedUnder;
|
309
|
}
|
310
|
|
311
|
public String getOriginalLabelInfo() {
|
312
|
return originalLabelInfo;
|
313
|
}
|
314
|
public void setOriginalLabelInfo(String originalLabelInfo) {
|
315
|
this.originalLabelInfo = originalLabelInfo;
|
316
|
}
|
317
|
public String getExsiccatum() {
|
318
|
return exsiccatum;
|
319
|
}
|
320
|
public void setExsiccatum(String exsiccatum) {
|
321
|
this.exsiccatum = exsiccatum;
|
322
|
}
|
323
|
|
324
|
}
|