View Javadoc

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