Project

General

Profile

Download (13.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.pesi.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.commons.lang3.StringUtils;
24
import org.apache.log4j.Logger;
25
import org.joda.time.DateTime;
26

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

    
46
/**
47
 * @author a.mueller
48
 * @since 20.03.2008
49
 */
50
public abstract class ErmsImportBase<CDM_BASE extends CdmBase>
51
             extends CdmImportBase<ErmsImportConfigurator, ErmsImportState>
52
             implements ICdmIO<ErmsImportState>, IPartitionedIO<ErmsImportState> {
53

    
54
    private static final long serialVersionUID = 3856605408484122428L;
55
    private static final Logger logger = Logger.getLogger(ErmsImportBase.class);
56

    
57
	public static final UUID ID_IN_SOURCE_EXT_UUID = UUID.fromString("23dac094-e793-40a4-bad9-649fc4fcfd44");
58

    
59
	//NAMESPACES
60

    
61
	protected static final String AREA_NAMESPACE = "gu";
62
	protected static final String DR_NAMESPACE = "dr";
63
	protected static final String IMAGE_NAMESPACE = "Images";
64
	protected static final String LINKS_NAMESPACE = "Links";
65
	protected static final String NOTES_NAMESPACE = "Notes";
66
	protected static final String LANGUAGE_NAMESPACE = "Language";
67
	protected static final String REFERENCE_NAMESPACE = "Source";
68
	protected static final String SOURCEUSE_NAMESPACE = "tu_sources";
69
	protected static final String TAXON_NAMESPACE = "Taxon";
70
	protected static final String NAME_NAMESPACE = "TaxonName";
71
	protected static final String VERNACULAR_NAMESPACE = "Vernaculars";
72
	protected static final String FEATURE_NAMESPACE = "note.type";
73
	protected static final String EXTENSION_TYPE_NAMESPACE = "ExtensionType";
74

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

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

    
90
	@Override
91
    protected void doInvoke(ErmsImportState state){
92
		logger.info("start make " + getPluralString() + " ...");
93
		ErmsImportConfigurator config = state.getConfig();
94
		Source source = config.getSource();
95

    
96
		String strIdQuery = getIdQuery();
97
		String strRecordQuery = getRecordQuery(config);
98

    
99
		int recordsPerTransaction = config.getRecordsPerTransaction();
100
		recordsPerTransaction = recordsPerTransaction / divideCountBy();
101

    
102
		try{
103
			ResultSetPartitioner<ErmsImportState> partitioner = ResultSetPartitioner.NewInstance(source, strIdQuery, strRecordQuery, recordsPerTransaction);
104
			while (partitioner.nextPartition()){
105
				partitioner.doPartition(this, state);
106
			}
107
		} catch (SQLException e) {
108
			logger.error("SQLException:" +  e);
109
			state.setUnsuccessfull();
110
			return;
111
		}
112

    
113
		logger.info("end make " + getPluralString() + " ... " + getSuccessString(true));
114
		return;
115
	}
116

    
117
	@Override
118
    public boolean doPartition(ResultSetPartitioner partitioner, ErmsImportState state) {
119
		boolean success = true ;
120
		Set<CdmBase> objectsToSave = new HashSet<>();
121

    
122
 		DbImportMapping<?, ?> mapping = getMapping();
123
		mapping.initialize(state, cdmTargetClass);
124

    
125
		ResultSet rs = partitioner.getResultSet();
126
		try{
127
			while (rs.next()){
128
				success &= mapping.invoke(rs,objectsToSave);
129
			}
130
		} catch (SQLException e) {
131
			logger.error("SQLException:" +  e);
132
			return false;
133
		}
134

    
135
		partitioner.startDoSave();
136
		getCommonService().save(objectsToSave);
137
		return success;
138
	}
139

    
140

    
141

    
142
	/**
143
	 * @return
144
	 */
145
	protected abstract DbImportMapping<?, ?> getMapping();
146

    
147
	/**
148
	 * @return
149
	 */
150
	protected abstract String getRecordQuery(ErmsImportConfigurator config);
151

    
152
	/**
153
	 * @return
154
	 */
155
	protected String getIdQuery(){
156
		String result = " SELECT id FROM " + getTableName();
157
		return result;
158
	}
159

    
160
	@Override
161
    public String getPluralString(){
162
		return pluralString;
163
	}
164

    
165
	/**
166
	 * @return
167
	 */
168
	protected String getTableName(){
169
		return this.dbTableName;
170
	}
171

    
172
	protected boolean doIdCreatedUpdatedNotes(ErmsImportState state, IdentifiableEntity identifiableEntity, ResultSet rs, long id, String namespace)
173
			throws SQLException{
174
		boolean success = true;
175
		//id
176
		success &= ImportHelper.setOriginalSource(identifiableEntity, state.getConfig().getSourceReference(), id, namespace);
177
		//createdUpdateNotes
178
		success &= doCreatedUpdatedNotes(state, identifiableEntity, rs, namespace);
179
		return success;
180
	}
181

    
182
	protected boolean doCreatedUpdatedNotes(ErmsImportState state, AnnotatableEntity annotatableEntity, ResultSet rs, String namespace)
183
			throws SQLException{
184

    
185
		ErmsImportConfigurator config = state.getConfig();
186
		Object createdWhen = rs.getObject("Created_When");
187
		String createdWho = rs.getString("Created_Who");
188
		Object updatedWhen = null;
189
		String updatedWho = null;
190
		try {
191
			updatedWhen = rs.getObject("Updated_When");
192
			updatedWho = rs.getString("Updated_who");
193
		} catch (SQLException e) {
194
			//Table "Name" has no updated when/who
195
		}
196
		String notes = rs.getString("notes");
197

    
198
		boolean success  = true;
199

    
200
		//Created When, Who, Updated When Who
201
		if (config.getEditor() == null || config.getEditor().equals(EDITOR.NO_EDITORS)){
202
			//do nothing
203
		}else if (config.getEditor().equals(EDITOR.EDITOR_AS_ANNOTATION)){
204
			String createdAnnotationString = "Berlin Model record was created By: " + String.valueOf(createdWho) + " (" + String.valueOf(createdWhen) + ") ";
205
			if (updatedWhen != null && updatedWho != null){
206
				createdAnnotationString += " and updated By: " + String.valueOf(updatedWho) + " (" + String.valueOf(updatedWhen) + ")";
207
			}
208
			Annotation annotation = Annotation.NewInstance(createdAnnotationString, Language.DEFAULT());
209
			annotation.setCommentator(config.getCommentator());
210
			annotation.setAnnotationType(AnnotationType.TECHNICAL());
211
			annotatableEntity.addAnnotation(annotation);
212
		}else if (config.getEditor().equals(EDITOR.EDITOR_AS_EDITOR)){
213
			User creator = getUser(createdWho, state);
214
			User updator = getUser(updatedWho, state);
215
			DateTime created = getDateTime(createdWhen);
216
			DateTime updated = getDateTime(updatedWhen);
217
			annotatableEntity.setCreatedBy(creator);
218
			annotatableEntity.setUpdatedBy(updator);
219
			annotatableEntity.setCreated(created);
220
			annotatableEntity.setUpdated(updated);
221
		}else {
222
			logger.warn("Editor type not yet implemented: " + config.getEditor());
223
		}
224

    
225

    
226
		//notes
227
		if (StringUtils.isNotBlank(notes)){
228
			String notesString = String.valueOf(notes);
229
			if (notesString.length() > 65530 ){
230
				notesString = notesString.substring(0, 65530) + "...";
231
				logger.warn("Notes string is longer than 65530 and was truncated: " + annotatableEntity);
232
			}
233
			Annotation notesAnnotation = Annotation.NewInstance(notesString, null);
234
			//notesAnnotation.setAnnotationType(AnnotationType.EDITORIAL());
235
			//notes.setCommentator(bmiConfig.getCommentator());
236
			annotatableEntity.addAnnotation(notesAnnotation);
237
		}
238
		return success;
239
	}
240

    
241
	private User getUser(String userString, ErmsImportState state){
242
		if (StringUtils.isBlank(userString)){
243
			return null;
244
		}
245
		userString = userString.trim();
246

    
247
		User user = state.getUser(userString);
248
		if (user == null){
249
			user = getTransformedUser(userString,state);
250
		}
251
		if (user == null){
252
			user = makeNewUser(userString, state);
253
		}
254
		if (user == null){
255
			logger.warn("User is null");
256
		}
257
		return user;
258
	}
259

    
260
	private User getTransformedUser(String userString, ErmsImportState state){
261
		Method method = state.getConfig().getUserTransformationMethod();
262
		if (method == null){
263
			return null;
264
		}
265
		try {
266
			userString = (String)state.getConfig().getUserTransformationMethod().invoke(null, userString);
267
		} catch (Exception e) {
268
			logger.warn("Error when trying to transform userString " +  userString + ". No transformation done.");
269
		}
270
		User user = state.getUser(userString);
271
		return user;
272
	}
273

    
274
	private User makeNewUser(String userString, ErmsImportState state){
275
		String pwd = getPassword();
276
		User user = User.NewInstance(userString, pwd);
277
		state.putUser(userString, user);
278
		getUserService().save(user);
279
		logger.info("Added new user: " + userString);
280
		return user;
281
	}
282

    
283
	private String getPassword(){
284
		String result = UUID.randomUUID().toString();
285
		return result;
286
	}
287

    
288
	private DateTime getDateTime(Object timeString){
289
		if (timeString == null){
290
			return null;
291
		}
292
		DateTime dateTime = null;
293
		if (timeString instanceof Timestamp){
294
			Timestamp timestamp = (Timestamp)timeString;
295
			dateTime = new DateTime(timestamp);
296
		}else{
297
			logger.warn("time ("+timeString+") is not a timestamp. Datetime set to current date. ");
298
			dateTime = new DateTime();
299
		}
300
		return dateTime;
301
	}
302

    
303
	protected boolean resultSetHasColumn(ResultSet rs, String columnName){
304
		try {
305
			ResultSetMetaData metaData = rs.getMetaData();
306
			for (int i = 0; i < metaData.getColumnCount(); i++){
307
				if (metaData.getColumnName(i + 1).equalsIgnoreCase(columnName)){
308
					return true;
309
				}
310
			}
311
			return false;
312
		} catch (SQLException e) {
313
            logger.warn("Exception in resultSetHasColumn");
314
            return false;
315
		}
316
	}
317

    
318
	protected boolean checkSqlServerColumnExists(Source source, String tableName, String columnName){
319
		String strQuery = "SELECT  Count(t.id) as n " +
320
				" FROM sysobjects AS t " +
321
				" INNER JOIN syscolumns AS c ON t.id = c.id " +
322
				" WHERE (t.xtype = 'U') AND " +
323
				" (t.name = '" + tableName + "') AND " +
324
				" (c.name = '" + columnName + "')";
325
		ResultSet rs = source.getResultSet(strQuery) ;
326
		int n;
327
		try {
328
			rs.next();
329
			n = rs.getInt("n");
330
			return n>0;
331
		} catch (SQLException e) {
332
			e.printStackTrace();
333
			return false;
334
		}
335

    
336
	}
337

    
338
	/**
339
	 * Returns a map that holds all values of a ResultSet. This is needed if a value needs to
340
	 * be accessed twice
341
	 * @param rs
342
	 * @return
343
	 * @throws SQLException
344
	 */
345
	protected Map<String, Object> getValueMap(ResultSet rs) throws SQLException{
346
		try{
347
			Map<String, Object> valueMap = new HashMap<>();
348
			int colCount = rs.getMetaData().getColumnCount();
349
			for (int c = 0; c < colCount ; c++){
350
				Object value = rs.getObject(c+1);
351
				String label = rs.getMetaData().getColumnLabel(c+1).toLowerCase();
352
				if (value != null && ! CdmUtils.Nz(value.toString()).trim().equals("")){
353
					valueMap.put(label, value);
354
				}
355
			}
356
			return valueMap;
357
		}catch(SQLException e){
358
			throw e;
359
		}
360
	}
361

    
362
	protected ExtensionType getExtensionType(UUID uuid, String label, String text, String labelAbbrev){
363
		ExtensionType extensionType = (ExtensionType)getTermService().find(uuid);
364
		if (extensionType == null){
365
			extensionType = ExtensionType.NewInstance(text, label, labelAbbrev);
366
			extensionType.setUuid(uuid);
367
			getTermService().save(extensionType);
368
		}
369
		return extensionType;
370
	}
371

    
372
	protected MarkerType getMarkerType(UUID uuid, String label, String text, String labelAbbrev){
373
		MarkerType markerType = (MarkerType)getTermService().find(uuid);
374
		if (markerType == null){
375
			markerType = MarkerType.NewInstance(label, text, labelAbbrev);
376
			markerType.setUuid(uuid);
377
			getTermService().save(markerType);
378
		}
379
		return markerType;
380
	}
381

    
382

    
383
	/**
384
	 * Reads a foreign key field from the result set and adds its value to the idSet.
385
	 * @param rs
386
	 * @param teamIdSet
387
	 * @throws SQLException
388
	 */
389
	protected void handleForeignKey(ResultSet rs, Set<String> idSet, String attributeName)
390
			throws SQLException {
391
		Object idObj = rs.getObject(attributeName);
392
		if (idObj != null){
393
			String id  = String.valueOf(idObj);
394
			idSet.add(id);
395
		}
396
	}
397

    
398
	protected int divideCountBy() { return 1;}
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/17)