View Javadoc

1   // $Id$
2   /**
3   * Copyright (C) 2009 EDIT
4   * European Distributed Institute of Taxonomy 
5   * http://www.e-taxonomy.eu
6   * 
7   * The contents of this file are subject to the Mozilla Public License Version 1.1
8   * See LICENSE.TXT at the top of this package for the full license terms.
9   */
10  package eu.etaxonomy.cdm.io.pesi.out;
11  
12  import java.sql.SQLException;
13  import java.util.ArrayList;
14  import java.util.List;
15  import java.util.Set;
16  
17  import org.apache.log4j.Logger;
18  import org.springframework.stereotype.Component;
19  import org.springframework.transaction.TransactionStatus;
20  
21  import eu.etaxonomy.cdm.io.berlinModel.out.mapper.DbExtensionMapper;
22  import eu.etaxonomy.cdm.io.berlinModel.out.mapper.DbStringMapper;
23  import eu.etaxonomy.cdm.io.berlinModel.out.mapper.DbTimePeriodMapper;
24  import eu.etaxonomy.cdm.io.berlinModel.out.mapper.IdMapper;
25  import eu.etaxonomy.cdm.io.berlinModel.out.mapper.MethodMapper;
26  import eu.etaxonomy.cdm.io.common.Source;
27  import eu.etaxonomy.cdm.io.common.IImportConfigurator.DO_REFERENCES;
28  import eu.etaxonomy.cdm.io.erms.ErmsTransformer;
29  import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
30  import eu.etaxonomy.cdm.model.common.CdmBase;
31  import eu.etaxonomy.cdm.model.common.ExtensionType;
32  import eu.etaxonomy.cdm.model.common.IdentifiableSource;
33  import eu.etaxonomy.cdm.model.reference.ReferenceBase;
34  
35  /**
36   * The export class for {@link eu.etaxonomy.cdm.model.reference.ReferenceBase References}.<p>
37   * Inserts into DataWarehouse database table <code>Source</code>.
38   * @author e.-m.lee
39   * @date 11.02.2010
40   *
41   */
42  @Component
43  @SuppressWarnings("unchecked")
44  public class PesiSourceExport extends PesiExportBase {
45  	private static final Logger logger = Logger.getLogger(PesiSourceExport.class);
46  	private static final Class<? extends CdmBase> standardMethodParameter = ReferenceBase.class;
47  
48  	private static int modCount = 1000;
49  	private static final String dbTableName = "Source";
50  	private static final String pluralString = "Sources";
51  	List<Integer> storedSourceIds = new ArrayList<Integer>();
52  
53  	public PesiSourceExport() {
54  		super();
55  	}
56  
57  	/* (non-Javadoc)
58  	 * @see eu.etaxonomy.cdm.io.pesi.out.PesiExportBase#getStandardMethodParameter()
59  	 */
60  	@Override
61  	public Class<? extends CdmBase> getStandardMethodParameter() {
62  		return standardMethodParameter;
63  	}
64  
65  	/* (non-Javadoc)
66  	 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#doCheck(eu.etaxonomy.cdm.io.common.IoStateBase)
67  	 */
68  	@Override
69  	protected boolean doCheck(PesiExportState state) {
70  		boolean result = true;
71  		return result;
72  	}
73  
74  	/**
75  	 * Checks whether a sourceId was stored already.
76  	 * @param sourceId
77  	 * @return
78  	 */
79  	protected boolean isStoredSourceId(Integer sourceId) {
80  		if (storedSourceIds.contains(sourceId)) {
81  			return true;
82  		} else {
83  			return false;
84  		}
85  	}
86  
87  	/**
88  	 * Adds a sourceId to the list of storedSourceIds.
89  	 * @param sourceId
90  	 */
91  	protected void addToStoredSourceIds(Integer sourceId) {
92  		if (! storedSourceIds.contains(sourceId)) {
93  			this.storedSourceIds.add(sourceId);
94  		}
95  	}
96  
97  	/* (non-Javadoc)
98  	 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#doInvoke(eu.etaxonomy.cdm.io.common.IoStateBase)
99  	 */
100 	@Override
101 	protected boolean doInvoke(PesiExportState state) {
102 		try{
103 			logger.error("*** Started Making " + pluralString + " ...");
104 
105 			PesiExportConfigurator pesiExportConfigurator = state.getConfig();
106 			
107 			// Get the limit for objects to save within a single transaction.
108 			int limit = pesiExportConfigurator.getLimitSave();
109 
110 			// Stores whether this invoke was successful or not.
111 			boolean success = true ;
112 
113 			// PESI: Clear the database table Source.
114 			doDelete(state);
115 
116 			// Get specific mappings: (CDM) Reference -> (PESI) Source
117 			PesiExportMapping mapping = getMapping();
118 
119 			// Initialize the db mapper
120 			mapping.initialize(state);
121 
122 			// Create the Sources
123 			int count = 0;
124 			int pastCount = 0;
125 			TransactionStatus txStatus = null;
126 			List<ReferenceBase> list = null;
127 
128 //			logger.error("PHASE 1...");
129 			// Start transaction
130 			txStatus = startTransaction(true);
131 			logger.error("Started new transaction. Fetching some " + pluralString + " (max: " + limit + ") ...");
132 			while ((list = getReferenceService().list(null, limit, count, null, null)).size() > 0) {
133 
134 				logger.error("Fetched " + list.size() + " " + pluralString + ". Exporting...");
135 				for (ReferenceBase<?> reference : list) {
136 					doCount(count++, modCount, pluralString);
137 					success &= mapping.invoke(reference);
138 				}
139 
140 				// Commit transaction
141 				commitTransaction(txStatus);
142 				logger.error("Committed transaction.");
143 				logger.error("Exported " + (count - pastCount) + " " + pluralString + ". Total: " + count);
144 				pastCount = count;
145 
146 				// Start transaction
147 				txStatus = startTransaction(true);
148 				logger.error("Started new transaction. Fetching some " + pluralString + " (max: " + limit + ") ...");
149 			}
150 			if (list.size() == 0) {
151 				logger.error("No " + pluralString + " left to fetch.");
152 			}
153 			// Commit transaction
154 			commitTransaction(txStatus);
155 			logger.error("Committed transaction.");
156 			
157 			logger.error("*** Finished Making " + pluralString + " ..." + getSuccessString(success));
158 
159 			return success;
160 		} catch (SQLException e) {
161 			e.printStackTrace();
162 			logger.error(e.getMessage());
163 			return false;
164 		}
165 	}
166 
167 	/**
168 	 * Deletes all entries of database tables related to <code>Source</code>.
169 	 * @param state The {@link PesiExportState PesiExportState}.
170 	 * @return Whether the delete operation was successful or not.
171 	 */
172 	protected boolean doDelete(PesiExportState state) {
173 		PesiExportConfigurator pesiConfig = (PesiExportConfigurator) state.getConfig();
174 		
175 		String sql;
176 		Source destination =  pesiConfig.getDestination();
177 
178 		// Clear Occurrences
179 		sql = "DELETE FROM Occurrence";
180 		destination.setQuery(sql);
181 		destination.update(sql);
182 
183 		// Clear Taxa
184 		sql = "DELETE FROM Taxon";
185 		destination.setQuery(sql);
186 		destination.update(sql);
187 
188 		// Clear Sources
189 		sql = "DELETE FROM " + dbTableName;
190 		destination.setQuery(sql);
191 		destination.update(sql);
192 		
193 		return true;
194 	}
195 	
196 	/**
197 	 * Returns the <code>IMIS_Id</code> attribute.
198 	 * @param reference The {@link ReferenceBase Reference}.
199 	 * @return The <code>IMIS_Id</code> attribute.
200 	 * @see MethodMapper
201 	 */
202 	@SuppressWarnings("unused")
203 	private static Integer getIMIS_Id(ReferenceBase<?> reference) {
204 		return null;
205 	}
206 	
207 	/**
208 	 * Returns the <code>SourceCategoryFK</code> attribute.
209 	 * @param reference The {@link ReferenceBase Reference}.
210 	 * @return The <code>SourceCategoryFK</code> attribute.
211 	 * @see MethodMapper
212 	 */
213 	@SuppressWarnings("unused")
214 	private static Integer getSourceCategoryFK(ReferenceBase<?> reference) {
215 		Integer result = null;
216 		try {
217 		result = PesiTransformer.reference2SourceCategoryFK(reference);
218 		} catch (Exception e) {
219 			e.printStackTrace();
220 		}
221 		return result;
222 	}
223 	
224 	/**
225 	 * Returns the <code>SourceCategoryCache</code> attribute.
226 	 * @param reference The {@link ReferenceBase Reference}.
227 	 * @return The <code>SourceCategoryCache</code> attribute.
228 	 * @see MethodMapper
229 	 */
230 	@SuppressWarnings("unused")
231 	private static String getSourceCategoryCache(ReferenceBase<?> reference) {
232 		String result = null;
233 		try {
234 		result = PesiTransformer.getSourceCategoryCache(reference);
235 		} catch (Exception e) {
236 			e.printStackTrace();
237 		}
238 		return result;
239 	}
240 
241 	/**
242 	 * Returns the <code>Name</code> attribute. The corresponding CDM attribute is <code>title</code>.
243 	 * @param reference The {@link ReferenceBase Reference}.
244 	 * @return The <code>Name</code> attribute.
245 	 * @see MethodMapper
246 	 */
247 	@SuppressWarnings("unused")
248 	private static String getName(ReferenceBase<?> reference) {
249 		if (reference != null) {
250 			return reference.getTitleCache(); // was getTitle()
251 		} else {
252 			return null;
253 		}
254 	}
255 	
256 	/**
257 	 * Returns the <code>AuthorString</code> attribute. The corresponding CDM attribute is the <code>titleCache</code> of an <code>authorTeam</code>.
258 	 * @param reference The {@link ReferenceBase Reference}.
259 	 * @return The <code>AuthorString</code> attribute.
260 	 * @see MethodMapper
261 	 */
262 	@SuppressWarnings("unused")
263 	private static String getAuthorString(ReferenceBase<?> reference) {
264 		String result = null;
265 
266 		try {
267 		if (reference != null) {
268 			TeamOrPersonBase team = reference.getAuthorTeam();
269 			if (team != null) {
270 				result = team.getTitleCache();
271 //				result = team.getNomenclaturalTitle();
272 			} else {
273 				result = null;
274 			}
275 		}
276 		} catch (Exception e) {
277 			e.printStackTrace();
278 		}
279 		
280 		return result;
281 	}
282 
283 	/**
284 	 * Returns the <code>NomRefCache</code> attribute. The corresponding CDM attribute is <code>titleCache</code>.
285 	 * @param reference The {@link ReferenceBase Reference}.
286 	 * @return The <code>NomRefCache</code> attribute.
287 	 * @see MethodMapper
288 	 */
289 	@SuppressWarnings("unused")
290 	private static String getNomRefCache(ReferenceBase<?> reference) {
291 		return null;
292 //		if (reference != null) {
293 //			return reference.getTitleCache();
294 //		} else {
295 //			return null;
296 //		}
297 	}
298 
299 	/**
300 	 * Returns the <code>Notes</code> attribute.
301 	 * @param reference The {@link ReferenceBase Reference}.
302 	 * @return The <code>Notes</code> attribute.
303 	 * @see MethodMapper
304 	 */
305 	@SuppressWarnings("unused")
306 	private static String getNotes(ReferenceBase<?> reference) {
307 		// TODO
308 		return null;
309 	}
310 
311 	/**
312 	 * Returns the <code>RefIdInSource</code> attribute.
313 	 * @param reference The {@link ReferenceBase Reference}.
314 	 * @return The <code>RefIdInSource</code> attribute.
315 	 * @see MethodMapper
316 	 */
317 	@SuppressWarnings("unused")
318 	private static String getRefIdInSource(ReferenceBase<?> reference) {
319 		String result = null;
320 
321 		try {
322 		if (reference != null) {
323 			Set<IdentifiableSource> sources = reference.getSources();
324 			if (sources.size() == 1) {
325 				result = sources.iterator().next().getIdInSource();
326 			} else if (sources.size() > 1) {
327 				logger.warn("Reference has multiple IdentifiableSources: " + reference.getUuid() + " (" + reference.getTitleCache() + ")");
328 				int count = 1;
329 				for (IdentifiableSource source : sources) {
330 					result += source.getIdInSource();
331 					if (count < sources.size()) {
332 						result += "; ";
333 					}
334 					count++;
335 				}
336 			}
337 		}
338 		} catch (Exception e) {
339 			e.printStackTrace();
340 		}
341 
342 		return result;
343 	}
344 
345 	/**
346 	 * Returns the <code>OriginalDB</code> attribute. The corresponding CDM attribute is the <code>titleCache</code> of a <code>citation</code>.
347 	 * @param reference The {@link ReferenceBase Reference}.
348 	 * @return The <code>OriginalDB</code> attribute.
349 	 * @see MethodMapper
350 	 */
351 	@SuppressWarnings("unused")
352 	private static String getOriginalDB(ReferenceBase<?> reference) {
353 		String result = "";
354 
355 		try {
356 		if (reference != null) {
357 			Set<IdentifiableSource> sources = reference.getSources();
358 			if (sources.size() == 1) {
359 				ReferenceBase citation = sources.iterator().next().getCitation();
360 				if (citation != null) {
361 					result = PesiTransformer.databaseString2Abbreviation(citation.getTitleCache()); //or just title
362 				} else {
363 					logger.warn("OriginalDB can not be determined because the citation of this source is NULL: " + sources.iterator().next().getUuid());
364 				}
365 			} else if (sources.size() > 1) {
366 				logger.warn("Taxon has multiple IdentifiableSources: " + reference.getUuid() + " (" + reference.getTitleCache() + ")");
367 				int count = 1;
368 				for (IdentifiableSource source : sources) {
369 					ReferenceBase citation = source.getCitation();
370 					if (citation != null) {
371 						result += PesiTransformer.databaseString2Abbreviation(citation.getTitleCache());
372 						if (count < sources.size()) {
373 							result += "; ";
374 						}
375 						count++;
376 					}
377 				}
378 			} else {
379 				result = null;
380 			}
381 		}
382 		} catch (Exception e) {
383 			e.printStackTrace();
384 		}
385 
386 		return result;
387 	}
388 
389 	/* (non-Javadoc)
390 	 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#isIgnore(eu.etaxonomy.cdm.io.common.IoStateBase)
391 	 */
392 	@Override
393 	protected boolean isIgnore(PesiExportState state) {
394 		return ! (((PesiExportConfigurator) state.getConfig()).getDoReferences().equals(DO_REFERENCES.ALL));
395 	}
396 
397 	/**
398 	 * Returns the CDM to PESI specific export mappings.
399 	 * @return The {@link PesiExportMapping PesiExportMapping}.
400 	 */
401 	private PesiExportMapping getMapping() {
402 		PesiExportMapping mapping = new PesiExportMapping(dbTableName);
403 		ExtensionType extensionType = null;
404 		
405 		mapping.addMapper(IdMapper.NewInstance("SourceId"));
406 		
407 		// IMIS_Id
408 		extensionType = (ExtensionType)getTermService().find(ErmsTransformer.IMIS_UUID);
409 		if (extensionType != null) {
410 			mapping.addMapper(DbExtensionMapper.NewInstance(extensionType, "IMIS_Id"));
411 		} else {
412 			mapping.addMapper(MethodMapper.NewInstance("IMIS_Id", this));
413 		}
414 		
415 		mapping.addMapper(MethodMapper.NewInstance("SourceCategoryFK", this));
416 		mapping.addMapper(MethodMapper.NewInstance("SourceCategoryCache", this));
417 		mapping.addMapper(MethodMapper.NewInstance("Name", this));
418 		mapping.addMapper(DbStringMapper.NewInstance("referenceAbstract", "Abstract"));
419 		mapping.addMapper(DbStringMapper.NewInstance("title", "Title"));
420 		mapping.addMapper(MethodMapper.NewInstance("AuthorString", this));
421 		mapping.addMapper(DbTimePeriodMapper.NewInstance("datePublished", "RefYear"));
422 		mapping.addMapper(MethodMapper.NewInstance("NomRefCache", this));
423 		mapping.addMapper(DbStringMapper.NewInstance("uri", "Link"));
424 		mapping.addMapper(MethodMapper.NewInstance("Notes", this));
425 		mapping.addMapper(MethodMapper.NewInstance("RefIdInSource", this));
426 		mapping.addMapper(MethodMapper.NewInstance("OriginalDB", this));
427 
428 		return mapping;
429 	}
430 
431 }