Project

General

Profile

Download (11.9 KB) Statistics
| Branch: | Revision:
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.globis;
11

    
12
import java.lang.reflect.Method;
13
import java.sql.ResultSet;
14
import java.sql.SQLException;
15
import java.sql.Timestamp;
16
import java.util.HashSet;
17
import java.util.Set;
18
import java.util.UUID;
19

    
20
import org.apache.commons.lang.StringUtils;
21
import org.apache.log4j.Logger;
22
import org.joda.time.DateTime;
23

    
24
import eu.etaxonomy.cdm.io.common.CdmImportBase;
25
import eu.etaxonomy.cdm.io.common.ICdmIO;
26
import eu.etaxonomy.cdm.io.common.IImportConfigurator.EDITOR;
27
import eu.etaxonomy.cdm.io.common.IPartitionedIO;
28
import eu.etaxonomy.cdm.io.common.ImportHelper;
29
import eu.etaxonomy.cdm.io.common.ResultSetPartitioner;
30
import eu.etaxonomy.cdm.io.common.Source;
31
import eu.etaxonomy.cdm.io.common.mapping.DbImportMapping;
32
import eu.etaxonomy.cdm.io.common.mapping.UndefinedTransformerMethodException;
33
import eu.etaxonomy.cdm.model.common.AnnotatableEntity;
34
import eu.etaxonomy.cdm.model.common.Annotation;
35
import eu.etaxonomy.cdm.model.common.AnnotationType;
36
import eu.etaxonomy.cdm.model.common.CdmBase;
37
import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
38
import eu.etaxonomy.cdm.model.common.Language;
39
import eu.etaxonomy.cdm.model.common.User;
40
import eu.etaxonomy.cdm.model.location.WaterbodyOrCountry;
41
import eu.etaxonomy.cdm.model.name.ZoologicalName;
42
import eu.etaxonomy.cdm.strategy.exceptions.StringNotParsableException;
43
import eu.etaxonomy.cdm.strategy.parser.INonViralNameParser;
44
import eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl;
45

    
46
/**
47
 * @author a.mueller
48
 * @created 20.03.2008
49
 * @version 1.0
50
 */
