a518e322aedf09f394d0db9997d3c6bd226a823c
[cdmlib-apps.git] / app-import / src / main / java / eu / etaxonomy / cdm / io / algaterra / AlgaTerraTypeImport.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.algaterra;
11
12 import java.sql.ResultSet;
13 import java.sql.SQLException;
14 import java.util.HashMap;
15 import java.util.HashSet;
16 import java.util.Map;
17 import java.util.Set;
18
19 import org.apache.commons.lang.StringUtils;
20 import org.apache.log4j.Logger;
21 import org.springframework.stereotype.Component;
22
23 import eu.etaxonomy.cdm.api.facade.DerivedUnitFacade;
24 import eu.etaxonomy.cdm.api.facade.DerivedUnitFacade.DerivedUnitType;
25 import eu.etaxonomy.cdm.api.facade.DerivedUnitFacadeNotSupportedException;
26 import eu.etaxonomy.cdm.io.algaterra.validation.AlgaTerraTypeImportValidator;
27 import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportConfigurator;
28 import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportState;
29 import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelReferenceImport;
30 import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelTaxonNameImport;
31 import eu.etaxonomy.cdm.io.common.IOValidator;
32 import eu.etaxonomy.cdm.io.common.ResultSetPartitioner;
33 import eu.etaxonomy.cdm.model.common.CdmBase;
34 import eu.etaxonomy.cdm.model.name.BotanicalName;
35 import eu.etaxonomy.cdm.model.name.Rank;
36 import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignation;
37 import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignationStatus;
38 import eu.etaxonomy.cdm.model.name.TaxonNameBase;
39 import eu.etaxonomy.cdm.model.occurrence.Collection;
40 import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
41 import eu.etaxonomy.cdm.model.occurrence.FieldObservation;
42 import eu.etaxonomy.cdm.model.reference.Reference;
43
44
45 /**
46 * @author a.mueller
47 * @created 20.03.2008
48 * @version 1.0
49 */
50 @Component
51 public class AlgaTerraTypeImport extends AlgaTerraSpecimenImportBase {
52 private static final Logger logger = Logger.getLogger(AlgaTerraTypeImport.class);
53
54
55 private static int modCount = 5000;
56 private static final String pluralString = "types";
57 private static final String dbTableName = "TypeDesignation"; //??
58
59 protected String getLocalityString(){
60 return "TypeLocality";
61 }
62
63 public AlgaTerraTypeImport(){
64 super(dbTableName, pluralString);
65 }
66
67
68 /* (non-Javadoc)
69 * @see eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportBase#getIdQuery()
70 */
71 @Override
72 protected String getIdQuery(BerlinModelImportState state) {
73 String result = " SELECT TypeDesignationId "
74 + " FROM TypeDesignation "
75 + " ORDER BY NameFk ";
76 return result;
77 }
78
79 /* (non-Javadoc)
80 * @see eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportBase#getRecordQuery(eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportConfigurator)
81 */
82 @Override
83 protected String getRecordQuery(BerlinModelImportConfigurator config) {
84 String strQuery =
85
86 " SELECT ts.*, ts.TypeSpecimenId as unitId, td.*, gz.ID as GazetteerId, gz.L2Code, gz.L3Code, gz.L4Code, gz.ISOCountry, gz.Country, ts.WaterBody " +
87 " " +
88 " FROM TypeSpecimenDesignation tsd "
89 + " LEFT OUTER JOIN TypeSpecimen AS ts ON tsd.TypeSpecimenFk = ts.TypeSpecimenId "
90 + " FULL OUTER JOIN TypeDesignation td ON td.TypeDesignationId = tsd.TypeDesignationFk "
91 + " LEFT OUTER JOIN TDWGGazetteer gz ON ts.TDWGGazetteerFk = gz.ID "
92 + " WHERE (td.TypeDesignationId IN (" + ID_LIST_TOKEN + ") )"
93 + " ORDER BY NameFk "
94 ;
95 return strQuery;
96 }
97
98 /* (non-Javadoc)
99 * @see eu.etaxonomy.cdm.io.berlinModel.in.IPartitionedIO#doPartition(eu.etaxonomy.cdm.io.berlinModel.in.ResultSetPartitioner, eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportState)
100 */
101 public boolean doPartition(ResultSetPartitioner partitioner, BerlinModelImportState bmState) {
102 boolean success = true;
103
104 AlgaTerraImportState state = (AlgaTerraImportState)bmState;
105
106 //TODO check that no duplicate vocabularies will be created, also remove redundant code here
107 // and in Specimen importer
108 try {
109 makeVocabulariesAndFeatures(state);
110 } catch (SQLException e1) {
111 logger.warn("Exception occurred when trying to create Type specimen vocabularies: " + e1.getMessage());
112 e1.printStackTrace();
113 }
114
115
116
117 Set<TaxonNameBase> namesToSave = new HashSet<TaxonNameBase>();
118
119 Map<String, TaxonNameBase> taxonNameMap = (Map<String, TaxonNameBase>) partitioner.getObjectMap(BerlinModelTaxonNameImport.NAMESPACE);
120 Map<String, DerivedUnit> ecoFactMap = (Map<String, DerivedUnit>) partitioner.getObjectMap(AlgaTerraSpecimenImport.ECO_FACT_FIELD_OBSERVATION_NAMESPACE);
121 Map<String, DerivedUnit> typeSpecimenMap = (Map<String, DerivedUnit>) partitioner.getObjectMap(TYPE_SPECIMEN_FIELD_OBSERVATION_NAMESPACE);
122 Map<String, Reference> biblioReference = (Map<String, Reference>) partitioner.getObjectMap(BerlinModelReferenceImport.BIBLIO_REFERENCE_NAMESPACE);
123
124
125 ResultSet rs = partitioner.getResultSet();
126
127 try {
128
129 int i = 0;
130
131 //for each reference
132 while (rs.next()){
133
134 if ((i++ % modCount) == 0 && i!= 1 ){ logger.info("Type designations handled: " + (i-1));}
135
136 int nameId = rs.getInt("nameFk");
137 int typeSpecimenId = rs.getInt("TypeSpecimenId");
138 int typeDesignationId = rs.getInt("TypeDesignationId");
139 Integer typeStatusFk = nullSafeInt(rs, "typeStatusFk");
140 Integer ecoFactId = nullSafeInt(rs, "ecoFactFk");
141 // String recordBasis = rs.getString("RecordBasis");
142
143 try {
144
145 //source ref
146 Reference<?> sourceRef = state.getTransactionalSourceReference();
147
148 //facade
149 //FIXME - depends on material category
150 // DerivedUnitType type = makeDerivedUnitType(recordBasis);
151 DerivedUnitType type = DerivedUnitType.Specimen;
152 DerivedUnitFacade facade = getDerivedUnit(state, typeSpecimenId, typeSpecimenMap, type, ecoFactMap, ecoFactId);
153
154 //field observation
155 handleSingleSpecimen(rs, facade, state, partitioner);
156
157 handleTypeSpecimenSpecificSpecimen(rs,facade, state);
158
159 state.setCurrentFieldObservationNotNew(false);
160
161 //Designation
162 TaxonNameBase<?,?> name = getTaxonName(state, taxonNameMap, nameId);
163 SpecimenTypeDesignation designation = SpecimenTypeDesignation.NewInstance();
164 SpecimenTypeDesignationStatus status = getSpecimenTypeDesignationStatusByKey(typeStatusFk);
165 designation.setTypeSpecimen(facade.innerDerivedUnit());
166 designation.setTypeStatus(status);
167 if (name != null){
168 name.addTypeDesignation(designation, true); //TODO check if true is correct
169 }else{
170 logger.warn("Name could not be found for type designation " + typeDesignationId);
171 }
172 namesToSave.add(name);
173
174
175 } catch (Exception e) {
176 logger.warn("Exception in TypeDesignation: TypeDesignationId " + typeDesignationId + ". " + e.getMessage());
177 e.printStackTrace();
178 }
179
180 }
181
182 // logger.warn("Specimen: " + countSpecimen + ", Descriptions: " + countDescriptions );
183
184 logger.warn("Names to save: " + namesToSave.size());
185 getNameService().save(namesToSave);
186
187 return success;
188 } catch (SQLException e) {
189 logger.error("SQLException:" + e);
190 return false;
191 }
192 }
193
194
195 protected String getDerivedUnitNameSpace(){
196 return TYPE_SPECIMEN_DERIVED_UNIT_NAMESPACE;
197 }
198
199 /**
200 * @param state
201 * @param taxonNameMap
202 * @param nameId
203 * @return
204 */
205 private TaxonNameBase<?,?> getTaxonName(AlgaTerraImportState state, Map<String, TaxonNameBase> taxonNameMap, int nameId) {
206 TaxonNameBase<?,?> result;
207 if (state.getConfig().isDoTaxonNames()){
208 result = taxonNameMap.get(String.valueOf(nameId));
209 }else{
210 //for testing
211 result = BotanicalName.NewInstance(Rank.SPECIES());
212 }
213 return result;
214 }
215
216 private void handleTypeSpecimenSpecificSpecimen(ResultSet rs, DerivedUnitFacade facade, AlgaTerraImportState state) throws SQLException {
217 //TODO
218
219
220 //collection
221 String barcode = rs.getString("Barcode");
222 if (StringUtils.isNotBlank(barcode)){
223 facade.setBarcode(barcode);
224 }
225
226 }
227
228 /**
229 * @param state
230 * @param ecoFactId
231 * @param derivedUnitMap
232 * @param type
233 * @param ecoFactId2
234 * @param ecoFactMap
235 * @return
236 */
237 private DerivedUnitFacade getDerivedUnit(AlgaTerraImportState state, int typeSpecimenId, Map<String, DerivedUnit> typeSpecimenMap, DerivedUnitType type, Map<String, DerivedUnit> ecoFactMap, Integer ecoFactId2) {
238 //TODO implement ecoFact map - if not all null anymore
239 String typeKey = String.valueOf(typeSpecimenId);
240 DerivedUnit derivedUnit = typeSpecimenMap.get(typeKey);
241 DerivedUnitFacade facade;
242 if (derivedUnit == null){
243 facade = DerivedUnitFacade.NewInstance(type);
244 typeSpecimenMap.put(typeKey, derivedUnit);
245 }else{
246 try {
247 facade = DerivedUnitFacade.NewInstance(derivedUnit);
248 } catch (DerivedUnitFacadeNotSupportedException e) {
249 logger.error(e.getMessage());
250 facade = DerivedUnitFacade.NewInstance(type);
251 }
252 }
253
254 return facade;
255 }
256 private DerivedUnitType makeDerivedUnitType(String recordBasis) {
257 DerivedUnitType result = null;
258 if (StringUtils.isBlank(recordBasis)){
259 result = DerivedUnitType.DerivedUnit;
260 } else if (recordBasis.equalsIgnoreCase("FossileSpecimen")){
261 result = DerivedUnitType.Fossil;
262 }else if (recordBasis.equalsIgnoreCase("HumanObservation")){
263 result = DerivedUnitType.Observation;
264 }else if (recordBasis.equalsIgnoreCase("Literature")){
265 logger.warn("Literature record basis not yet supported");
266 result = DerivedUnitType.DerivedUnit;
267 }else if (recordBasis.equalsIgnoreCase("LivingSpecimen")){
268 result = DerivedUnitType.LivingBeing;
269 }else if (recordBasis.equalsIgnoreCase("MachineObservation")){
270 logger.warn("MachineObservation record basis not yet supported");
271 result = DerivedUnitType.Observation;
272 }else if (recordBasis.equalsIgnoreCase("PreservedSpecimen")){
273 result = DerivedUnitType.Specimen;
274 }
275 return result;
276 }
277
278
279 private SpecimenTypeDesignationStatus getSpecimenTypeDesignationStatusByKey(Integer typeStatusFk) {
280 if (typeStatusFk == null){ return null;
281 }else if (typeStatusFk == 1) { return SpecimenTypeDesignationStatus.HOLOTYPE();
282 }else if (typeStatusFk == 2) { return SpecimenTypeDesignationStatus.LECTOTYPE();
283 }else if (typeStatusFk == 3) { return SpecimenTypeDesignationStatus.NEOTYPE();
284 }else if (typeStatusFk == 4) { return SpecimenTypeDesignationStatus.EPITYPE();
285 }else if (typeStatusFk == 5) { return SpecimenTypeDesignationStatus.ISOLECTOTYPE();
286 }else if (typeStatusFk == 6) { return SpecimenTypeDesignationStatus.ISONEOTYPE();
287 }else if (typeStatusFk == 7) { return SpecimenTypeDesignationStatus.ISOTYPE();
288 }else if (typeStatusFk == 8) { return SpecimenTypeDesignationStatus.PARANEOTYPE();
289 }else if (typeStatusFk == 9) { return SpecimenTypeDesignationStatus.PARATYPE();
290 }else if (typeStatusFk == 10) { return SpecimenTypeDesignationStatus.SECOND_STEP_LECTOTYPE();
291 }else if (typeStatusFk == 11) { return SpecimenTypeDesignationStatus.SECOND_STEP_NEOTYPE();
292 }else if (typeStatusFk == 12) { return SpecimenTypeDesignationStatus.SYNTYPE();
293 }else if (typeStatusFk == 13) { return SpecimenTypeDesignationStatus.PARALECTOTYPE();
294 }else if (typeStatusFk == 14) { return SpecimenTypeDesignationStatus.ISOEPITYPE();
295 }else if (typeStatusFk == 21) { return SpecimenTypeDesignationStatus.ICONOTYPE();
296 }else if (typeStatusFk == 22) { return SpecimenTypeDesignationStatus.PHOTOTYPE();
297 }else if (typeStatusFk == 30) { return SpecimenTypeDesignationStatus.TYPE();
298 }else if (typeStatusFk == 38) { return SpecimenTypeDesignationStatus.ISOEPITYPE();
299 // }else if (typeStatusFk == 39) { return SpecimenTypeDesignationStatus.;
300 }else if (typeStatusFk == 40) { return SpecimenTypeDesignationStatus.ORIGINAL_MATERIAL();
301 }else{
302 logger.warn("typeStatusFk undefined for " + typeStatusFk);
303 return SpecimenTypeDesignationStatus.TYPE();
304 }
305
306 }
307
308
309 /* (non-Javadoc)
310 * @see eu.etaxonomy.cdm.io.berlinModel.in.IPartitionedIO#getRelatedObjectsForPartition(java.sql.ResultSet)
311 */
312 public Map<Object, Map<String, ? extends CdmBase>> getRelatedObjectsForPartition(ResultSet rs) {
313 String nameSpace;
314 Class cdmClass;
315 Set<String> idSet;
316 Map<Object, Map<String, ? extends CdmBase>> result = new HashMap<Object, Map<String, ? extends CdmBase>>();
317
318 try{
319 Set<String> nameIdSet = new HashSet<String>();
320 Set<String> ecoFieldObservationIdSet = new HashSet<String>();
321 Set<String> typeSpecimenIdSet = new HashSet<String>();
322 Set<String> termsIdSet = new HashSet<String>();
323 Set<String> collectionIdSet = new HashSet<String>();
324
325 while (rs.next()){
326 handleForeignKey(rs, nameIdSet, "nameFk");
327 handleForeignKey(rs, ecoFieldObservationIdSet, "ecoFactFk");
328 handleForeignKey(rs, typeSpecimenIdSet, "TypeSpecimenId");
329 handleForeignKey(rs, collectionIdSet, "CollectionFk");
330 }
331
332 //name map
333 nameSpace = BerlinModelTaxonNameImport.NAMESPACE;
334 cdmClass = TaxonNameBase.class;
335 idSet = nameIdSet;
336 Map<String, TaxonNameBase> objectMap = (Map<String, TaxonNameBase>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
337 result.put(nameSpace, objectMap);
338
339 //eco fact field observation map
340 nameSpace = AlgaTerraTypeImport.ECO_FACT_FIELD_OBSERVATION_NAMESPACE;
341 cdmClass = FieldObservation.class;
342 idSet = ecoFieldObservationIdSet;
343 Map<String, FieldObservation> fieldObservationMap = (Map<String, FieldObservation>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
344 result.put(nameSpace, fieldObservationMap);
345
346 //type specimen map
347 nameSpace = AlgaTerraTypeImport.TYPE_SPECIMEN_FIELD_OBSERVATION_NAMESPACE;
348 cdmClass = FieldObservation.class;
349 idSet = typeSpecimenIdSet;
350 Map<String, FieldObservation> typeSpecimenMap = (Map<String, FieldObservation>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
351 result.put(nameSpace, typeSpecimenMap);
352
353
354 //collections
355 nameSpace = AlgaTerraCollectionImport.NAMESPACE_COLLECTION;
356 cdmClass = Collection.class;
357 idSet = collectionIdSet;
358 Map<String, Collection> collectionMap = (Map<String, Collection>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
359 result.put(nameSpace, collectionMap);
360
361 //sub-collections
362 nameSpace = AlgaTerraCollectionImport.NAMESPACE_SUBCOLLECTION;
363 cdmClass = Collection.class;
364 idSet = collectionIdSet;
365 Map<String, Collection> subCollectionMap = (Map<String, Collection>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
366 result.put(nameSpace, subCollectionMap);
367
368
369 //
370 // //terms
371 // nameSpace = AlgaTerraTypeImport.TERMS_NAMESPACE;
372 // cdmClass = FieldObservation.class;
373 // idSet = taxonIdSet;
374 // Map<String, DefinedTermBase> termMap = (Map<String, DefinedTermBase>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
375 // result.put(nameSpace, termMap);
376
377
378
379
380 } catch (SQLException e) {
381 throw new RuntimeException(e);
382 }
383 return result;
384 }
385
386 /* (non-Javadoc)
387 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#doCheck(eu.etaxonomy.cdm.io.common.IoStateBase)
388 */
389 @Override
390 protected boolean doCheck(BerlinModelImportState state){
391 IOValidator<BerlinModelImportState> validator = new AlgaTerraTypeImportValidator();
392 return validator.validate(state);
393 }
394
395
396 /* (non-Javadoc)
397 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#isIgnore(eu.etaxonomy.cdm.io.common.IImportConfigurator)
398 */
399 protected boolean isIgnore(BerlinModelImportState state){
400 return ! state.getConfig().isDoTypes();
401 }
402
403 }