Project

General

Profile

Download (12.3 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.NamedArea;
41
import eu.etaxonomy.cdm.model.location.WaterbodyOrCountry;
42
import eu.etaxonomy.cdm.model.name.ZoologicalName;
43
import eu.etaxonomy.cdm.strategy.exceptions.StringNotParsableException;
44
import eu.etaxonomy.cdm.strategy.parser.INonViralNameParser;
45
import eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl;
46

    
47
/**
48
 * @author a.mueller
49
 * @created 20.03.2008
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
	protected static final String IMAGE_NAMESPACE = "Einzelbilder";
62
	protected static final String SPEC_TAX_NAMESPACE = "specTax";
63
	protected static final String TYPE_NAMESPACE = "specTax.SpecTypeDepository";
64
	
65
	private String pluralString;
66
	private String dbTableName;
67
	//TODO needed?
68
	private Class cdmTargetClass;
69

    
70
	private INonViralNameParser parser = NonViralNameParserImpl.NewInstance();
71

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

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

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

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

    
143
	/**
144
	 * @param state
145
	 * @param countryStr
146
	 * @return
147
	 */
148
	protected NamedArea getCountry(GlobisImportState state, String countryStr) {
149
		NamedArea country = WaterbodyOrCountry.getWaterbodyOrCountryByLabel(countryStr);
150
		if (country == null){
151
			try {
152
				country = (NamedArea)state.getTransformer().getNamedAreaByKey(countryStr);
153
			} catch (UndefinedTransformerMethodException e) {
154
				e.printStackTrace();
155
			}
156
		}
157
		return country;
158
	}
159

    
160
	
161

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

    
184

    
185
	
186
	/**
187
	 * @return
188
	 */
189
	protected /*abstract*/ DbImportMapping<?, ?> getMapping(){
190
		return null;
191
	}
192
	
193
	/**
194
	 * @return
195
	 */
196
	protected abstract String getRecordQuery(GlobisImportConfigurator config);
197

    
198
	/**
199
	 * @return
200
	 */
201
	protected String getIdQuery(){
202
		String result = " SELECT id FROM " + getTableName();
203
		return result;
204
	}
205
	
206
	/* (non-Javadoc)
207
	 * @see eu.etaxonomy.cdm.io.berlinModel.in.IPartitionedIO#getPluralString()
208
	 */
209
	public String getPluralString(){
210
		return pluralString;
211
	}
212

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

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

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

    
388

    
389
	
390
}
(4-4/9)