51
public abstract class GlobisImportBase<CDM_BASE extends CdmBase> extends CdmImportBase<GlobisImportConfigurator, GlobisImportState> implements ICdmIO<GlobisImportState>, IPartitionedIO<GlobisImportState> {
52
	private static final Logger logger = Logger.getLogger(GlobisImportBase.class);
53
	
54
	public static final UUID ID_IN_SOURCE_EXT_UUID = UUID.fromString("23dac094-e793-40a4-bad9-649fc4fcfd44");
55
	
56
	//NAMESPACES
57
	
58
	protected static final String REFERENCE_NAMESPACE = "Literatur";
59
	protected static final String TAXON_NAMESPACE = "current_species";
60
	protected static final String COLLECTION_NAMESPACE = "Collection";
61
	
62
	private String pluralString;
63
	private String dbTableName;
64
	//TODO needed?
65
	private Class cdmTargetClass;
66

    
67
	private INonViralNameParser parser = NonViralNameParserImpl.NewInstance();
68

    
69
	
70
	/**
71
	 * @param dbTableName
72
	 * @param dbTableName2 
73
	 */
74
	public GlobisImportBase(String pluralString, String dbTableName, Class cdmTargetClass) {
75
		this.pluralString = pluralString;
76
		this.dbTableName = dbTableName;
77
		this.cdmTargetClass = cdmTargetClass;
78
	}
79

    
80
	protected void doInvoke(GlobisImportState state){
81
		logger.info("start make " + getPluralString() + " ...");
82
		GlobisImportConfigurator config = state.getConfig();
83
		Source source = config.getSource();
84
			
85
		String strIdQuery = getIdQuery();
86
		String strRecordQuery = getRecordQuery(config);
87

    
88
		int recordsPerTransaction = config.getRecordsPerTransaction();
89
		try{
90
			ResultSetPartitioner partitioner = ResultSetPartitioner.NewInstance(source, strIdQuery, strRecordQuery, recordsPerTransaction);
91
			while (partitioner.nextPartition()){
92
				partitioner.doPartition(this, state);
93
			}
94
		} catch (SQLException e) {
95
			logger.error("SQLException:" +  e);
96
			state.setUnsuccessfull();
97
		}
98
		
99
		logger.info("end make " + getPluralString() + " ... " + getSuccessString(true));
100
		return;
101
	}
102

    
103
	/**
104
	 * @param authorAndYear
105
	 * @param zooName
106
	 */
107
	protected void handleAuthorAndYear(String authorAndYear, ZoologicalName zooName) {
108
		if (isBlank(authorAndYear)){
109
			return;
110
		}
111
		try {
112
			String doubtfulAuthorAndYear = null;
113
			if(authorAndYear.matches(".+\\,\\s\\[\\d{4}\\].*")){
114
				doubtfulAuthorAndYear = authorAndYear;
115
				authorAndYear = authorAndYear.replace("[", "").replace("]", "");
116
			}
117
			if (authorAndYear.contains("?")){
118
				authorAndYear = authorAndYear.replace("H?bner", "H\u00fcbner");
119
				authorAndYear = authorAndYear.replace("Oberth?r", "Oberth\u00fcr");
120
				//TODO remove
121
				authorAndYear = authorAndYear.replace("?", "");
122
				
123
			}
124
			
125
			parser.parseAuthors(zooName, authorAndYear);
126
			if (doubtfulAuthorAndYear != null){
127
				zooName.setAuthorshipCache(doubtfulAuthorAndYear, true);
128
			}
129
			
130
		} catch (StringNotParsableException e) {
131
			logger.warn("Author could not be parsed: " + authorAndYear);
132
			zooName.setAuthorshipCache(authorAndYear, true);
133
		}
134
	}
135
	
136

    
137
	/**
138
	 * @param state
139
	 * @param countryStr
140
	 * @return
141
	 */
142
	protected WaterbodyOrCountry getCountry(GlobisImportState state, String countryStr) {
143
		WaterbodyOrCountry country = WaterbodyOrCountry.getWaterbodyOrCountryByLabel(countryStr);
144
		if (country == null){
145
			try {
146
				country = (WaterbodyOrCountry)state.getTransformer().getNamedAreaByKey(countryStr);
147
			} catch (UndefinedTransformerMethodException e) {
148
				e.printStackTrace();
149
			}
150
		}
151
		return country;
152
	}
153

    
154
	
155

    
156
	public boolean doPartition(ResultSetPartitioner partitioner, GlobisImportState state) {
157
		boolean success = true ;
158
		Set objectsToSave = new HashSet();
159
		
160
 		DbImportMapping<?, ?> mapping = getMapping();
161
		mapping.initialize(state, cdmTargetClass);
162
		
163
		ResultSet rs = partitioner.getResultSet();
164
		try{
165
			while (rs.next()){
166
				success &= mapping.invoke(rs,objectsToSave);
167
			}
168
		} catch (SQLException e) {
169
			logger.error("SQLException:" +  e);
170
			return false;
171
		}
172
	
173
		partitioner.startDoSave();
174
		getCommonService().save(objectsToSave);
175
		return success;
176
	}
177

    
178

    
179
	
180
	/**
181
	 * @return
182
	 */
183
	protected /*abstract*/ DbImportMapping<?, ?> getMapping(){
184
		return null;
185
	}
186
	
187
	/**
188
	 * @return
189
	 */
190
	protected abstract String getRecordQuery(GlobisImportConfigurator config);
191

    
192
	/**
193
	 * @return
194
	 */
195
	protected String getIdQuery(){
196
		String result = " SELECT id FROM " + getTableName();
197
		return result;
198
	}
199
	
200
	/* (non-Javadoc)
201
	 * @see eu.etaxonomy.cdm.io.berlinModel.in.IPartitionedIO#getPluralString()
202
	 */
203
	public String getPluralString(){
204
		return pluralString;
205
	}
206

    
207
	/**
208
	 * @return
209
	 */
210
	protected String getTableName(){
211
		return this.dbTableName;
212
	}
213
	
214
	protected boolean doIdCreatedUpdatedNotes(GlobisImportState state, IdentifiableEntity identifiableEntity, ResultSet rs, long id, String namespace)
215
			throws SQLException{
216
		boolean success = true;
217
		//id
218
		success &= ImportHelper.setOriginalSource(identifiableEntity, state.getTransactionalSourceReference(), id, namespace);
219
		//createdUpdateNotes
220
		success &= doCreatedUpdatedNotes(state, identifiableEntity, rs, namespace);
221
		return success;
222
	}
223
	
224
	
225
	protected boolean doCreatedUpdatedNotes(GlobisImportState state, AnnotatableEntity annotatableEntity, ResultSet rs, String namespace)
226
			throws SQLException{
227

    
228
		GlobisImportConfigurator config = state.getConfig();
229
		Object createdWhen = rs.getObject("Created_When");
230
		String createdWho = rs.getString("Created_Who");
231
		Object updatedWhen = null;
232
		String updatedWho = null;
233
		try {
234
			updatedWhen = rs.getObject("Updated_When");
235
			updatedWho = rs.getString("Updated_who");
236
		} catch (SQLException e) {
237
			//Table "Name" has no updated when/who
238
		}
239
		String notes = rs.getString("notes");
240
		
241
		boolean success  = true;
242
		
243
		//Created When, Who, Updated When Who
244
		if (config.getEditor() == null || config.getEditor().equals(EDITOR.NO_EDITORS)){
245
			//do nothing
246
		}else if (config.getEditor().equals(EDITOR.EDITOR_AS_ANNOTATION)){
247
			String createdAnnotationString = "Berlin Model record was created By: " + String.valueOf(createdWho) + " (" + String.valueOf(createdWhen) + ") ";
248
			if (updatedWhen != null && updatedWho != null){
249
				createdAnnotationString += " and updated By: " + String.valueOf(updatedWho) + " (" + String.valueOf(updatedWhen) + ")";
250
			}
251
			Annotation annotation = Annotation.NewInstance(createdAnnotationString, Language.DEFAULT());
252
			annotation.setCommentator(config.getCommentator());
253
			annotation.setAnnotationType(AnnotationType.TECHNICAL());
254
			annotatableEntity.addAnnotation(annotation);
255
		}else if (config.getEditor().equals(EDITOR.EDITOR_AS_EDITOR)){
256
			User creator = getUser(createdWho, state);
257
			User updator = getUser(updatedWho, state);
258
			DateTime created = getDateTime(createdWhen);
259
			DateTime updated = getDateTime(updatedWhen);
260
			annotatableEntity.setCreatedBy(creator);
261
			annotatableEntity.setUpdatedBy(updator);
262
			annotatableEntity.setCreated(created);
263
			annotatableEntity.setUpdated(updated);
264
		}else {
265
			logger.warn("Editor type not yet implemented: " + config.getEditor());
266
		}
267
		
268
		
269
		//notes
270
		if (StringUtils.isNotBlank(notes)){
271
			String notesString = String.valueOf(notes);
272
			if (notesString.length() > 65530 ){
273
				notesString = notesString.substring(0, 65530) + "...";
274
				logger.warn("Notes string is longer than 65530 and was truncated: " + annotatableEntity);
275
			}
276
			Annotation notesAnnotation = Annotation.NewInstance(notesString, null);
277
			//notesAnnotation.setAnnotationType(AnnotationType.EDITORIAL());
278
			//notes.setCommentator(bmiConfig.getCommentator());
279
			annotatableEntity.addAnnotation(notesAnnotation);
280
		}
281
		return success;
282
	}
283
	
284
	private User getUser(String userString, GlobisImportState state){
285
		if (StringUtils.isBlank(userString)){
286
			return null;
287
		}
288
		userString = userString.trim();
289
		
290
		User user = state.getUser(userString);
291
		if (user == null){
292
			user = getTransformedUser(userString,state);
293
		}
294
		if (user == null){
295
			user = makeNewUser(userString, state);
296
		}
297
		if (user == null){
298
			logger.warn("User is null");
299
		}
300
		return user;
301
	}
302
	
303
	private User getTransformedUser(String userString, GlobisImportState state){
304
		Method method = state.getConfig().getUserTransformationMethod();
305
		if (method == null){
306
			return null;
307
		}
308
		try {
309
			userString = (String)state.getConfig().getUserTransformationMethod().invoke(null, userString);
310
		} catch (Exception e) {
311
			logger.warn("Error when trying to transform userString " +  userString + ". No transformation done.");
312
		}
313
		User user = state.getUser(userString);
314
		return user;
315
	}
316

    
317
	private User makeNewUser(String userString, GlobisImportState state){
318
		String pwd = getPassword(); 
319
		User user = User.NewInstance(userString, pwd);
320
		state.putUser(userString, user);
321
		getUserService().save(user);
322
		logger.info("Added new user: " + userString);
323
		return user;
324
	}
325
	
326
	private String getPassword(){
327
		String result = UUID.randomUUID().toString();
328
		return result;
329
	}
330
	
331
	private DateTime getDateTime(Object timeString){
332
		if (timeString == null){
333
			return null;
334
		}
335
		DateTime dateTime = null;
336
		if (timeString instanceof Timestamp){
337
			Timestamp timestamp = (Timestamp)timeString;
338
			dateTime = new DateTime(timestamp);
339
		}else{
340
			logger.warn("time ("+timeString+") is not a timestamp. Datetime set to current date. ");
341
			dateTime = new DateTime();
342
		}
343
		return dateTime;
344
	}
345
	
346
	
347
	
348
	/**
349
	 * Reads a foreign key field from the result set and adds its value to the idSet.
350
	 * @param rs
351
	 * @param teamIdSet
352
	 * @throws SQLException
353
	 */
354
	protected void handleForeignKey(ResultSet rs, Set<String> idSet, String attributeName)
355
			throws SQLException {
356
		Object idObj = rs.getObject(attributeName);
357
		if (idObj != null){
358
			String id  = String.valueOf(idObj);
359
			idSet.add(id);
360
		}
361
	}
362
	
363
	
364
	
365
	
366
	/**
367
	 * Returns true if i is a multiple of recordsPerTransaction
368
	 * @param i
369
	 * @param recordsPerTransaction
370
	 * @return
371
	 */
372
	protected boolean loopNeedsHandling(int i, int recordsPerLoop) {
373
		startTransaction();
374
		return (i % recordsPerLoop) == 0;
375
	}
376
	
377
	protected void doLogPerLoop(int count, int recordsPerLog, String pluralString){
378
		if ((count % recordsPerLog ) == 0 && count!= 0 ){ logger.info(pluralString + " handled: " + (count));}
379
	}
380
	
381

    
382

    
383
	
384
}
(4-4/10)