Project

General

Profile

Download (13.4 KB) Statistics
| Branch: | Tag: | 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.erms;
11

    
12
import java.lang.reflect.Method;
13
import java.sql.ResultSet;
14
import java.sql.ResultSetMetaData;
15
import java.sql.SQLException;
16
import java.sql.Timestamp;
17
import java.util.HashMap;
18
import java.util.HashSet;
19
import java.util.Map;
20
import java.util.Set;
21
import java.util.UUID;
22

    
23
import org.apache.log4j.Logger;
24
import org.joda.time.DateTime;
25

    
26
import eu.etaxonomy.cdm.common.CdmUtils;
27
import eu.etaxonomy.cdm.io.common.CdmImportBase;
28
import eu.etaxonomy.cdm.io.common.ICdmIO;
29
import eu.etaxonomy.cdm.io.common.IPartitionedIO;
30
import eu.etaxonomy.cdm.io.common.ImportHelper;
31
import eu.etaxonomy.cdm.io.common.ResultSetPartitioner;
32
import eu.etaxonomy.cdm.io.common.Source;
33
import eu.etaxonomy.cdm.io.common.IImportConfigurator.EDITOR;
34
import eu.etaxonomy.cdm.io.common.mapping.DbImportMapping;
35
import eu.etaxonomy.cdm.model.common.AnnotatableEntity;
36
import eu.etaxonomy.cdm.model.common.Annotation;
37
import eu.etaxonomy.cdm.model.common.AnnotationType;
38
import eu.etaxonomy.cdm.model.common.CdmBase;
39
import eu.etaxonomy.cdm.model.common.ExtensionType;
40
import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
41
import eu.etaxonomy.cdm.model.common.Language;
42
import eu.etaxonomy.cdm.model.common.MarkerType;
43
import eu.etaxonomy.cdm.model.common.User;
44

    
45
/**
46
 * @author a.mueller
47
 * @created 20.03.2008
48
 * @version 1.0
49
 */
