Project

General

Profile

Download (11.2 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.io.dwca.out;
11

    
12
import java.io.FileNotFoundException;
13
import java.io.IOException;
14
import java.io.PrintWriter;
15
import java.io.UnsupportedEncodingException;
16
import java.util.HashSet;
17
import java.util.List;
18
import java.util.Set;
19
import java.util.UUID;
20

    
21
import org.apache.log4j.Logger;
22
import org.springframework.stereotype.Component;
23
import org.springframework.transaction.TransactionStatus;
24

    
25
import eu.etaxonomy.cdm.api.facade.DerivedUnitFacade;
26
import eu.etaxonomy.cdm.api.facade.DerivedUnitFacadeNotSupportedException;
27
import eu.etaxonomy.cdm.io.common.ExportDataWrapper;
28
import eu.etaxonomy.cdm.model.common.CdmBase;
29
import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
30
import eu.etaxonomy.cdm.model.description.IndividualsAssociation;
31
import eu.etaxonomy.cdm.model.description.TaxonDescription;
32
import eu.etaxonomy.cdm.model.name.INonViralName;
33
import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignation;
34
import eu.etaxonomy.cdm.model.name.TaxonName;
35
import eu.etaxonomy.cdm.model.name.TypeDesignationBase;
36
import eu.etaxonomy.cdm.model.name.TypeDesignationStatusBase;
37
import eu.etaxonomy.cdm.model.occurrence.Collection;
38
import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
39
import eu.etaxonomy.cdm.model.occurrence.DeterminationEvent;
40
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
41
import eu.etaxonomy.cdm.model.taxon.Classification;
42
import eu.etaxonomy.cdm.model.taxon.Synonym;
43
import eu.etaxonomy.cdm.model.taxon.Taxon;
44
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
45
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
46

    
47
/**
48
 * @author a.mueller
49
 * @created 20.04.2011
50
 */
51
@Component
52
public class DwcaTypesExport extends DwcaExportBase {
53
	private static final Logger logger = Logger.getLogger(DwcaTypesExport.class);
54

    
55
	private static final String ROW_TYPE = "http://rs.gbif.org/terms/1.0/TypesAndSpecimen";
56
	private static final String fileName = "typesAndSpecimen.txt";
57

    
58
	/**
59
	 * Constructor
60
	 */
61
	public DwcaTypesExport() {
62
		super();
63
		this.ioName = this.getClass().getSimpleName();
64
		this.exportData = ExportDataWrapper.NewByteArrayInstance();
65
	}
66

    
67
	/** Retrieves data from a CDM DB and serializes them CDM to XML.
68
	 * Starts with root taxa and traverses the classification to retrieve children taxa, synonyms and relationships.
69
	 * Taxa that are not part of the classification are not found.
70
	 *
71
	 * @param exImpConfig
72
	 * @param dbname
73
	 * @param filename
74
	 */
75
	@Override
76
	protected void doInvoke(DwcaTaxExportState state){
77
		DwcaTaxExportConfigurator config = state.getConfig();
78
		TransactionStatus txStatus = startTransaction(true);
79

    
80
		PrintWriter writer = null;
81
		try {
82

    
83
			writer = createPrintWriter(fileName, state);
84
			DwcaMetaDataRecord metaRecord = new DwcaMetaDataRecord(! IS_CORE, fileName, ROW_TYPE);
85
			state.addMetaRecord(metaRecord);
86

    
87

    
88
			Set<UUID> classificationUuidSet = config.getClassificationUuids();
89
            List<Classification> classificationList;
90
            if (classificationUuidSet.isEmpty()){
91
                classificationList = getClassificationService().list(Classification.class, null, 0, null, null);
92
            }else{
93
                classificationList = getClassificationService().find(classificationUuidSet);
94
            }
95

    
96
            Set<Classification> classificationSet = new HashSet<Classification>();
97
            classificationSet.addAll(classificationList);
98
            List<TaxonNode> allNodes;
99

    
100
            if (state.getAllNodes().isEmpty()){
101
                getAllNodes(state, classificationSet);
102
            }
103
            allNodes = state.getAllNodes();
104

    
105
			for (TaxonNode node : allNodes){
106
				Taxon taxon = CdmBase.deproxy(node.getTaxon(), Taxon.class);
107

    
108
				//TODO use API methods to retrieve all related specimen
109

    
110
				//individual associations
111
				Set<TaxonDescription> descriptions = taxon.getDescriptions();
112
				for (TaxonDescription description : descriptions){
113
					for (DescriptionElementBase el : description.getElements()){
114
						if (el.isInstanceOf(IndividualsAssociation.class)){
115
							DwcaTypesRecord record = new DwcaTypesRecord(metaRecord, config);
116
							IndividualsAssociation individualAssociation = CdmBase.deproxy(el,IndividualsAssociation.class);
117
							if (! this.recordExistsUuid(individualAssociation) && handleSpecimen(record, individualAssociation, null, taxon, config)){
118
								record.write(writer);
119
								this.addExistingRecordUuid(individualAssociation);
120
							}
121
						}
122
					}
123
				}
124

    
125
				//type specimen
126
				INonViralName nvn = taxon.getName();
127
				handleTypeName(writer, taxon, nvn, metaRecord, config);
128
				for (Synonym synonym : taxon.getSynonyms()){
129
					handleTypeName(writer, synonym, nvn, metaRecord, config);
130
				}
131

    
132
				//FIXME
133
				//Determinations
134

    
135

    
136
				writer.flush();
137

    
138
			}
139
		} catch (FileNotFoundException e) {
140
			e.printStackTrace();
141
		} catch (UnsupportedEncodingException e) {
142
			e.printStackTrace();
143
		} catch (ClassCastException e) {
144
			e.printStackTrace();
145
		} catch (IOException e) {
146
			e.printStackTrace();
147
		} finally{
148
			closeWriter(writer, state);
149
		}
150
		commitTransaction(txStatus);
151
		return;
152
	}
153

    
154
	/**
155
	 * @param writer
156
	 * @param taxon
157
	 * @param nvn
158
	 * @param config
159
	 * @return
160
	 */
161
	private Set<TypeDesignationBase> handleTypeName(PrintWriter writer, TaxonBase<?> taxonBase,
162
	        INonViralName nvn, DwcaMetaDataRecord metaRecord, DwcaTaxExportConfigurator config) {
163
		Set<TypeDesignationBase> designations = nvn.getTypeDesignations();
164
		for (TypeDesignationBase<?> designation:designations){
165
			DwcaTypesRecord record = new DwcaTypesRecord(metaRecord, config);
166
			if (! this.recordExistsUuid(designation) && handleSpecimen(record, null, designation, taxonBase, config)){
167
				record.write(writer);
168
				addExistingRecordUuid(designation);
169
			}
170
		}
171
		return designations;
172
	}
173

    
174

    
175
	private boolean handleSpecimen(DwcaTypesRecord record, IndividualsAssociation individualsAssociation, TypeDesignationBase<?> designation, TaxonBase<?> taxonBase, DwcaTaxExportConfigurator config) {
176
		TypeDesignationStatusBase<?> status = null;
177
		DerivedUnitFacade facade = null;
178
		if (individualsAssociation != null){
179
			facade = getFacadeFromAssociation(individualsAssociation);
180
		}else if (designation != null){
181
			facade = getFacadeFromDesignation(designation);
182
			status = designation.getTypeStatus();
183
		}
184
		if (facade == null){
185
			return false;
186
		}
187

    
188
		record.setId(taxonBase.getId());
189
		record.setUuid(taxonBase.getUuid());
190
		record.setBibliographicCitation(facade.getTitleCache());
191
		record.setTypeStatus(status);
192
		record.setTypeDesignatedBy( (designation == null || designation.getCitation()==null)? null: designation.getCitation().getTitleCache());
193

    
194
		TaxonName scientificName = getScientificName(facade);
195
		if (scientificName != null){
196
			record.setScientificName(scientificName.getTitleCache());
197
			record.setTaxonRank(scientificName.getRank());
198
		}
199

    
200
		record.setOccurrenceId(facade.innerDerivedUnit());
201
		Collection collection = facade.getCollection();
202
		if (collection != null){
203
			record.setCollectionCode(collection.getCode());
204
			if (collection.getInstitute() != null){
205
				record.setInstitutionCode(collection.getInstitute().getCode());
206
			}
207
		}
208
		record.setCatalogNumber(facade.getCatalogNumber());
209
		record.setLocality(facade.getLocalityText());
210
		record.setSex(facade.getSex());
211
		record.setRecordedBy(facade.getCollector());
212
		//TODO ???
213

    
214
		String source2 = "";
215
		if (individualsAssociation!=null) {
216
            source2 = getSources2(individualsAssociation.getSources(), config);
217
        }
218

    
219
		record.setSource(getSources3(facade.innerDerivedUnit(), config));
220
		record.setDescriptionSource(source2);
221

    
222
		record.setEventDate(facade.getGatheringPeriod());
223
		//TODO missing
224
		record.setVerbatimLabel(null);
225
		if (facade.getExactLocation() != null){
226
			if (facade.getExactLocation().getLongitude() != null){
227
//				record.setVerbatimLongitude(facade.getExactLocation().getLongitudeSexagesimal().toString());
228
			    record.setVerbatimLongitude(facade.getExactLocation().getLongitude().toString());
229
			}
230
			if (facade.getExactLocation().getLatitude() != null){
231
//				record.setVerbatimLatitude(facade.getExactLocation().getLatitudeSexagesimal().toString());
232
			    record.setVerbatimLatitude(facade.getExactLocation().getLatitude().toString());
233
			}
234
			if(facade.getExactLocation().getErrorRadius() != null) {
235
                record.setCoordinatesPrecisionOrError(facade.getExactLocation().getErrorRadius().toString());
236
            }
237
			if(facade.getExactLocation().getReferenceSystem() != null) {
238
                record.setCoordinatesSystem(facade.getExactLocation().getReferenceSystem().toString());
239
            }
240
		}
241
		return true;
242
	}
243

    
244
	private TaxonName<?,?> getScientificName(DerivedUnitFacade facade) {
245
		Set<DeterminationEvent> detEvents = facade.getDeterminations();
246
		for (DeterminationEvent detEvent : detEvents){
247
			if (detEvent.getPreferredFlag()== true || detEvents.size()==1){
248
				return detEvent.getTaxon().getName();
249
			}
250
		}
251
		return null;
252
	}
253

    
254
	private DerivedUnitFacade getFacadeFromDesignation(TypeDesignationBase<?> designation) {
255
		if (designation.isInstanceOf(SpecimenTypeDesignation.class)){
256
			SpecimenTypeDesignation specDesig = CdmBase.deproxy(designation, SpecimenTypeDesignation.class);
257
			try {
258
				DerivedUnit derivedUnit = specDesig.getTypeSpecimen();
259
				if (derivedUnit == null){
260
					return null;
261
				}else{
262
					DerivedUnitFacade facade = DerivedUnitFacade.NewInstance(derivedUnit);
263
					return facade;
264
				}
265
			} catch (DerivedUnitFacadeNotSupportedException e) {
266
				String message = "DerivedUnit is too complex to be handled by facade based darwin core archive export";
267
				logger.warn(message);
268
				//TODO handle empty records
269
				return null;
270
			}
271
		}else{
272
			return null;
273
		}
274
	}
275

    
276
	private DerivedUnitFacade getFacadeFromAssociation(IndividualsAssociation individualsAssociation) {
277
		SpecimenOrObservationBase<?> specimen = individualsAssociation.getAssociatedSpecimenOrObservation();
278
		DerivedUnitFacade facade;
279
		if (! specimen.isInstanceOf(DerivedUnit.class)){
280
			String message = "Non DerivedUnit specimen can not yet be handled by this export";
281
			logger.warn(message);
282
			//TODO handle empty records
283
			return null;
284
		}else{
285
			DerivedUnit derivedUnit = CdmBase.deproxy(specimen, DerivedUnit.class);
286
			try {
287
				facade = DerivedUnitFacade.NewInstance(derivedUnit);
288
			} catch (DerivedUnitFacadeNotSupportedException e) {
289
				String message = "DerivedUnit is too complex to be handled by facade based darwin core archive export";
290
				logger.warn(message);
291
				//TODO handle empty records
292
				return null;
293
			}
294

    
295
		}
296
		return facade;
297
	}
298

    
299
	@Override
300
	protected boolean doCheck(DwcaTaxExportState state) {
301
		boolean result = true;
302
		logger.warn("No check implemented for " + this.ioName);
303
		return result;
304
	}
305

    
306

    
307
	@Override
308
	protected boolean isIgnore(DwcaTaxExportState state) {
309
		return ! state.getConfig().isDoTypesAndSpecimen();
310
	}
311

    
312

    
313
}
(23-23/29)