adapt some classes to new CommonService.getSourcedObjectSByIdInSource and cleanup
[cdmlib-apps.git] / app-import / src / main / java / eu / etaxonomy / cdm / io / berlinModel / in / BerlinModelTaxonNameRelationImport.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.berlinModel.in;
11
12 import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.NAME_REL_HAS_SAME_TYPE_AS;
13 import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.NAME_REL_IS_ALTERNATIVE_NAME_FOR;
14 import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.NAME_REL_IS_BASIONYM_FOR;
15 import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.NAME_REL_IS_CONSERVED_TYPE_OF;
16 import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.NAME_REL_IS_FEMALE_PARENT_OF;
17 import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.NAME_REL_IS_FIRST_PARENT_OF;
18 import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.NAME_REL_IS_LATER_HOMONYM_OF;
19 import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.NAME_REL_IS_LATER_VALIDATION_OF;
20 import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.NAME_REL_IS_LECTOTYPE_OF;
21 import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.NAME_REL_IS_MALE_PARENT_OF;
22 import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.NAME_REL_IS_ORTHOGRAPHIC_VARIANT_OF;
23 import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.NAME_REL_IS_REJECTED_TYPE_OF;
24 import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.NAME_REL_IS_REPLACED_SYNONYM_FOR;
25 import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.NAME_REL_IS_SECOND_PARENT_OF;
26 import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.NAME_REL_IS_TREATED_AS_LATER_HOMONYM_OF;
27 import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.NAME_REL_IS_TYPE_OF;
28 import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.NAME_REL_IS_VALIDATION_OF;
29 import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.NAME_REL_TYPE_NOT_DESIGNATED;
30
31 import java.lang.reflect.Method;
32 import java.sql.ResultSet;
33 import java.sql.SQLException;
34 import java.util.HashMap;
35 import java.util.HashSet;
36 import java.util.Map;
37 import java.util.Set;
38
39 import org.apache.log4j.Logger;
40 import org.springframework.stereotype.Component;
41
42 import eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer;
43 import eu.etaxonomy.cdm.io.berlinModel.in.validation.BerlinModelTaxonNameRelationImportValidator;
44 import eu.etaxonomy.cdm.io.common.IOValidator;
45 import eu.etaxonomy.cdm.io.common.ResultSetPartitioner;
46 import eu.etaxonomy.cdm.model.common.AnnotatableEntity;
47 import eu.etaxonomy.cdm.model.common.Annotation;
48 import eu.etaxonomy.cdm.model.common.AnnotationType;
49 import eu.etaxonomy.cdm.model.common.CdmBase;
50 import eu.etaxonomy.cdm.model.name.HybridRelationshipType;
51 import eu.etaxonomy.cdm.model.name.IBotanicalName;
52 import eu.etaxonomy.cdm.model.name.NameRelationshipType;
53 import eu.etaxonomy.cdm.model.name.NameTypeDesignationStatus;
54 import eu.etaxonomy.cdm.model.name.TaxonName;
55 import eu.etaxonomy.cdm.model.reference.Reference;
56 import eu.etaxonomy.cdm.strategy.exceptions.UnknownCdmTypeException;
57
58 /**
59 * @author a.mueller
60 * @since 20.03.2008
61 */
62 @Component
63 public class BerlinModelTaxonNameRelationImport extends BerlinModelImportBase {
64
65 private static final long serialVersionUID = 1197601822023101796L;
66 private static final Logger logger = Logger.getLogger(BerlinModelTaxonNameRelationImport.class);
67
68 private static int modCount = 5000;
69 private static final String pluralString = "name relations";
70 private static final String dbTableName = "RelName";
71
72
73 public BerlinModelTaxonNameRelationImport(){
74 super(dbTableName, pluralString);
75 }
76
77
78 @Override
79 protected String getIdQuery(BerlinModelImportState state) {
80 String nameIdTable = state.getConfig().getNameIdTable();
81 String result = super.getIdQuery(state);
82 if (isNotBlank(nameIdTable)){
83 if (state.getConfig().isEuroMed()){
84 result += " WHERE nameFk1 IN (SELECT NameId FROM %s) AND RelNameQualifierFk IN (2, 4, 5, 13, 14, 15, 17, 18, 37, 62) OR ";
85 result += " nameFk2 IN (SELECT NameId FROM %s) ";
86 //the first part is only to check if there are relations that we have maybe missed.
87 //2 is unclear, 17 should be in both, 62 links names to itself
88 result = String.format(result, nameIdTable, nameIdTable);
89 }else{
90 result += " WHERE nameFk1 IN (SELECT NameId FROM %s) OR ";
91 result += " nameFk2 IN (SELECT NameId FROM %s) ";
92 result = String.format(result, nameIdTable, nameIdTable );
93 }
94
95 }else{
96 //
97 }
98 return result;
99 }
100
101
102 @Override
103 protected String getRecordQuery(BerlinModelImportConfigurator config) {
104 String strQuery =
105 " SELECT RelName.*, FromName.nameId as name1Id, ToName.nameId as name2Id, RefDetail.Details " +
106 " FROM Name as FromName INNER JOIN " +
107 " RelName ON FromName.NameId = RelName.NameFk1 INNER JOIN " +
108 " Name AS ToName ON RelName.NameFk2 = ToName.NameId LEFT OUTER JOIN "+
109 " RefDetail ON RelName.RefDetailFK = RefDetail.RefDetailId " +
110 " WHERE (RelNameId IN ("+ID_LIST_TOKEN +"))";
111 return strQuery;
112 }
113
114 @Override
115 public boolean doPartition(ResultSetPartitioner partitioner, BerlinModelImportState state) {
116 boolean success = true ;
117 BerlinModelImportConfigurator config = state.getConfig();
118 Set<TaxonName> nameToSave = new HashSet<>();
119 Map<String, TaxonName> nameMap = partitioner.getObjectMap(BerlinModelTaxonNameImport.NAMESPACE);
120 Map<String, Reference> refMap = partitioner.getObjectMap(BerlinModelReferenceImport.REFERENCE_NAMESPACE);
121
122 ResultSet rs = partitioner.getResultSet();
123 try {
124
125 int i = 0;
126 //for each name relation
127 while (rs.next()){
128
129 if ((i++ % modCount) == 0 && i!= 1 ){ logger.info("RelName handled: " + (i-1));}
130
131 int relNameId = rs.getInt("RelNameId");
132 int name1Id = rs.getInt("name1Id");
133 int name2Id = rs.getInt("name2Id");
134 Object relRefFkObj = rs.getObject("refFk");
135 String details = rs.getString("details");
136 int relQualifierFk = rs.getInt("relNameQualifierFk");
137 String notes = rs.getString("notes");
138
139 TaxonName nameFrom = nameMap.get(String.valueOf(name1Id));
140 TaxonName nameTo = nameMap.get(String.valueOf(name2Id));
141
142
143 Reference citation = null;
144 if (relRefFkObj != null){
145 String relRefFk = String.valueOf(relRefFkObj);
146 //get nomRef
147 citation = refMap.get(relRefFk);
148 }
149
150 //TODO (preliminaryFlag = true testen
151 String microcitation = details;
152 String rule = null;
153
154 if (nameFrom != null && nameTo != null){
155 success = handleNameRelationship(success, config, name1Id, name2Id, relQualifierFk,
156 notes, nameFrom, nameTo, citation, microcitation, rule, relNameId);
157
158 if (! nameFrom.isProtectedTitleCache()){
159 nameFrom.setTitleCache(null);
160 nameFrom.getTitleCache();
161 }
162 if (! nameTo.isProtectedTitleCache()){
163 nameTo.setTitleCache(null);
164 nameTo.getTitleCache();
165 }
166 nameToSave.add(nameFrom);
167
168 //TODO
169 //ID
170 //etc.
171 }else{
172 //TODO
173 if (nameFrom == null){
174 if ( ! (config.isUseEmAreaVocabulary() && relNameId == 28159 )) {
175 logger.warn("from TaxonName " + name1Id + " for RelName (" + relNameId + " , type: " + relQualifierFk + " , toName: " + name2Id+ ") does not exist in store. ToName is: " + (nameTo == null ? "" : nameTo.getTitleCache()));
176 }
177 }
178 if (nameTo == null){
179 logger.warn("to TaxonName " + name2Id + " for RelName (" + relNameId + " , type: " + relQualifierFk + " , fromName: " + name1Id + ") does not exist in store. FromName is: " + (nameFrom == null ? "" : nameFrom.getTitleCache()));
180 }
181 success = false;
182 }
183 }
184
185
186 partitioner.startDoSave();
187 getNameService().save(nameToSave);
188
189 return success;
190 } catch (SQLException e) {
191 logger.error("SQLException:" + e);
192 return false;
193 }
194 }
195
196 /**
197 * @param success
198 * @param config
199 * @param name1Id
200 * @param name2Id
201 * @param relQualifierFk
202 * @param notes
203 * @param nameFrom
204 * @param nameTo
205 * @param citation
206 * @param microcitation
207 * @param rule
208 * @param relNameId
209 * @return
210 */
211 private boolean handleNameRelationship(boolean success,
212 BerlinModelImportConfigurator config, int name1Id, int name2Id,
213 int relQualifierFk, String notes, TaxonName nameFrom,
214 TaxonName nameTo, Reference citation,
215 String microcitation, String rule, int relNameId) {
216 AnnotatableEntity nameRelationship = null;
217 if (relQualifierFk == NAME_REL_IS_BASIONYM_FOR){
218 nameRelationship = nameTo.addBasionym(nameFrom, citation, microcitation, rule, null);
219 }else if (relQualifierFk == NAME_REL_IS_LATER_HOMONYM_OF){
220 nameRelationship = nameFrom.addRelationshipToName(nameTo, NameRelationshipType.LATER_HOMONYM(), citation, microcitation, rule, null) ;
221 }else if (relQualifierFk == NAME_REL_IS_TREATED_AS_LATER_HOMONYM_OF){
222 nameRelationship = nameFrom.addRelationshipToName(nameTo, NameRelationshipType.LATER_HOMONYM(), citation, microcitation, rule, null) ;
223 }else if (relQualifierFk == NAME_REL_IS_REPLACED_SYNONYM_FOR){
224 nameRelationship = nameFrom.addRelationshipToName(nameTo, NameRelationshipType.REPLACED_SYNONYM(), citation, microcitation, rule, null) ;
225 }else if (relQualifierFk == NAME_REL_HAS_SAME_TYPE_AS){
226 nameTo.getHomotypicalGroup().merge(nameFrom.getHomotypicalGroup());
227 }else if (relQualifierFk == NAME_REL_IS_VALIDATION_OF){
228 nameRelationship = nameTo.addRelationshipToName(nameFrom, NameRelationshipType.VALIDATED_BY_NAME(), citation, microcitation, rule, null) ;
229 }else if (relQualifierFk == NAME_REL_IS_LATER_VALIDATION_OF){
230 nameRelationship = nameTo.addRelationshipToName(nameFrom, NameRelationshipType.LATER_VALIDATED_BY_NAME(), citation, microcitation, rule, null) ;
231 }else if (relQualifierFk == NAME_REL_IS_TYPE_OF || relQualifierFk == NAME_REL_IS_REJECTED_TYPE_OF || relQualifierFk == NAME_REL_IS_CONSERVED_TYPE_OF || relQualifierFk == NAME_REL_IS_LECTOTYPE_OF || relQualifierFk == NAME_REL_TYPE_NOT_DESIGNATED ){
232 boolean isRejectedType = (relQualifierFk == NAME_REL_IS_REJECTED_TYPE_OF);
233 boolean isConservedType = (relQualifierFk == NAME_REL_IS_CONSERVED_TYPE_OF);
234 boolean isLectoType = (relQualifierFk == NAME_REL_IS_LECTOTYPE_OF);
235 boolean isNotDesignated = (relQualifierFk == NAME_REL_TYPE_NOT_DESIGNATED);
236
237 NameTypeDesignationStatus status = null;
238 String originalNameString = null;
239 //TODO addToAllNames true or false?
240 boolean addToAllNames = false;
241 if (config.getNameTypeDesignationStatusMethod() != null){
242 Method method = config.getNameTypeDesignationStatusMethod();
243 method.setAccessible(true);
244 try {
245 status = (NameTypeDesignationStatus)method.invoke(null, notes);
246 nameRelationship = nameTo.addNameTypeDesignation(nameFrom, citation, microcitation, originalNameString, status, addToAllNames);
247 } catch (Exception e) {
248 throw new RuntimeException(e);
249 }
250 }else{
251 if (isLectoType){
252 status = NameTypeDesignationStatus.LECTOTYPE();
253 }
254 if (isNotDesignated && nameTo == nameFrom){
255 nameFrom = null; //E+M case
256 }
257
258 nameRelationship = nameTo.addNameTypeDesignation(nameFrom, citation, microcitation, originalNameString, status, isRejectedType, isConservedType, isNotDesignated, addToAllNames);
259 }
260
261 }else if (relQualifierFk == NAME_REL_IS_ORTHOGRAPHIC_VARIANT_OF){
262 nameRelationship = nameFrom.addRelationshipToName(nameTo, NameRelationshipType.ORTHOGRAPHIC_VARIANT(), citation, microcitation, rule, null) ;
263 }else if (relQualifierFk == NAME_REL_IS_ALTERNATIVE_NAME_FOR){
264 nameRelationship = nameFrom.addRelationshipToName(nameTo, NameRelationshipType.ALTERNATIVE_NAME(), citation, microcitation, rule, null) ;
265 }else if (relQualifierFk == NAME_REL_IS_FIRST_PARENT_OF || relQualifierFk == NAME_REL_IS_SECOND_PARENT_OF || relQualifierFk == NAME_REL_IS_FEMALE_PARENT_OF || relQualifierFk == NAME_REL_IS_MALE_PARENT_OF){
266 //HybridRelationships
267 try {
268 HybridRelationshipType hybridRelType = BerlinModelTransformer.relNameId2HybridRel(relQualifierFk);
269 IBotanicalName parent = nameFrom;
270 IBotanicalName child = nameTo;
271
272 nameRelationship = parent.addHybridChild(child, hybridRelType, rule);
273
274 } catch (UnknownCdmTypeException e) {
275 logger.warn(e);
276 success = false;
277 }
278 }else {
279 //TODO
280 Method method = config.getNamerelationshipTypeMethod();
281 if (method != null){
282 try {
283 method.invoke(null, relQualifierFk, nameTo, nameFrom);
284 } catch (Exception e) {
285 logger.error(e.getMessage());
286 logger.warn("NameRelationship could not be imported");
287 success = false;
288 }
289 }else{
290 logger.warn("NameRelationShipType " + relQualifierFk + " not yet implemented");
291 success = false;
292 }
293 }
294 Annotation annotation = doNotes(nameRelationship, notes);
295 if (config.isEuroMed() && annotation != null){
296 if (relQualifierFk == NAME_REL_IS_BASIONYM_FOR){
297 annotation.setAnnotationType(AnnotationType.TECHNICAL());
298 }else if ((relQualifierFk == NAME_REL_IS_LECTOTYPE_OF) && !notes.contains("designated")){
299 annotation.setAnnotationType(AnnotationType.TECHNICAL());
300 }else{
301 logger.warn("Annotation type not defined for name relationship " + relNameId);
302 }
303 }else if (annotation != null){
304 logger.warn("Annotation type not defined for name relationship " + relNameId);
305 }
306 return success;
307 }
308
309 @Override
310 public Map<Object, Map<String, ? extends CdmBase>> getRelatedObjectsForPartition(ResultSet rs, BerlinModelImportState state) {
311
312 String nameSpace;
313 Set<String> idSet;
314 Map<Object, Map<String, ? extends CdmBase>> result = new HashMap<>();
315
316 try{
317 Set<String> nameIdSet = new HashSet<>();
318 Set<String> referenceIdSet = new HashSet<>();
319 Set<String> refDetailIdSet = new HashSet<>();
320 while (rs.next()){
321 handleForeignKey(rs, nameIdSet, "name1Id");
322 handleForeignKey(rs, nameIdSet, "name2Id");
323 handleForeignKey(rs, referenceIdSet, "RefFk");
324 handleForeignKey(rs, refDetailIdSet, "RefDetailFk");
325 }
326
327 //name map
328 nameSpace = BerlinModelTaxonNameImport.NAMESPACE;
329 idSet = nameIdSet;
330 Map<String, TaxonName> objectMap = getCommonService().getSourcedObjectsByIdInSourceC(TaxonName.class, idSet, nameSpace);
331 result.put(nameSpace, objectMap);
332
333 //reference map
334 nameSpace = BerlinModelReferenceImport.REFERENCE_NAMESPACE;
335 idSet = referenceIdSet;
336 Map<String, Reference> referenceMap = getCommonService().getSourcedObjectsByIdInSourceC(Reference.class, idSet, nameSpace);
337 result.put(nameSpace, referenceMap);
338
339 //refDetail map
340 nameSpace = BerlinModelRefDetailImport.REFDETAIL_NAMESPACE;
341 idSet = refDetailIdSet;
342 Map<String, Reference> refDetailMap= getCommonService().getSourcedObjectsByIdInSourceC(Reference.class, idSet, nameSpace);
343 result.put(nameSpace, refDetailMap);
344
345 } catch (SQLException e) {
346 throw new RuntimeException(e);
347 }
348 return result;
349 }
350
351 @Override
352 protected boolean doCheck(BerlinModelImportState state){
353 IOValidator<BerlinModelImportState> validator = new BerlinModelTaxonNameRelationImportValidator();
354 return validator.validate(state);
355 }
356
357 @Override
358 protected boolean isIgnore(BerlinModelImportState state){
359 return ! state.getConfig().isDoRelNames();
360 }
361 }