50
public abstract class ErmsImportBase<CDM_BASE extends CdmBase> extends CdmImportBase<ErmsImportConfigurator, ErmsImportState> implements ICdmIO<ErmsImportState>, IPartitionedIO<ErmsImportState> {
51
	private static final Logger logger = Logger.getLogger(ErmsImportBase.class);
52
	
53
	public static final UUID ID_IN_SOURCE_EXT_UUID = UUID.fromString("23dac094-e793-40a4-bad9-649fc4fcfd44");
54
	
55
	//NAMESPACES
56
	
57
	protected static final String AREA_NAMESPACE = "gu";
58
	protected static final String DR_NAMESPACE = "dr";
59
	protected static final String IMAGE_NAMESPACE = "Images";
60
	protected static final String LINKS_NAMESPACE = "Links";
61
	protected static final String NOTES_NAMESPACE = "Notes";
62
	protected static final String LANGUAGE_NAMESPACE = "Language";
63
	protected static final String REFERENCE_NAMESPACE = "Source";
64
	protected static final String SOURCEUSE_NAMESPACE = "tu_sources";
65
	protected static final String TAXON_NAMESPACE = "Taxon";
66
	protected static final String NAME_NAMESPACE = "TaxonName";
67
	protected static final String VERNACULAR_NAMESPACE = "Vernaculars";
68
	protected static final String FEATURE_NAMESPACE = "note.type";
69
	
70
	//UUIDS
71
	public static final UUID GAZETTEER_UUID = UUID.fromString("dcfa124a-1028-49cd-aea5-fdf9bd396c1a");
72
	public static final UUID IMIS_UUID = UUID.fromString("ee2ac2ca-b60c-4e6f-9cad-720fcdb0a6ae");
73
	public static final UUID TNS_EXT_UUID = UUID.fromString("41cb0450-ac84-4d73-905e-9c7773c23b05");
74
	
75

    
76
	private String pluralString;
77
	private String dbTableName;
78
	//TODO needed?
79
	private Class cdmTargetClass;
80

    
81
	
82
	
83
	/**
84
	 * @param dbTableName
85
	 * @param dbTableName2 
86
	 */
87
	public ErmsImportBase(String pluralString, String dbTableName, Class cdmTargetClass) {
88
		this.pluralString = pluralString;
89
		this.dbTableName = dbTableName;
90
		this.cdmTargetClass = cdmTargetClass;
91
	}
92

    
93
	protected boolean doInvoke(ErmsImportState state){
94
		logger.info("start make " + getPluralString() + " ...");
95
		boolean success = true ;
96
		ErmsImportConfigurator config = state.getConfig();
97
		Source source = config.getSource();
98
			
99
		String strIdQuery = getIdQuery();
100
		String strRecordQuery = getRecordQuery(config);
101

    
102
		int recordsPerTransaction = config.getRecordsPerTransaction();
103
		try{
104
			ResultSetPartitioner partitioner = ResultSetPartitioner.NewInstance(source, strIdQuery, strRecordQuery, recordsPerTransaction);
105
			while (partitioner.nextPartition()){
106
				partitioner.doPartition(this, state);
107
			}
108
		} catch (SQLException e) {
109
			logger.error("SQLException:" +  e);
110
			return false;
111
		}
112
		
113
		logger.info("end make " + getPluralString() + " ... " + getSuccessString(success));
114
		return success;
115
	}
116
	
117
	public boolean doPartition(ResultSetPartitioner partitioner, ErmsImportState state) {
118
		boolean success = true ;
119
		Set objectsToSave = new HashSet();
120
		
121
 		DbImportMapping<?, ?> mapping = getMapping();
122
		mapping.initialize(state, cdmTargetClass);
123
		
124
		ResultSet rs = partitioner.getResultSet();
125
		try{
126
			while (rs.next()){
127
				success &= mapping.invoke(rs,objectsToSave);
128
			}
129
		} catch (SQLException e) {
130
			logger.error("SQLException:" +  e);
131
			return false;
132
		}
133
	
134
		partitioner.startDoSave();
135
		getCommonService().save(objectsToSave);
136
		return success;
137
	}
138

    
139

    
140
	
141
	/**
142
	 * @return
143
	 */
144
	protected abstract DbImportMapping<?, ?> getMapping();
145
	
146
	/**
147
	 * @return
148
	 */
149
	protected abstract String getRecordQuery(ErmsImportConfigurator config);
150

    
151
	/**
152
	 * @return
153
	 */
154
	protected String getIdQuery(){
155
		String result = " SELECT id FROM " + getTableName();
156
		return result;
157
	}
158
	
159
	/* (non-Javadoc)
160
	 * @see eu.etaxonomy.cdm.io.berlinModel.in.IPartitionedIO#getPluralString()
161
	 */
162
	public String getPluralString(){
163
		return pluralString;
164
	}
165

    
166
	/**
167
	 * @return
168
	 */
169
	protected String getTableName(){
170
		return this.dbTableName;
171
	}
172
	
173
	protected boolean doIdCreatedUpdatedNotes(ErmsImportState state, IdentifiableEntity identifiableEntity, ResultSet rs, long id, String namespace)
174
			throws SQLException{
175
		boolean success = true;
176
		//id
177
		success &= ImportHelper.setOriginalSource(identifiableEntity, state.getConfig().getSourceReference(), id, namespace);
178
		//createdUpdateNotes
179
		success &= doCreatedUpdatedNotes(state, identifiableEntity, rs, namespace);
180
		return success;
181
	}
182
	
183
	
184
	protected boolean doCreatedUpdatedNotes(ErmsImportState state, AnnotatableEntity annotatableEntity, ResultSet rs, String namespace)
185
			throws SQLException{
186

    
187
		ErmsImportConfigurator config = state.getConfig();
188
		Object createdWhen = rs.getObject("Created_When");
189
		String createdWho = rs.getString("Created_Who");
190
		Object updatedWhen = null;
191
		String updatedWho = null;
192
		try {
193
			updatedWhen = rs.getObject("Updated_When");
194
			updatedWho = rs.getString("Updated_who");
195
		} catch (SQLException e) {
196
			//Table "Name" has no updated when/who
197
		}
198
		String notes = rs.getString("notes");
199
		
200
		boolean success  = true;
201
		
202
		//Created When, Who, Updated When Who
203
		if (config.getEditor() == null || config.getEditor().equals(EDITOR.NO_EDITORS)){
204
			//do nothing
205
		}else if (config.getEditor().equals(EDITOR.EDITOR_AS_ANNOTATION)){
206
			String createdAnnotationString = "Berlin Model record was created By: " + String.valueOf(createdWho) + " (" + String.valueOf(createdWhen) + ") ";
207
			if (updatedWhen != null && updatedWho != null){
208
				createdAnnotationString += " and updated By: " + String.valueOf(updatedWho) + " (" + String.valueOf(updatedWhen) + ")";
209
			}
210
			Annotation annotation = Annotation.NewInstance(createdAnnotationString, Language.DEFAULT());
211
			annotation.setCommentator(config.getCommentator());
212
			annotation.setAnnotationType(AnnotationType.TECHNICAL());
213
			annotatableEntity.addAnnotation(annotation);
214
		}else if (config.getEditor().equals(EDITOR.EDITOR_AS_EDITOR)){
215
			User creator = getUser(createdWho, state);
216
			User updator = getUser(updatedWho, state);
217
			DateTime created = getDateTime(createdWhen);
218
			DateTime updated = getDateTime(updatedWhen);
219
			annotatableEntity.setCreatedBy(creator);
220
			annotatableEntity.setUpdatedBy(updator);
221
			annotatableEntity.setCreated(created);
222
			annotatableEntity.setUpdated(updated);
223
		}else {
224
			logger.warn("Editor type not yet implemented: " + config.getEditor());
225
		}
226
		
227
		
228
		//notes
229
		if (CdmUtils.isNotEmpty(notes)){
230
			String notesString = String.valueOf(notes);
231
			if (notesString.length() > 65530 ){
232
				notesString = notesString.substring(0, 65530) + "...";
233
				logger.warn("Notes string is longer than 65530 and was truncated: " + annotatableEntity);
234
			}
235
			Annotation notesAnnotation = Annotation.NewInstance(notesString, null);
236
			//notesAnnotation.setAnnotationType(AnnotationType.EDITORIAL());
237
			//notes.setCommentator(bmiConfig.getCommentator());
238
			annotatableEntity.addAnnotation(notesAnnotation);
239
		}
240
		return success;
241
	}
242
	
243
	private User getUser(String userString, ErmsImportState state){
244
		if (CdmUtils.isEmpty(userString)){
245
			return null;
246
		}
247
		userString = userString.trim();
248
		
249
		User user = state.getUser(userString);
250
		if (user == null){
251
			user = getTransformedUser(userString,state);
252
		}
253
		if (user == null){
254
			user = makeNewUser(userString, state);
255
		}
256
		if (user == null){
257
			logger.warn("User is null");
258
		}
259
		return user;
260
	}
261
	
262
	private User getTransformedUser(String userString, ErmsImportState state){
263
		Method method = state.getConfig().getUserTransformationMethod();
264
		if (method == null){
265
			return null;
266
		}
267
		try {
268
			userString = (String)state.getConfig().getUserTransformationMethod().invoke(null, userString);
269
		} catch (Exception e) {
270
			logger.warn("Error when trying to transform userString " +  userString + ". No transformation done.");
271
		}
272
		User user = state.getUser(userString);
273
		return user;
274
	}
275

    
276
	private User makeNewUser(String userString, ErmsImportState state){
277
		String pwd = getPassword(); 
278
		User user = User.NewInstance(userString, pwd);
279
		state.putUser(userString, user);
280
		getUserService().save(user);
281
		logger.info("Added new user: " + userString);
282
		return user;
283
	}
284
	
285
	private String getPassword(){
286
		String result = UUID.randomUUID().toString();
287
		return result;
288
	}
289
	
290
	private DateTime getDateTime(Object timeString){
291
		if (timeString == null){
292
			return null;
293
		}
294
		DateTime dateTime = null;
295
		if (timeString instanceof Timestamp){
296
			Timestamp timestamp = (Timestamp)timeString;
297
			dateTime = new DateTime(timestamp);
298
		}else{
299
			logger.warn("time ("+timeString+") is not a timestamp. Datetime set to current date. ");
300
			dateTime = new DateTime();
301
		}
302
		return dateTime;
303
	}
304
	
305
	protected boolean resultSetHasColumn(ResultSet rs, String columnName){
306
		try {
307
			ResultSetMetaData metaData = rs.getMetaData();
308
			for (int i = 0; i < metaData.getColumnCount(); i++){
309
				if (metaData.getColumnName(i + 1).equalsIgnoreCase(columnName)){
310
					return true;
311
				}
312
			}
313
			return false;
314
		} catch (SQLException e) {
315
            logger.warn("Exception in resultSetHasColumn");
316
            return false;
317
		}
318
	}
319
	
320
	protected boolean checkSqlServerColumnExists(Source source, String tableName, String columnName){
321
		String strQuery = "SELECT  Count(t.id) as n " +
322
				" FROM sysobjects AS t " +
323
				" INNER JOIN syscolumns AS c ON t.id = c.id " +
324
				" WHERE (t.xtype = 'U') AND " + 
325
				" (t.name = '" + tableName + "') AND " + 
326
				" (c.name = '" + columnName + "')";
327
		ResultSet rs = source.getResultSet(strQuery) ;		
328
		int n;
329
		try {
330
			rs.next();
331
			n = rs.getInt("n");
332
			return n>0;
333
		} catch (SQLException e) {
334
			e.printStackTrace();
335
			return false;
336
		}
337
		
338
	}
339
	
340
	/**
341
	 * Returns a map that holds all values of a ResultSet. This is needed if a value needs to
342
	 * be accessed twice
343
	 * @param rs
344
	 * @return
345
	 * @throws SQLException
346
	 */
347
	protected Map<String, Object> getValueMap(ResultSet rs) throws SQLException{
348
		try{
349
			Map<String, Object> valueMap = new HashMap<String, Object>();
350
			int colCount = rs.getMetaData().getColumnCount();
351
			for (int c = 0; c < colCount ; c++){
352
				Object value = rs.getObject(c+1);
353
				String label = rs.getMetaData().getColumnLabel(c+1).toLowerCase();
354
				if (value != null && ! CdmUtils.Nz(value.toString()).trim().equals("")){
355
					valueMap.put(label, value);
356
				}
357
			}
358
			return valueMap;
359
		}catch(SQLException e){
360
			throw e;
361
		}
362
	}
363
	
364
	protected ExtensionType getExtensionType(UUID uuid, String label, String text, String labelAbbrev){
365
		ExtensionType extensionType = (ExtensionType)getTermService().find(uuid);
366
		if (extensionType == null){
367
			extensionType = new ExtensionType(label, text, labelAbbrev);
368
			extensionType.setUuid(uuid);
369
			getTermService().save(extensionType);
370
		}
371
		return extensionType;
372
	}
373
	
374
	protected MarkerType getMarkerType(UUID uuid, String label, String text, String labelAbbrev){
375
		MarkerType markerType = (MarkerType)getTermService().find(uuid);
376
		if (markerType == null){
377
			markerType = MarkerType.NewInstance(label, text, labelAbbrev);
378
			markerType.setUuid(uuid);
379
			getTermService().save(markerType);
380
		}
381
		return markerType;
382
	}
383
	
384

    
385
	/**
386
	 * Reads a foreign key field from the result set and adds its value to the idSet.
387
	 * @param rs
388
	 * @param teamIdSet
389
	 * @throws SQLException
390
	 */
391
	protected void handleForeignKey(ResultSet rs, Set<String> idSet, String attributeName)
392
			throws SQLException {
393
		Object idObj = rs.getObject(attributeName);
394
		if (idObj != null){
395
			String id  = String.valueOf(idObj);
396
			idSet.add(id);
397
		}
398
	}
399
	
400
	/**
401
	 * Returns true if i is a multiple of recordsPerTransaction
402
	 * @param i
403
	 * @param recordsPerTransaction
404
	 * @return
405
	 */
406
	protected boolean loopNeedsHandling(int i, int recordsPerLoop) {
407
		startTransaction();
408
		return (i % recordsPerLoop) == 0;
409
	}
410
	
411
	protected void doLogPerLoop(int count, int recordsPerLog, String pluralString){
412
		if ((count % recordsPerLog ) == 0 && count!= 0 ){ logger.info(pluralString + " handled: " + (count));}
413
	}
414
	
415

    
416

    
417
	
418
}
(4-4/18)