Remove OriginalNameID from DwcA Export
[cdmlib.git] / cdmlib-io / src / main / java / eu / etaxonomy / cdm / io / dwca / out / DwcaTypesExport.java
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.List;
17 import java.util.Set;
18
19 import org.apache.log4j.Logger;
20 import org.springframework.stereotype.Component;
21 import org.springframework.transaction.TransactionStatus;
22
23 import eu.etaxonomy.cdm.api.facade.DerivedUnitFacade;
24 import eu.etaxonomy.cdm.api.facade.DerivedUnitFacadeNotSupportedException;
25 import eu.etaxonomy.cdm.model.common.CdmBase;
26 import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
27 import eu.etaxonomy.cdm.model.description.IndividualsAssociation;
28 import eu.etaxonomy.cdm.model.description.TaxonDescription;
29 import eu.etaxonomy.cdm.model.name.NonViralName;
30 import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignation;
31 import eu.etaxonomy.cdm.model.name.TaxonNameBase;
32 import eu.etaxonomy.cdm.model.name.TypeDesignationBase;
33 import eu.etaxonomy.cdm.model.name.TypeDesignationStatusBase;
34 import eu.etaxonomy.cdm.model.occurrence.Collection;
35 import eu.etaxonomy.cdm.model.occurrence.DerivedUnitBase;
36 import eu.etaxonomy.cdm.model.occurrence.DeterminationEvent;
37 import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
38 import eu.etaxonomy.cdm.model.taxon.Synonym;
39 import eu.etaxonomy.cdm.model.taxon.Taxon;
40 import eu.etaxonomy.cdm.model.taxon.TaxonBase;
41 import eu.etaxonomy.cdm.model.taxon.TaxonNode;
42
43 /**
44 * @author a.mueller
45 * @created 20.04.2011
46 */
47 @Component
48 public class DwcaTypesExport extends DwcaExportBase {
49 private static final Logger logger = Logger.getLogger(DwcaTypesExport.class);
50
51 private static final String ROW_TYPE = "http://rs.gbif.org/terms/1.0/TypesAndSpecimen";
52 private static final String fileName = "typesAndSpecimen.txt";
53
54 /**
55 * Constructor
56 */
57 public DwcaTypesExport() {
58 super();
59 this.ioName = this.getClass().getSimpleName();
60 }
61
62 /** Retrieves data from a CDM DB and serializes them CDM to XML.
63 * Starts with root taxa and traverses the classification to retrieve children taxa, synonyms and relationships.
64 * Taxa that are not part of the classification are not found.
65 *
66 * @param exImpConfig
67 * @param dbname
68 * @param filename
69 */
70 @Override
71 protected boolean doInvoke(DwcaTaxExportState state){
72 DwcaTaxExportConfigurator config = state.getConfig();
73 TransactionStatus txStatus = startTransaction(true);
74
75 PrintWriter writer = null;
76 try {
77
78 writer = createPrintWriter(fileName, state);
79 DwcaMetaDataRecord metaRecord = new DwcaMetaDataRecord(! IS_CORE, fileName, ROW_TYPE);
80 state.addMetaRecord(metaRecord);
81
82
83 List<TaxonNode> allNodes = getAllNodes(null);
84
85 for (TaxonNode node : allNodes){
86 Taxon taxon = CdmBase.deproxy(node.getTaxon(), Taxon.class);
87
88 //TODO use API methods to retrieve all related specimen
89
90 //individual associations
91 Set<TaxonDescription> descriptions = taxon.getDescriptions();
92 for (TaxonDescription description : descriptions){
93 for (DescriptionElementBase el : description.getElements()){
94 if (el.isInstanceOf(IndividualsAssociation.class)){
95 DwcaTypesRecord record = new DwcaTypesRecord(metaRecord, config);
96 IndividualsAssociation individualAssociation = CdmBase.deproxy(el,IndividualsAssociation.class);
97 if (! this.recordExistsUuid(individualAssociation) && handleSpecimen(record, individualAssociation, null, taxon, config)){
98 record.write(writer);
99 this.addExistingRecordUuid(individualAssociation);
100 }
101 }
102 }
103 }
104
105 //type specimen
106 NonViralName<?> nvn = CdmBase.deproxy(taxon.getName(), NonViralName.class);
107 handleTypeName(writer, taxon, nvn, metaRecord, config);
108 for (Synonym synonym : taxon.getSynonyms()){
109 handleTypeName(writer, synonym, nvn, metaRecord, config);
110 }
111
112 //FIXME
113 //Determinations
114
115
116 writer.flush();
117
118 }
119 } catch (FileNotFoundException e) {
120 e.printStackTrace();
121 } catch (UnsupportedEncodingException e) {
122 e.printStackTrace();
123 } catch (ClassCastException e) {
124 e.printStackTrace();
125 } catch (IOException e) {
126 e.printStackTrace();
127 } finally{
128 closeWriter(writer, state);
129 }
130 commitTransaction(txStatus);
131 return true;
132 }
133
134 /**
135 * @param writer
136 * @param taxon
137 * @param nvn
138 * @param config
139 * @return
140 */
141 private Set<TypeDesignationBase<?>> handleTypeName(PrintWriter writer, TaxonBase<?> taxonBase, NonViralName<?> nvn, DwcaMetaDataRecord metaRecord, DwcaTaxExportConfigurator config) {
142 Set<TypeDesignationBase<?>> designations = nvn.getTypeDesignations();
143 for (TypeDesignationBase<?> designation:designations){
144 DwcaTypesRecord record = new DwcaTypesRecord(metaRecord, config);
145 if (! this.recordExistsUuid(designation) && handleSpecimen(record, null, designation, taxonBase, config)){
146 record.write(writer);
147 addExistingRecordUuid(designation);
148 }
149 }
150 return designations;
151 }
152
153
154 private boolean handleSpecimen(DwcaTypesRecord record, IndividualsAssociation individualsAssociation, TypeDesignationBase<?> designation, TaxonBase<?> taxonBase, DwcaTaxExportConfigurator config) {
155 TypeDesignationStatusBase<?> status = null;
156 DerivedUnitFacade facade = null;
157 if (individualsAssociation != null){
158 facade = getFacadeFromAssociation(individualsAssociation);
159 }else if (designation != null){
160 facade = getFacadeFromDesignation(designation);
161 status = designation.getTypeStatus();
162 }
163 if (facade == null){
164 return false;
165 }
166
167 record.setId(taxonBase.getId());
168 record.setUuid(taxonBase.getUuid());
169 record.setBibliographicCitation(facade.getTitleCache());
170 record.setTypeStatus(status);
171 record.setTypeDesignatedBy( (designation == null || designation.getCitation()==null)? null: designation.getCitation().getTitleCache());
172
173 TaxonNameBase<?,?> scientificName = getScientificName(facade);
174 if (scientificName != null){
175 record.setScientificName(scientificName.getTitleCache());
176 record.setTaxonRank(scientificName.getRank());
177 }
178
179 record.setOccurrenceId(facade.innerDerivedUnit());
180 Collection collection = facade.getCollection();
181 if (collection != null){
182 record.setCollectionCode(collection.getCode());
183 if (collection.getInstitute() != null){
184 record.setInstitutionCode(collection.getInstitute().getCode());
185 }
186 }
187 record.setCatalogNumber(facade.getCatalogNumber());
188 record.setLocality(facade.getLocalityText());
189 record.setSex(facade.getSex());
190 record.setRecordedBy(facade.getCollector());
191 //TODO ???
192 record.setSource(getSources(facade.innerDerivedUnit(), config));
193 record.setEventDate(facade.getGatheringPeriod());
194 //TODO missing
195 record.setVerbatimLabel(null);
196 if (facade.getExactLocation() != null){
197 if (facade.getExactLocation().getLongitude() != null){
198 record.setVerbatimLongitude(facade.getExactLocation().getLongitudeSexagesimal().toString());
199 }
200 if (facade.getExactLocation().getLatitude() != null){
201 record.setVerbatimLatitude(facade.getExactLocation().getLatitudeSexagesimal().toString());
202 }
203 }
204 return true;
205 }
206
207 private TaxonNameBase<?,?> getScientificName(DerivedUnitFacade facade) {
208 Set<DeterminationEvent> detEvents = facade.getDeterminations();
209 for (DeterminationEvent detEvent : detEvents){
210 if (detEvent.getPreferredFlag()== true){
211 return detEvent.getTaxon().getName();
212 }
213 }
214 return null;
215 }
216
217 private DerivedUnitFacade getFacadeFromDesignation(TypeDesignationBase<?> designation) {
218 if (designation.isInstanceOf(SpecimenTypeDesignation.class)){
219 SpecimenTypeDesignation specDesig = CdmBase.deproxy(designation, SpecimenTypeDesignation.class);
220 try {
221 DerivedUnitBase<?> derivedUnit = specDesig.getTypeSpecimen();
222 if (derivedUnit == null){
223 return null;
224 }else{
225 DerivedUnitFacade facade = DerivedUnitFacade.NewInstance(derivedUnit);
226 return facade;
227 }
228 } catch (DerivedUnitFacadeNotSupportedException e) {
229 String message = "DerivedUnit is too complex to be handled by facade based darwin core archive export";
230 logger.warn(message);
231 //TODO handle empty records
232 return null;
233 }
234 }else{
235 return null;
236 }
237 }
238
239 private DerivedUnitFacade getFacadeFromAssociation(IndividualsAssociation individualsAssociation) {
240 SpecimenOrObservationBase<?> specimen = individualsAssociation.getAssociatedSpecimenOrObservation();
241 DerivedUnitFacade facade;
242 if (! specimen.isInstanceOf(DerivedUnitBase.class)){
243 String message = "Non DerivedUnit specimen can not yet be handled by this export";
244 logger.warn(message);
245 //TODO handle empty records
246 return null;
247 }else{
248 DerivedUnitBase<?> derivedUnit = CdmBase.deproxy(specimen, DerivedUnitBase.class);
249 try {
250 facade = DerivedUnitFacade.NewInstance(derivedUnit);
251 } catch (DerivedUnitFacadeNotSupportedException e) {
252 String message = "DerivedUnit is too complex to be handled by facade based darwin core archive export";
253 logger.warn(message);
254 //TODO handle empty records
255 return null;
256 }
257
258 }
259 return facade;
260 }
261
262 @Override
263 protected boolean doCheck(DwcaTaxExportState state) {
264 boolean result = true;
265 logger.warn("No check implemented for " + this.ioName);
266 return result;
267 }
268
269
270 @Override
271 protected boolean isIgnore(DwcaTaxExportState state) {
272 return ! state.getConfig().isDoTypesAndSpecimen();
273 }
274
275 }