View Javadoc

1   /**
2   * Copyright (C) 2008 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.jaxb;
11  
12  import java.io.File;
13  import java.net.URI;
14  import java.net.URISyntaxException;
15  import java.util.ArrayList;
16  import java.util.Collection;
17  import java.util.Iterator;
18  import java.util.List;
19  
20  import org.apache.log4j.Logger;
21  import org.springframework.stereotype.Component;
22  import org.springframework.transaction.TransactionStatus;
23  
24  import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
25  import eu.etaxonomy.cdm.io.common.CdmIoBase;
26  import eu.etaxonomy.cdm.io.common.ICdmIO;
27  import eu.etaxonomy.cdm.io.common.IImportConfigurator;
28  import eu.etaxonomy.cdm.model.agent.AgentBase;
29  import eu.etaxonomy.cdm.model.common.DefinedTermBase;
30  import eu.etaxonomy.cdm.model.common.LanguageStringBase;
31  import eu.etaxonomy.cdm.model.common.TermVocabulary;
32  import eu.etaxonomy.cdm.model.common.User;
33  import eu.etaxonomy.cdm.model.description.DescriptionBase;
34  import eu.etaxonomy.cdm.model.description.FeatureNode;
35  import eu.etaxonomy.cdm.model.description.FeatureTree;
36  import eu.etaxonomy.cdm.model.media.Media;
37  import eu.etaxonomy.cdm.model.name.HomotypicalGroup;
38  import eu.etaxonomy.cdm.model.name.TaxonNameBase;
39  import eu.etaxonomy.cdm.model.name.TypeDesignationBase;
40  import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
41  import eu.etaxonomy.cdm.model.reference.ReferenceBase;
42  import eu.etaxonomy.cdm.model.taxon.TaxonBase;
43  import eu.etaxonomy.cdm.model.taxon.TaxonNode;
44  import eu.etaxonomy.cdm.model.taxon.TaxonomicTree;
45  
46  /**
47   * @author a.babadshanjan
48   * @created 13.11.2008
49   * @version 1.0
50   */
51  @Component
52  public class JaxbImport extends CdmIoBase<JaxbImportState> implements ICdmIO<JaxbImportState> {
53  
54  	private static final Logger logger = Logger.getLogger(JaxbImport.class);
55  	private CdmDocumentBuilder cdmDocumentBuilder = null;
56  	
57  
58  	/** Reads data from an XML file and stores them into a CDM DB.
59       * 
60       * @param config
61       * @param stores (not used)
62       */
63  //	@Override
64  //	protected boolean doInvoke(IImportConfigurator config,
65  //			Map<String, MapWrapper<? extends CdmBase>> stores) {
66  		@Override
67  		protected boolean doInvoke(JaxbImportState state) {
68  			
69  		state.getConfig();
70  		boolean success = true;
71          URI uri = null;
72  		JaxbImportConfigurator jaxbImpConfig = (JaxbImportConfigurator)state.getConfig();
73      	
74      	String urlFileName = (String)jaxbImpConfig.getSource();
75  		logger.debug("urlFileName: " + urlFileName);
76      	try {
77      		uri = new URI(urlFileName);
78  			logger.debug("uri: " + uri.toString());
79      	} catch (URISyntaxException ex) {
80  			logger.error("File not found");
81  			return false;
82      	}
83  
84  		logger.info("Deserializing " + urlFileName + " to DB " ); //+ dbname
85  
86  		DataSet dataSet = new DataSet();
87  		
88          // unmarshalling XML file
89  		try {
90  			cdmDocumentBuilder = new CdmDocumentBuilder();
91  			logger.info("Unmarshalling " + urlFileName);
92  			File file = new File(uri);
93  			logger.debug("Absolute path: " + file.getAbsolutePath());
94  			dataSet = cdmDocumentBuilder.unmarshal(DataSet.class, file);
95  
96  		} catch (Exception e) {
97  			logger.error("Unmarshalling error");
98  			e.printStackTrace();
99  		} 
100 		
101 		// save data in DB
102 		logger.error("Saving data to DB... "); //+ dbname
103 		
104 		success = saveData(jaxbImpConfig, dataSet);
105 		
106 		return success;
107 	}
108 
109 	
110 	/**  Saves data in DB */
111 	private boolean saveData (JaxbImportConfigurator jaxbImpConfig, DataSet dataSet) {
112 
113 		boolean ret = true;
114 		Collection<TaxonBase> taxonBases;
115 		List<? extends AgentBase> agents;
116 		List<DefinedTermBase> terms;
117 		List<User> users;
118 		List<ReferenceBase> references;
119 		List<TaxonNameBase> taxonomicNames;
120 		List<DescriptionBase> descriptions;
121 		List<TypeDesignationBase> typeDesignations;
122 		List<SpecimenOrObservationBase> occurrences;
123 		List<FeatureTree> featureTrees;
124 		List<FeatureNode> featureNodes;
125 		List<Media> media;
126 		List<LanguageStringBase> languageData;
127 		List<TermVocabulary<DefinedTermBase>> termVocabularies;
128 		List<HomotypicalGroup> homotypicalGroups;
129 
130 		// Get an app controller that omits term loading
131 		// CdmApplicationController.getCdmAppController(boolean createNew, boolean omitTermLoading){
132 		//CdmApplicationController appCtr = jaxbImpConfig.getCdmAppController(false, true);
133 		TransactionStatus txStatus = startTransaction();
134 		//TransactionStatus txStatus = null;
135 
136 		// Have single transactions per service save call. Otherwise, getting
137 		// H2 HYT00 error (timeout locking table DEFINEDTERMBASE) when running from editor.
138 
139 		// If data of a certain type, such as terms, are not saved here explicitly, 
140 		// then only those data of this type that are referenced by other objects are saved implicitly.
141 		// For example, if taxa are saved all other data referenced by those taxa, such as synonyms, 
142 		// are automatically saved as well.
143 
144 		
145 		
146 		if ((jaxbImpConfig.isDoTerms() == true)
147 				&& (terms = dataSet.getTerms()).size() > 0) {
148 			//txStatus = startTransaction();
149 			ret &= saveTerms(terms);
150 			
151 			//commitTransaction(txStatus);
152 		}
153 		if ((jaxbImpConfig.isDoTermVocabularies() == true) 
154 				&& (termVocabularies = dataSet.getTermVocabularies()).size() > 0) {
155 			//txStatus = startTransaction();
156 			ret &= saveTermVocabularies(termVocabularies);
157 			
158 		}
159 		
160 		// TODO: Have separate data save methods
161 
162 //		txStatus = startTransaction();
163 //		try {
164 //			if (jaxbImpConfig.isDoLanguageData() == true) {
165 //				if ((languageData = dataSet.getLanguageData()).size() > 0) {
166 //					logger.info("Language data: " + languageData.size());
167 //					getTermService().saveLanguageDataAll(languageData);
168 //				}
169 //			}
170 //		} catch (Exception ex) {
171 //			logger.error("Error saving language data");
172 //			ret = false;
173 //		}
174 //		commitTransaction(txStatus);
175 		try {
176 			if (jaxbImpConfig.isDoUser() == true) {
177 				if ((users = dataSet.getUsers()).size() > 0) {
178 					logger.error("Users: " + users.size());
179 					getUserService().save(users);
180 					
181 				}
182 			}
183 		} catch (Exception ex) {
184 			logger.error("Error saving users");
185 			ret = false;
186 		}
187 		
188 		//txStatus = startTransaction();
189 		try {
190 			if (jaxbImpConfig.isDoAuthors() == true) {
191 				if ((agents = dataSet.getAgents()).size() > 0) {
192 					logger.error("Agents: " + agents.size());
193 					getAgentService().save((Collection)agents);
194 				}
195 			}
196 		} catch (Exception ex) {
197 			logger.error("Error saving agents");
198 			ret = false;
199 		}
200 		//commitTransaction(txStatus);
201 
202 
203 		//txStatus = startTransaction();
204 		try {
205 			if (jaxbImpConfig.getDoReferences() != IImportConfigurator.DO_REFERENCES.NONE) {
206 				if ((references = dataSet.getReferences()).size() > 0) {
207 					logger.error("References: " + references.size());
208 					getReferenceService().save(references);
209 					logger.error("ready...");
210 				}
211 			}
212 		} catch (Exception ex) {
213 			ex.printStackTrace();
214 			logger.error("Error saving references");
215 			ret = false;
216 		}
217 		//commitTransaction(txStatus);
218 
219 
220 		//txStatus = startTransaction();
221 		try {
222 			if (jaxbImpConfig.isDoTaxonNames() == true) {
223 				if ((taxonomicNames = dataSet.getTaxonomicNames()).size() > 0) {
224 					logger.error("Taxonomic names: " + taxonomicNames.size());
225 					getNameService().save(taxonomicNames);
226 				}
227 			}
228 		} catch (Exception ex) {
229 			logger.error("Error saving taxon names");
230 			ret = false;
231 		}
232 		//commitTransaction(txStatus);
233 
234 
235 		//txStatus = startTransaction();
236 		try {
237 			if (jaxbImpConfig.isDoHomotypicalGroups() == true) {
238 				if ((homotypicalGroups = dataSet.getHomotypicalGroups()).size() > 0) {
239 					logger.error("Homotypical groups: " + homotypicalGroups.size());
240 					getNameService().saveAllHomotypicalGroups(homotypicalGroups);
241 					
242 				}
243 			}
244 		} catch (Exception ex) {
245 			logger.error("Error saving homotypical groups");
246 			ret = false;
247 		}
248 		//commitTransaction(txStatus);
249 
250 
251 		//txStatus = startTransaction();
252 		// Need to get the taxa and the synonyms here.
253 		try {
254 			if (jaxbImpConfig.isDoTaxa() == true) {
255 				if ((taxonBases = dataSet.getTaxonBases()).size() > 0) {
256 					logger.error("Taxon bases: " + taxonBases.size());
257 					Iterator <TaxonBase> taxBases = taxonBases.iterator();
258 					getTaxonService().save(taxonBases);
259 					/*while (taxBases.hasNext()){
260 						getTaxonService().save(taxBases.next());
261 					}*/
262 					//getTaxonService().saveTaxonAll(taxonBases);
263 				}
264 			}
265 		} catch (Exception ex) {
266 			logger.error("Error saving taxa");
267 			ex.printStackTrace();
268 			ret = false;
269 		}
270 		//commitTransaction(txStatus);
271 
272 
273 		//txStatus = startTransaction();
274 		// NomenclaturalStatus, TypeDesignations
275 		try {
276 			if (jaxbImpConfig.isDoTypeDesignations() == true) {
277 				if ((typeDesignations = dataSet.getTypeDesignations()).size() > 0) {
278 					logger.error("Type Designations: " + typeDesignations.size());
279 					getNameService().saveTypeDesignationAll(typeDesignations);
280 				}
281 			}
282 		} catch (Exception ex) {
283 			logger.error("Error saving type designations");
284 			ret = false;
285 		}
286 		//commitTransaction(txStatus);
287 
288 
289 		// TODO: Implement dataSet.getDescriptions() and IDescriptionService.saveDescriptionAll()
290 //		if ((descriptions = dataSet.getDescriptions()) != null) {
291 //		logger.info("Saving " + descriptions.size() + " descriptions");
292 //		getDescriptionService().saveDescriptionAll(descriptions);
293 //		}
294 
295 		//txStatus = startTransaction();
296 		try {
297 			if (jaxbImpConfig.isDoOccurrence() == true) {
298 				if ((occurrences = dataSet.getOccurrences()).size() > 0) {
299 					logger.error("Occurrences: " + occurrences.size());
300 					getOccurrenceService().save(occurrences);
301 				}
302 			}
303 		} catch (Exception ex) {
304 			logger.error("Error saving occurrences");
305 			ret = false;
306 		}
307 		//commitTransaction(txStatus);
308 
309 
310 		//txStatus = startTransaction();
311 		try {
312 			if (jaxbImpConfig.isDoFeatureData() == true) {
313 				if ((featureTrees = dataSet.getFeatureTrees()).size() > 0) {
314 					logger.error("Feature data: " + featureTrees.size());
315 					getFeatureTreeService().save(featureTrees);
316 				}
317 			}
318 		} catch (Exception ex) {
319 			logger.error("Error saving feature data");
320 			ret = false;
321 		}
322 		//commitTransaction(txStatus);
323 
324 
325 		//txStatus = startTransaction();
326 		try {
327 			if (jaxbImpConfig.isDoMedia() == true) {
328 				if ((media = dataSet.getMedia()).size() > 0) {
329 					logger.error("Media: " + media.size());
330 					getMediaService().save(media);
331 				}
332 			}
333 		} catch (Exception ex) {
334 			logger.error("Error saving media");
335 			ret = false;
336 		}
337 		
338 		if (jaxbImpConfig.isDoTaxonomicTreeData() == true) {
339 			logger.error("# Taxonomic Tree");
340 			
341 			Collection<TaxonNode> nodes = dataSet.getTaxonNodes();
342 			Collection<TaxonomicTree> taxonTrees = dataSet.getTaxonomicTrees();
343 			getTaxonTreeService().saveTaxonNodeAll(nodes);
344 			for (TaxonomicTree tree: taxonTrees){
345 				getTaxonTreeService().saveOrUpdate(tree);
346 			}
347 		}
348 		
349 		
350 		commitTransaction(txStatus);
351 		logger.info("All data saved");
352 
353 		return ret;
354 
355 	}
356 	
357 	
358 	private boolean saveTermVocabularies(
359 			List<TermVocabulary<DefinedTermBase>> termVocabularies) {
360 
361 		boolean success = true;
362 		logger.info("Term vocabularies: " + termVocabularies.size());
363 		try {
364 			getVocabularyService().save((List)termVocabularies);
365 		} catch (Exception ex) {
366 			logger.error("Error saving term vocabularies");
367 			success = false;
368 		}
369 		return success;
370 	}
371 
372 	private boolean saveTerms(List<DefinedTermBase> terms) {
373 
374 		boolean success = true;
375 		logger.info("Terms: " + terms.size());
376 		try {
377 			getTermService().save(terms);
378 		} catch (Exception ex) {
379 			logger.error("Error saving terms");
380 			ex.printStackTrace();
381 			success = false;
382 		}
383 		return success;
384 	}
385 
386 	
387 	@Override
388 	protected boolean doCheck(JaxbImportState state) {
389 		boolean result = true;
390 		logger.warn("No check implemented for Jaxb import");
391 		return result;
392 	}
393 	
394 
395 	@Override
396 	protected boolean isIgnore(JaxbImportState state) {
397 		return false;
398 	}
399 }