minor
[cdmlib.git] / cdmlib-io / 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_TYPE_OF;
27 import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.NAME_REL_IS_VALIDATION_OF;
28 import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.NAME_REL_TYPE_NOT_DESIGNATED;
29 import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.NAME_REL_IS_TREATED_AS_LATER_HOMONYM_OF;
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.commons.lang.StringUtils;
40 import org.apache.log4j.Logger;
41 import org.springframework.stereotype.Component;
42
43 import eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer;
44 import eu.etaxonomy.cdm.io.berlinModel.in.validation.BerlinModelTaxonNameRelationImportValidator;
45 import eu.etaxonomy.cdm.io.common.IOValidator;
46 import eu.etaxonomy.cdm.io.common.ResultSetPartitioner;
47 import eu.etaxonomy.cdm.model.agent.Person;
48 import eu.etaxonomy.cdm.model.common.AnnotatableEntity;
49 import eu.etaxonomy.cdm.model.common.CdmBase;
50 import eu.etaxonomy.cdm.model.name.BotanicalName;
51 import eu.etaxonomy.cdm.model.name.HybridRelationshipType;
52 import eu.etaxonomy.cdm.model.name.NameRelationshipType;
53 import eu.etaxonomy.cdm.model.name.NameTypeDesignationStatus;
54 import eu.etaxonomy.cdm.model.name.NonViralName;
55 import eu.etaxonomy.cdm.model.name.TaxonNameBase;
56 import eu.etaxonomy.cdm.model.reference.Reference;
57 import eu.etaxonomy.cdm.strategy.exceptions.UnknownCdmTypeException;
58
59 /**
60 * @author a.mueller
61 * @created 20.03.2008
62 * @version 1.0
63 */
64 @Component
65 public class BerlinModelTaxonNameRelationImport extends BerlinModelImportBase {
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();
75 }
76
77
78
79 @Override
80 protected String getIdQuery(BerlinModelImportState state) {
81 if (StringUtils.isNotBlank(state.getConfig().getNameIdTable())){
82 String result = super.getIdQuery(state);
83 result += " WHERE nameFk1 IN (SELECT NameId FROM %s) OR ";
84 result += " nameFk2 IN (SELECT NameId FROM %s)";
85 result = String.format(result, state.getConfig().getNameIdTable(),state.getConfig().getNameIdTable() );
86 return result;
87 }else{
88 return super.getIdQuery(state);
89 }
90 }
91
92
93 /* (non-Javadoc)
94 * @see eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportBase#getRecordQuery(eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportConfigurator)
95 */
96 @Override
97 protected String getRecordQuery(BerlinModelImportConfigurator config) {
98 String strQuery =
99 " SELECT RelName.*, FromName.nameId as name1Id, ToName.nameId as name2Id, RefDetail.Details " +
100 " FROM Name as FromName INNER JOIN " +
101 " RelName ON FromName.NameId = RelName.NameFk1 INNER JOIN " +
102 " Name AS ToName ON RelName.NameFk2 = ToName.NameId LEFT OUTER JOIN "+
103 " RefDetail ON RelName.RefDetailFK = RefDetail.RefDetailId " +
104 " WHERE (RelNameId IN ("+ID_LIST_TOKEN +"))";
105 return strQuery;
106 }
107
108 /* (non-Javadoc)
109 * @see eu.etaxonomy.cdm.io.berlinModel.in.IPartitionedIO#doPartition(eu.etaxonomy.cdm.io.berlinModel.in.ResultSetPartitioner, eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportState)
110 */
111 public boolean doPartition(ResultSetPartitioner partitioner, BerlinModelImportState state) {
112 boolean success = true ;
113 BerlinModelImportConfigurator config = state.getConfig();
114 Set<TaxonNameBase> nameToSave = new HashSet<TaxonNameBase>();
115 Map<String, TaxonNameBase> nameMap = (Map<String, TaxonNameBase>) partitioner.getObjectMap(BerlinModelTaxonNameImport.NAMESPACE);
116 Map<String, Reference> biblioRefMap = partitioner.getObjectMap(BerlinModelReferenceImport.BIBLIO_REFERENCE_NAMESPACE);
117 Map<String, Reference> nomRefMap = partitioner.getObjectMap(BerlinModelReferenceImport.NOM_REFERENCE_NAMESPACE);
118
119
120 ResultSet rs = partitioner.getResultSet();
121 try {
122
123 int i = 0;
124 //for each name relation
125 while (rs.next()){
126
127 if ((i++ % modCount) == 0 && i!= 1 ){ logger.info("RelName handled: " + (i-1));}
128
129 int relNameId = rs.getInt("RelNameId");
130 int name1Id = rs.getInt("name1Id");
131 int name2Id = rs.getInt("name2Id");
132 Object relRefFkObj = rs.getObject("refFk");
133 String details = rs.getString("details");
134 int relQualifierFk = rs.getInt("relNameQualifierFk");
135 String notes = rs.getString("notes");
136
137 TaxonNameBase nameFrom = nameMap.get(String.valueOf(name1Id));
138 TaxonNameBase nameTo = nameMap.get(String.valueOf(name2Id));
139
140
141 Reference<?> citation = null;
142 if (relRefFkObj != null){
143 String relRefFk = String.valueOf(relRefFkObj);
144 //get nomRef
145 citation = getReferenceOnlyFromMaps(biblioRefMap, nomRefMap,
146 relRefFk);
147 }
148
149 //TODO (preliminaryFlag = true testen
150 String microcitation = details;
151 String rule = null;
152
153 if (nameFrom != null && nameTo != null){
154 success = handleNameRelationship(success, config, name1Id, name2Id, relQualifierFk,
155 notes, nameFrom, nameTo, citation, microcitation, rule);
156 nameFrom.setTitleCache(null);
157 nameTo.setTitleCache(null);
158 nameFrom.getTitleCache();
159 nameTo.getTitleCache();
160 nameToSave.add(nameFrom);
161
162 //TODO
163 //ID
164 //etc.
165 }else{
166 //TODO
167 if (nameFrom == null){
168 logger.warn("from TaxonName " + name1Id + " for RelName (" + relNameId + " , type: " + relQualifierFk + ") does not exist in store. ToName is: " + (nameTo == null ? "" : nameTo.getTitleCache()));
169 }
170 if (nameTo == null){
171 logger.warn("to TaxonName " + name2Id + " for RelName (" + relNameId + " , type: " + relQualifierFk + ") does not exist in store. FromName is: " + (nameFrom == null ? "" : nameFrom.getTitleCache()));
172 }
173 success = false;
174 }
175 }
176
177
178 partitioner.startDoSave();
179 getNameService().save(nameToSave);
180
181 return success;
182 } catch (SQLException e) {
183 logger.error("SQLException:" + e);
184 return false;
185 }
186 }
187
188 /**
189 * @param success
190 * @param config
191 * @param name1Id
192 * @param name2Id
193 * @param relQualifierFk
194 * @param notes
195 * @param nameFrom
196 * @param nameTo
197 * @param citation
198 * @param microcitation
199 * @param rule
200 * @return
201 */
202 private boolean handleNameRelationship(boolean success,
203 BerlinModelImportConfigurator config, int name1Id, int name2Id,
204 int relQualifierFk, String notes, TaxonNameBase nameFrom,
205 TaxonNameBase nameTo, Reference<?> citation,
206 String microcitation, String rule) {
207 AnnotatableEntity nameRelationship = null;
208 if (relQualifierFk == NAME_REL_IS_BASIONYM_FOR){
209 nameRelationship = nameTo.addBasionym(nameFrom, citation, microcitation, rule);
210 }else if (relQualifierFk == NAME_REL_IS_LATER_HOMONYM_OF){
211 nameRelationship = nameFrom.addRelationshipToName(nameTo, NameRelationshipType.LATER_HOMONYM(), citation, microcitation, rule) ;
212 }else if (relQualifierFk == NAME_REL_IS_TREATED_AS_LATER_HOMONYM_OF){
213 nameRelationship = nameFrom.addRelationshipToName(nameTo, NameRelationshipType.LATER_HOMONYM(), citation, microcitation, rule) ;
214 }else if (relQualifierFk == NAME_REL_IS_REPLACED_SYNONYM_FOR){
215 nameRelationship = nameFrom.addRelationshipToName(nameTo, NameRelationshipType.REPLACED_SYNONYM(), citation, microcitation, rule) ;
216 }else if (relQualifierFk == NAME_REL_HAS_SAME_TYPE_AS){
217 nameTo.getHomotypicalGroup().merge(nameFrom.getHomotypicalGroup());
218 }else if (relQualifierFk == NAME_REL_IS_VALIDATION_OF){
219 nameRelationship = nameTo.addRelationshipToName(nameFrom, NameRelationshipType.VALIDATED_BY_NAME(), citation, microcitation, rule) ;
220 }else if (relQualifierFk == NAME_REL_IS_LATER_VALIDATION_OF){
221 nameRelationship = nameTo.addRelationshipToName(nameFrom, NameRelationshipType.LATER_VALIDATED_BY_NAME(), citation, microcitation, rule) ;
222 }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 ){
223 boolean isRejectedType = (relQualifierFk == NAME_REL_IS_REJECTED_TYPE_OF);
224 boolean isConservedType = (relQualifierFk == NAME_REL_IS_CONSERVED_TYPE_OF);
225 boolean isLectoType = (relQualifierFk == NAME_REL_IS_LECTOTYPE_OF);
226 boolean isNotDesignated = (relQualifierFk == NAME_REL_TYPE_NOT_DESIGNATED);
227
228 NameTypeDesignationStatus status = null;
229 String originalNameString = null;
230 //TODO addToAllNames true or false?
231 boolean addToAllNames = false;
232 if (config.getNameTypeDesignationStatusMethod() != null){
233 Method method = config.getNameTypeDesignationStatusMethod();
234 method.setAccessible(true);
235 try {
236 status = (NameTypeDesignationStatus)method.invoke(null, notes);
237 nameRelationship = nameTo.addNameTypeDesignation(nameFrom, citation, microcitation, originalNameString, status, addToAllNames);
238 } catch (Exception e) {
239 throw new RuntimeException(e);
240 }
241 }else{
242 if (isLectoType){
243 status = NameTypeDesignationStatus.LECTOTYPE();
244 }
245 nameRelationship = nameTo.addNameTypeDesignation(nameFrom, citation, microcitation, originalNameString, status, isRejectedType, isConservedType, /*isLectoType,*/ isNotDesignated, addToAllNames);
246 }
247
248 }else if (relQualifierFk == NAME_REL_IS_ORTHOGRAPHIC_VARIANT_OF){
249 nameRelationship = nameFrom.addRelationshipToName(nameTo, NameRelationshipType.ORTHOGRAPHIC_VARIANT(), citation, microcitation, rule) ;
250 }else if (relQualifierFk == NAME_REL_IS_ALTERNATIVE_NAME_FOR){
251 nameRelationship = nameFrom.addRelationshipToName(nameTo, NameRelationshipType.ALTERNATIVE_NAME(), citation, microcitation, rule) ;
252 }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){
253 //HybridRelationships
254 if (! (nameTo instanceof NonViralName ) || ! (nameFrom instanceof NonViralName)){
255 logger.warn("HybridrelationshipNames ("+name1Id +"," + name2Id +") must be of type NonViralNameName but are not");
256 success = false;
257 }
258 try {
259 HybridRelationshipType hybridRelType = BerlinModelTransformer.relNameId2HybridRel(relQualifierFk);
260 BotanicalName parent = (BotanicalName)nameFrom;
261 BotanicalName child = (BotanicalName)nameTo;
262
263 nameRelationship = parent.addHybridChild(child, hybridRelType, rule);
264
265 } catch (UnknownCdmTypeException e) {
266 logger.warn(e);
267 success = false;
268 }
269 }else {
270 //TODO
271 Method method = config.getNamerelationshipTypeMethod();
272 if (method != null){
273 try {
274 method.invoke(null, relQualifierFk, nameTo, nameFrom);
275 } catch (Exception e) {
276 logger.error(e.getMessage());
277 logger.warn("NameRelationship could not be imported");
278 success = false;
279 }
280 }else{
281 logger.warn("NameRelationShipType " + relQualifierFk + " not yet implemented");
282 success = false;
283 }
284 }
285 doNotes(nameRelationship, notes);
286 return success;
287 }
288
289 /* (non-Javadoc)
290 * @see eu.etaxonomy.cdm.io.berlinModel.in.IPartitionedIO#getRelatedObjectsForPartition(java.sql.ResultSet)
291 */
292 public Map<Object, Map<String, ? extends CdmBase>> getRelatedObjectsForPartition(ResultSet rs) {
293 String nameSpace;
294 Class cdmClass;
295 Set<String> idSet;
296 Map<Object, Map<String, ? extends CdmBase>> result = new HashMap<Object, Map<String, ? extends CdmBase>>();
297
298 try{
299 Set<String> nameIdSet = new HashSet<String>();
300 Set<String> referenceIdSet = new HashSet<String>();
301 Set<String> refDetailIdSet = new HashSet<String>();
302 while (rs.next()){
303 handleForeignKey(rs, nameIdSet, "name1Id");
304 handleForeignKey(rs, nameIdSet, "name2Id");
305 handleForeignKey(rs, referenceIdSet, "RefFk");
306 handleForeignKey(rs, refDetailIdSet, "RefDetailFk");
307 }
308
309 //name map
310 nameSpace = BerlinModelTaxonNameImport.NAMESPACE;
311 cdmClass = TaxonNameBase.class;
312 idSet = nameIdSet;
313 Map<String, Person> objectMap = (Map<String, Person>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
314 result.put(nameSpace, objectMap);
315
316 //nom reference map
317 nameSpace = BerlinModelReferenceImport.NOM_REFERENCE_NAMESPACE;
318 cdmClass = Reference.class;
319 idSet = referenceIdSet;
320 Map<String, Reference> nomReferenceMap = (Map<String, Reference>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
321 result.put(nameSpace, nomReferenceMap);
322
323 //biblio reference map
324 nameSpace = BerlinModelReferenceImport.BIBLIO_REFERENCE_NAMESPACE;
325 cdmClass = Reference.class;
326 idSet = referenceIdSet;
327 Map<String, Reference> biblioReferenceMap = (Map<String, Reference>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
328 result.put(nameSpace, biblioReferenceMap);
329
330 //nom refDetail map
331 nameSpace = BerlinModelRefDetailImport.NOM_REFDETAIL_NAMESPACE;
332 cdmClass = Reference.class;
333 idSet = refDetailIdSet;
334 Map<String, Reference> nomRefDetailMap= (Map<String, Reference>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
335 result.put(nameSpace, nomRefDetailMap);
336
337 //biblio refDetail map
338 nameSpace = BerlinModelRefDetailImport.BIBLIO_REFDETAIL_NAMESPACE;
339 cdmClass = Reference.class;
340 idSet = refDetailIdSet;
341 Map<String, Reference> biblioRefDetailMap= (Map<String, Reference>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
342 result.put(nameSpace, biblioRefDetailMap);
343
344 } catch (SQLException e) {
345 throw new RuntimeException(e);
346 }
347 return result;
348 }
349
350 /* (non-Javadoc)
351 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#doCheck(eu.etaxonomy.cdm.io.common.IImportConfigurator)
352 */
353 @Override
354 protected boolean doCheck(BerlinModelImportState state){
355 IOValidator<BerlinModelImportState> validator = new BerlinModelTaxonNameRelationImportValidator();
356 return validator.validate(state);
357 }
358
359 /* (non-Javadoc)
360 * @see eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportBase#getTableName()
361 */
362 @Override
363 protected String getTableName() {
364 return dbTableName;
365 }
366
367
368 /* (non-Javadoc)
369 * @see eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportBase#getPluralString()
370 */
371 @Override
372 public String getPluralString() {
373 return pluralString;
374 }
375
376 /* (non-Javadoc)
377 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#isIgnore(eu.etaxonomy.cdm.io.common.IImportConfigurator)
378 */
379 protected boolean isIgnore(BerlinModelImportState state){
380 return ! state.getConfig().isDoRelNames();
381 }
382
383
384 }