11 |
11 |
|
12 |
12 |
import java.sql.ResultSet;
|
13 |
13 |
import java.sql.SQLException;
|
|
14 |
import java.sql.Timestamp;
|
14 |
15 |
import java.util.HashMap;
|
15 |
16 |
import java.util.HashSet;
|
16 |
17 |
import java.util.Map;
|
... | ... | |
18 |
19 |
|
19 |
20 |
import org.apache.commons.lang.StringUtils;
|
20 |
21 |
import org.apache.log4j.Logger;
|
|
22 |
import org.joda.time.DateTime;
|
21 |
23 |
import org.springframework.stereotype.Component;
|
22 |
24 |
|
23 |
25 |
import eu.etaxonomy.cdm.api.facade.DerivedUnitFacade;
|
24 |
26 |
import eu.etaxonomy.cdm.api.facade.DerivedUnitFacadeNotSupportedException;
|
25 |
27 |
import eu.etaxonomy.cdm.io.algaterra.validation.AlgaTerraTypeImportValidator;
|
|
28 |
import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportBase;
|
26 |
29 |
import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportConfigurator;
|
27 |
30 |
import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportState;
|
|
31 |
import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelRefDetailImport;
|
28 |
32 |
import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelReferenceImport;
|
29 |
33 |
import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelTaxonNameImport;
|
30 |
34 |
import eu.etaxonomy.cdm.io.common.IOValidator;
|
31 |
35 |
import eu.etaxonomy.cdm.io.common.ResultSetPartitioner;
|
|
36 |
import eu.etaxonomy.cdm.io.common.IImportConfigurator.EDITOR;
|
|
37 |
import eu.etaxonomy.cdm.model.common.AnnotatableEntity;
|
|
38 |
import eu.etaxonomy.cdm.model.common.Annotation;
|
|
39 |
import eu.etaxonomy.cdm.model.common.AnnotationType;
|
32 |
40 |
import eu.etaxonomy.cdm.model.common.CdmBase;
|
33 |
41 |
import eu.etaxonomy.cdm.model.common.IdentifiableSource;
|
|
42 |
import eu.etaxonomy.cdm.model.common.Language;
|
|
43 |
import eu.etaxonomy.cdm.model.common.OriginalSourceType;
|
|
44 |
import eu.etaxonomy.cdm.model.common.User;
|
34 |
45 |
import eu.etaxonomy.cdm.model.name.BotanicalName;
|
35 |
46 |
import eu.etaxonomy.cdm.model.name.Rank;
|
36 |
47 |
import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignation;
|
... | ... | |
64 |
75 |
}
|
65 |
76 |
|
66 |
77 |
|
67 |
|
/* (non-Javadoc)
|
68 |
|
* @see eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportBase#getIdQuery()
|
69 |
|
*/
|
70 |
78 |
@Override
|
71 |
79 |
protected String getIdQuery(BerlinModelImportState state) {
|
72 |
80 |
String result = " SELECT TypeDesignationId "
|
... | ... | |
75 |
83 |
return result;
|
76 |
84 |
}
|
77 |
85 |
|
78 |
|
/* (non-Javadoc)
|
79 |
|
* @see eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportBase#getRecordQuery(eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportConfigurator)
|
80 |
|
*/
|
81 |
86 |
@Override
|
82 |
87 |
protected String getRecordQuery(BerlinModelImportConfigurator config) {
|
83 |
88 |
String strQuery =
|
84 |
89 |
|
85 |
90 |
" SELECT ts.*, ts.TypeSpecimenId as unitId, td.*, gz.ID as GazetteerId, gz.L2Code, gz.L3Code, gz.L4Code, gz.ISOCountry, gz.Country, ts.WaterBody, " +
|
86 |
|
" ts.RefFk as tsRefFk, ts.RefDetailFk as tsRefDetailFk, td.RefFk as tdRefFk, td.RefDetailFk as tdRefDetailFk " +
|
|
91 |
" ts.RefFk as tsRefFk, ts.RefDetailFk as tsRefDetailFk, td.RefFk as tdRefFk, td.RefDetailFk as tdRefDetailFk, " +
|
|
92 |
" RefDet.Details as tdRefDetails, " +
|
|
93 |
" td.created_When tdCreated_When, tsd.created_When tsdCreated_When, td.updated_when tdUpdated_when" +
|
|
94 |
" td.created_who tdCreated_who, tsd.created_who tdCreated_who, td.updated_who tdUpdated_who, " +
|
87 |
95 |
" FROM TypeSpecimenDesignation tsd "
|
88 |
96 |
+ " LEFT OUTER JOIN TypeSpecimen AS ts ON tsd.TypeSpecimenFk = ts.TypeSpecimenId "
|
89 |
97 |
+ " FULL OUTER JOIN TypeDesignation td ON td.TypeDesignationId = tsd.TypeDesignationFk "
|
90 |
98 |
+ " LEFT OUTER JOIN TDWGGazetteer gz ON ts.TDWGGazetteerFk = gz.ID "
|
|
99 |
+ " LEFT OUTER JOIN RefDetail refDet ON td.RefDetailFk = refDet.RefDetailId AND td.RefFk = refDet.RefFk "
|
91 |
100 |
+ " WHERE (td.TypeDesignationId IN (" + ID_LIST_TOKEN + ") )"
|
92 |
101 |
+ " ORDER BY NameFk "
|
93 |
102 |
;
|
94 |
103 |
return strQuery;
|
95 |
104 |
}
|
96 |
105 |
|
97 |
|
/* (non-Javadoc)
|
98 |
|
* @see eu.etaxonomy.cdm.io.berlinModel.in.IPartitionedIO#doPartition(eu.etaxonomy.cdm.io.berlinModel.in.ResultSetPartitioner, eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportState)
|
99 |
|
*/
|
|
106 |
@Override
|
100 |
107 |
public boolean doPartition(ResultSetPartitioner partitioner, BerlinModelImportState bmState) {
|
101 |
108 |
boolean success = true;
|
102 |
109 |
|
... | ... | |
119 |
126 |
Map<String, DerivedUnit> ecoFactMap = (Map<String, DerivedUnit>) partitioner.getObjectMap(AlgaTerraEcoFactImport.ECO_FACT_FIELD_OBSERVATION_NAMESPACE);
|
120 |
127 |
Map<String, DerivedUnit> typeSpecimenMap = (Map<String, DerivedUnit>) partitioner.getObjectMap(TYPE_SPECIMEN_FIELD_OBSERVATION_NAMESPACE);
|
121 |
128 |
Map<String, Reference> refMap = (Map<String, Reference>) partitioner.getObjectMap(BerlinModelReferenceImport.REFERENCE_NAMESPACE);
|
|
129 |
Map<String, Reference> refDetailMap = partitioner.getObjectMap(BerlinModelRefDetailImport.REFDETAIL_NAMESPACE);
|
122 |
130 |
|
123 |
131 |
|
124 |
132 |
ResultSet rs = partitioner.getResultSet();
|
... | ... | |
139 |
147 |
Integer ecoFactId = nullSafeInt(rs, "ecoFactFk");
|
140 |
148 |
Integer tdRefFk = nullSafeInt(rs, "tdRefFk");
|
141 |
149 |
Integer tdRefDetailFk = nullSafeInt(rs, "tdRefDetailFk");
|
|
150 |
String tdRefDetails = rs.getString("tdRefDetails");
|
|
151 |
Boolean restrictedFlag = nullSafeBoolean(rs, "RestrictedFlag");
|
|
152 |
|
|
153 |
String typeSpecimenPhrase = rs.getString("TypeSpecimnePhrase");
|
142 |
154 |
|
143 |
155 |
|
144 |
|
// String recordBasis = rs.getString("RecordBasis");
|
|
156 |
|
|
157 |
boolean isIcon = typeSpecimenPhrase.toLowerCase().startsWith("[icon");
|
145 |
158 |
|
146 |
159 |
try {
|
147 |
160 |
|
... | ... | |
149 |
162 |
Reference<?> sourceRef = state.getTransactionalSourceReference();
|
150 |
163 |
|
151 |
164 |
//facade
|
152 |
|
//FIXME - depends on material category
|
153 |
|
// DerivedUnitType type = makeDerivedUnitType(recordBasis);
|
154 |
|
if (i<=2){logger.warn("RecordBasis not yet implemented in TypeImport");}
|
155 |
|
|
156 |
165 |
SpecimenOrObservationType type = SpecimenOrObservationType.PreservedSpecimen;
|
157 |
|
DerivedUnitFacade facade = getDerivedUnit(state, typeSpecimenId, typeSpecimenMap, type, ecoFactMap, ecoFactId);
|
|
166 |
if (isIcon){
|
|
167 |
//TODO handle images correctly for these specimen
|
|
168 |
type = SpecimenOrObservationType.StillImage;
|
|
169 |
}else if (typeStatusFk.equals(39)){
|
|
170 |
type = SpecimenOrObservationType.LivingSpecimen;
|
|
171 |
}
|
|
172 |
|
|
173 |
DerivedUnitFacade facade = getDerivedUnit(state, typeSpecimenId, typeSpecimenMap, type, ecoFactMap, ecoFactId, sourceRef);
|
158 |
174 |
|
159 |
175 |
//field observation
|
160 |
176 |
handleFieldObservationSpecimen(rs, facade, state, partitioner);
|
... | ... | |
169 |
185 |
TaxonNameBase<?,?> name = getTaxonName(state, taxonNameMap, nameId);
|
170 |
186 |
SpecimenTypeDesignation designation = SpecimenTypeDesignation.NewInstance();
|
171 |
187 |
SpecimenTypeDesignationStatus status = getSpecimenTypeDesignationStatusByKey(typeStatusFk);
|
|
188 |
if (typeStatusFk.equals(39)){
|
|
189 |
designation.addAnnotation(Annotation.NewInstance("Type status: Authentic strain", AnnotationType.EDITORIAL(), Language.DEFAULT()));
|
|
190 |
}
|
|
191 |
|
172 |
192 |
designation.setTypeSpecimen(facade.innerDerivedUnit());
|
173 |
193 |
designation.setTypeStatus(status);
|
174 |
194 |
if (tdRefFk != null){
|
175 |
|
Reference<?> typeDesigRef = refMap.get(String.valueOf(tdRefFk));
|
|
195 |
Reference<?> typeDesigRef = getReferenceFromMaps(refDetailMap, refMap, String.valueOf(tdRefDetailFk), String.valueOf(tdRefFk));
|
176 |
196 |
if (typeDesigRef == null){
|
177 |
197 |
logger.warn("Type designation reference not found in maps: " + tdRefFk);
|
178 |
198 |
}else{
|
179 |
199 |
designation.setCitation(typeDesigRef);
|
180 |
200 |
}
|
181 |
201 |
}
|
|
202 |
if (isNotBlank(tdRefDetails)){
|
|
203 |
designation.setCitationMicroReference(tdRefDetails);
|
|
204 |
}
|
182 |
205 |
|
183 |
|
if (tdRefDetailFk != null){
|
184 |
|
logger.warn("TypeDesignation.RefDetailFk not yet implemented: " + typeDesignationId);
|
|
206 |
//ID: Type designations do not allow OriginalSources
|
|
207 |
designation.addAnnotation(Annotation.NewInstance("Id in BerlinModel-TypeDesignation: " + String.valueOf(typeDesignationId), AnnotationType.TECHNICAL(), Language.UNDETERMINED()));
|
|
208 |
|
|
209 |
if (restrictedFlag != null &&restrictedFlag.equals(true)){
|
|
210 |
logger.warn("Restricted Flag is expected to be null or 0. TypeDesignationId" + typeDesignationId);
|
185 |
211 |
}
|
186 |
212 |
|
|
213 |
//Created, Updated
|
|
214 |
this.doCreatedUpdated(state, designation, rs);
|
|
215 |
|
187 |
216 |
if (name != null){
|
188 |
217 |
name.addTypeDesignation(designation, true); //TODO check if true is correct
|
189 |
218 |
}else{
|
... | ... | |
211 |
240 |
}
|
212 |
241 |
}
|
213 |
242 |
|
|
243 |
/**
|
|
244 |
* same as {@link BerlinModelImportBase#doCreatedUpdatedNotes}, but handles multiple similar fields
|
|
245 |
* @throws SQLException
|
|
246 |
*/
|
|
247 |
private void doCreatedUpdated(BerlinModelImportState state, AnnotatableEntity annotatableEntity, ResultSet rs) throws SQLException{
|
|
248 |
BerlinModelImportConfigurator config = state.getConfig();
|
|
249 |
Object createdWhen = rs.getObject("tsdCreated_When");
|
|
250 |
Object tdCreatedWhen = rs.getObject("tdCreated_When");
|
|
251 |
if (tdCreatedWhen != null){
|
|
252 |
createdWhen = tdCreatedWhen;
|
|
253 |
}
|
|
254 |
|
|
255 |
String createdWho = rs.getString("tsdCreated_Who");
|
|
256 |
String tdCreatedWho = rs.getString("tdCreated_Who");
|
|
257 |
if (tdCreatedWho != null){
|
|
258 |
createdWho = tdCreatedWho;
|
|
259 |
}
|
|
260 |
|
|
261 |
Object updatedWhen = rs.getObject("tdUpdated_When");
|
|
262 |
String updatedWho = rs.getString("tdUpdated_who");
|
|
263 |
|
|
264 |
//Created When, Who, Updated When Who
|
|
265 |
if (config.getEditor() == null || config.getEditor().equals(EDITOR.NO_EDITORS)){
|
|
266 |
//do nothing
|
|
267 |
}else if (config.getEditor().equals(EDITOR.EDITOR_AS_ANNOTATION)){
|
|
268 |
String createdAnnotationString = "Berlin Model record was created By: " + String.valueOf(createdWho) + " (" + String.valueOf(createdWhen) + ") ";
|
|
269 |
if (updatedWhen != null && updatedWho != null){
|
|
270 |
createdAnnotationString += " and updated By: " + String.valueOf(updatedWho) + " (" + String.valueOf(updatedWhen) + ")";
|
|
271 |
}
|
|
272 |
Annotation annotation = Annotation.NewInstance(createdAnnotationString, Language.DEFAULT());
|
|
273 |
annotation.setCommentator(config.getCommentator());
|
|
274 |
annotation.setAnnotationType(AnnotationType.TECHNICAL());
|
|
275 |
annotatableEntity.addAnnotation(annotation);
|
|
276 |
}else if (config.getEditor().equals(EDITOR.EDITOR_AS_EDITOR)){
|
|
277 |
User creator = getUser(state, createdWho);
|
|
278 |
User updator = getUser(state, updatedWho);
|
|
279 |
DateTime created = getDateTime(createdWhen);
|
|
280 |
DateTime updated = getDateTime(updatedWhen);
|
|
281 |
annotatableEntity.setCreatedBy(creator);
|
|
282 |
annotatableEntity.setUpdatedBy(updator);
|
|
283 |
annotatableEntity.setCreated(created);
|
|
284 |
annotatableEntity.setUpdated(updated);
|
|
285 |
}else {
|
|
286 |
logger.warn("Editor type not yet implemented: " + config.getEditor());
|
|
287 |
}
|
|
288 |
}
|
|
289 |
|
|
290 |
|
|
291 |
private DateTime getDateTime(Object timeString){
|
|
292 |
if (timeString == null){
|
|
293 |
return null;
|
|
294 |
}
|
|
295 |
DateTime dateTime = null;
|
|
296 |
if (timeString instanceof Timestamp){
|
|
297 |
Timestamp timestamp = (Timestamp)timeString;
|
|
298 |
dateTime = new DateTime(timestamp);
|
|
299 |
}else{
|
|
300 |
logger.warn("time ("+timeString+") is not a timestamp. Datetime set to current date. ");
|
|
301 |
dateTime = new DateTime();
|
|
302 |
}
|
|
303 |
return dateTime;
|
|
304 |
}
|
|
305 |
|
214 |
306 |
|
215 |
307 |
protected String getDerivedUnitNameSpace(){
|
216 |
308 |
return TYPE_SPECIMEN_DERIVED_UNIT_NAMESPACE;
|
... | ... | |
281 |
373 |
* @param type
|
282 |
374 |
* @param ecoFactId2
|
283 |
375 |
* @param ecoFactMap
|
|
376 |
* @param sourceRef
|
284 |
377 |
* @return
|
285 |
378 |
*/
|
286 |
|
private DerivedUnitFacade getDerivedUnit(AlgaTerraImportState state, int typeSpecimenId, Map<String, DerivedUnit> typeSpecimenMap, SpecimenOrObservationType type, Map<String, DerivedUnit> ecoFactMap, Integer ecoFactId2) {
|
|
379 |
private DerivedUnitFacade getDerivedUnit(AlgaTerraImportState state, int typeSpecimenId, Map<String, DerivedUnit> typeSpecimenMap, SpecimenOrObservationType type, Map<String, DerivedUnit> ecoFactMap, Integer ecoFactId2, Reference<?> sourceRef) {
|
287 |
380 |
//TODO implement ecoFact map - if not all null anymore
|
288 |
381 |
String typeKey = String.valueOf(typeSpecimenId);
|
289 |
382 |
DerivedUnit derivedUnit = typeSpecimenMap.get(typeKey);
|
... | ... | |
294 |
387 |
}else{
|
295 |
388 |
try {
|
296 |
389 |
facade = DerivedUnitFacade.NewInstance(derivedUnit);
|
|
390 |
facade.addSource(IdentifiableSource.NewDataImportInstance(typeKey, "TypeSpecimen", sourceRef));
|
297 |
391 |
} catch (DerivedUnitFacadeNotSupportedException e) {
|
298 |
392 |
logger.error(e.getMessage());
|
299 |
393 |
facade = DerivedUnitFacade.NewInstance(type);
|
... | ... | |
345 |
439 |
}else if (typeStatusFk == 22) { return SpecimenTypeDesignationStatus.PHOTOTYPE();
|
346 |
440 |
}else if (typeStatusFk == 30) { return SpecimenTypeDesignationStatus.TYPE();
|
347 |
441 |
}else if (typeStatusFk == 38) { return SpecimenTypeDesignationStatus.ISOEPITYPE();
|
348 |
|
// }else if (typeStatusFk == 39) { return SpecimenTypeDesignationStatus.;
|
|
442 |
}else if (typeStatusFk == 39) { return SpecimenTypeDesignationStatus.ORIGINAL_MATERIAL();
|
349 |
443 |
}else if (typeStatusFk == 40) { return SpecimenTypeDesignationStatus.ORIGINAL_MATERIAL();
|
350 |
444 |
}else{
|
351 |
445 |
logger.warn("typeStatusFk undefined for " + typeStatusFk);
|
... | ... | |
369 |
463 |
// Set<String> termsIdSet = new HashSet<String>();
|
370 |
464 |
Set<String> collectionIdSet = new HashSet<String>();
|
371 |
465 |
Set<String> referenceIdSet = new HashSet<String>();
|
|
466 |
Set<String> refDetailIdSet = new HashSet<String>();
|
372 |
467 |
|
373 |
468 |
while (rs.next()){
|
374 |
469 |
handleForeignKey(rs, nameIdSet, "nameFk");
|
... | ... | |
377 |
472 |
handleForeignKey(rs, collectionIdSet, "CollectionFk");
|
378 |
473 |
handleForeignKey(rs, referenceIdSet, "tsRefFk");
|
379 |
474 |
handleForeignKey(rs, referenceIdSet, "tdRefFk");
|
|
475 |
handleForeignKey(rs, refDetailIdSet, "tdRefDetailFk");
|
380 |
476 |
}
|
381 |
477 |
|
382 |
478 |
//name map
|
... | ... | |
422 |
518 |
Map<String, Reference> referenceMap = (Map<String, Reference>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
|
423 |
519 |
result.put(nameSpace, referenceMap);
|
424 |
520 |
|
425 |
|
//
|
426 |
|
// //terms
|
427 |
|
// nameSpace = AlgaTerraTypeImport.TERMS_NAMESPACE;
|
428 |
|
// cdmClass = FieldObservation.class;
|
429 |
|
// idSet = taxonIdSet;
|
430 |
|
// Map<String, DefinedTermBase> termMap = (Map<String, DefinedTermBase>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
|
431 |
|
// result.put(nameSpace, termMap);
|
432 |
|
|
433 |
|
|
|
521 |
//refDetail map
|
|
522 |
nameSpace = BerlinModelRefDetailImport.REFDETAIL_NAMESPACE;
|
|
523 |
cdmClass = Reference.class;
|
|
524 |
idSet = refDetailIdSet;
|
|
525 |
Map<String, Reference> refDetailMap= (Map<String, Reference>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
|
|
526 |
result.put(nameSpace, refDetailMap);
|
|
527 |
|
434 |
528 |
|
435 |
529 |
|
436 |
530 |
} catch (SQLException e) {
|
Some updates for AlgaTerra Types import