Project

General

Profile

Download (13.7 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.indexFungorum;
11

    
12
import java.sql.ResultSet;
13
import java.sql.ResultSetMetaData;
14
import java.sql.SQLException;
15
import java.util.HashMap;
16
import java.util.HashSet;
17
import java.util.Map;
18
import java.util.Set;
19
import java.util.UUID;
20

    
21
import org.apache.commons.lang.StringUtils;
22
import org.apache.log4j.Logger;
23

    
24
import com.ibm.lsid.MalformedLSIDException;
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.ResultSetPartitioner;
31
import eu.etaxonomy.cdm.io.common.Source;
32
import eu.etaxonomy.cdm.io.common.mapping.out.DbLastActionMapper;
33
import eu.etaxonomy.cdm.io.pesi.out.PesiTransformer;
34
import eu.etaxonomy.cdm.model.agent.Team;
35
import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
36
import eu.etaxonomy.cdm.model.common.CdmBase;
37
import eu.etaxonomy.cdm.model.common.IdentifiableSource;
38
import eu.etaxonomy.cdm.model.common.LSID;
39
import eu.etaxonomy.cdm.model.common.Marker;
40
import eu.etaxonomy.cdm.model.common.MarkerType;
41
import eu.etaxonomy.cdm.model.common.OriginalSourceType;
42
import eu.etaxonomy.cdm.model.name.INonViralName;
43
import eu.etaxonomy.cdm.model.reference.Reference;
44
import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
45
import eu.etaxonomy.cdm.model.taxon.Classification;
46
import eu.etaxonomy.cdm.model.taxon.Taxon;
47
import eu.etaxonomy.cdm.strategy.exceptions.StringNotParsableException;
48
import eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl;
49
import eu.etaxonomy.cdm.strategy.parser.TimePeriodParser;
50

    
51
/**
52
 * @author a.mueller
53
 * @since 27.02.2012
54
 */
55
public abstract class IndexFungorumImportBase extends CdmImportBase<IndexFungorumImportConfigurator, IndexFungorumImportState> implements ICdmIO<IndexFungorumImportState>, IPartitionedIO<IndexFungorumImportState> {
56
	private static final Logger logger = Logger.getLogger(IndexFungorumImportBase.class);
57

    
58
	//NAMESPACES
59
	protected static final String NAMESPACE_REFERENCE = "reference";
60
	protected static final String NAMESPACE_TAXON = "Taxon";
61
	protected static final String NAMESPACE_SUPRAGENERIC_NAMES = "SupragenericNames";
62
	protected static final String NAMESPACE_GENERA = "Genera";
63
	protected static final String NAMESPACE_SPECIES = "Species";
64

    
65

    
66
	protected static final String INCERTAE_SEDIS = "Incertae sedis";
67
	protected static final String FOSSIL_FUNGI = "Fossil Fungi";
68

    
69
	protected static final String SOURCE_REFERENCE = "SOURCE_REFERENCE";
70

    
71

    
72

    
73

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

    
79

    
80

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

    
91
	@Override
92
    protected void doInvoke(IndexFungorumImportState state){
93
		System.out.println("start make " + getPluralString() + " ...");
94
		IndexFungorumImportConfigurator config = state.getConfig();
95
		Source source = config.getSource();
96

    
97

    
98
		String strIdQuery = getIdQuery();
99

    
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
			state.setUnsuccessfull();
111
			return;
112
		}
113

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

    
118

    
119

    
120

    
121

    
122

    
123

    
124
    @Override
125
    public boolean doPartition(ResultSetPartitioner partitioner, IndexFungorumImportState state) {
126
		boolean success = true ;
127
		Set objectsToSave = new HashSet<CdmBase>();
128

    
129
// 		DbImportMapping<?, ?> mapping = getMapping();
130
//		mapping.initialize(state, cdmTargetClass);
131

    
132
		ResultSet rs = partitioner.getResultSet();
133
		try{
134
			while (rs.next()){
135
//				success &= mapping.invoke(rs,objectsToSave);
136
			}
137
		} catch (SQLException e) {
138
			logger.error("SQLException:" +  e);
139
			return false;
140
		}
141

    
142
		partitioner.startDoSave();
143
		getCommonService().save(objectsToSave);
144
		return success;
145
	}
146

    
147

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

    
153

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

    
162
	/* (non-Javadoc)
163
	 * @see eu.etaxonomy.cdm.io.berlinModel.in.IPartitionedIO#getPluralString()
164
	 */
165
	@Override
166
    public String getPluralString(){
167
		return pluralString;
168
	}
169

    
170
	/**
171
	 * @return
172
	 */
173
	protected String getTableName(){
174
		return this.dbTableName;
175
	}
176

    
177

    
178
	protected boolean resultSetHasColumn(ResultSet rs, String columnName){
179
		try {
180
			ResultSetMetaData metaData = rs.getMetaData();
181
			for (int i = 0; i < metaData.getColumnCount(); i++){
182
				if (metaData.getColumnName(i + 1).equalsIgnoreCase(columnName)){
183
					return true;
184
				}
185
			}
186
			return false;
187
		} catch (SQLException e) {
188
            logger.warn("Exception in resultSetHasColumn");
189
            return false;
190
		}
191
	}
192

    
193
	protected boolean checkSqlServerColumnExists(Source source, String tableName, String columnName){
194
		String strQuery = "SELECT  Count(t.id) as n " +
195
				" FROM sysobjects AS t " +
196
				" INNER JOIN syscolumns AS c ON t.id = c.id " +
197
				" WHERE (t.xtype = 'U') AND " +
198
				" (t.name = '" + tableName + "') AND " +
199
				" (c.name = '" + columnName + "')";
200
		ResultSet rs = source.getResultSet(strQuery) ;
201
		int n;
202
		try {
203
			rs.next();
204
			n = rs.getInt("n");
205
			return n>0;
206
		} catch (SQLException e) {
207
			e.printStackTrace();
208
			return false;
209
		}
210

    
211
	}
212

    
213
	/**
214
	 * Returns a map that holds all values of a ResultSet. This is needed if a value needs to
215
	 * be accessed twice
216
	 * @param rs
217
	 * @return
218
	 * @throws SQLException
219
	 */
220
	protected Map<String, Object> getValueMap(ResultSet rs) throws SQLException{
221
		try{
222
			Map<String, Object> valueMap = new HashMap<String, Object>();
223
			int colCount = rs.getMetaData().getColumnCount();
224
			for (int c = 0; c < colCount ; c++){
225
				Object value = rs.getObject(c+1);
226
				String label = rs.getMetaData().getColumnLabel(c+1).toLowerCase();
227
				if (value != null && ! CdmUtils.Nz(value.toString()).trim().equals("")){
228
					valueMap.put(label, value);
229
				}
230
			}
231
			return valueMap;
232
		}catch(SQLException e){
233
			throw e;
234
		}
235
	}
236

    
237

    
238
	/**
239
	 * Reads a foreign key field from the result set and adds its value to the idSet.
240
	 * @param rs
241
	 * @param teamIdSet
242
	 * @throws SQLException
243
	 */
244
	protected void handleForeignKey(ResultSet rs, Set<String> idSet, String attributeName)
245
			throws SQLException {
246
		Object idObj = rs.getObject(attributeName);
247
		if (idObj != null){
248
			String id  = String.valueOf(idObj);
249
			idSet.add(id);
250
		}
251
	}
252

    
253
	/**
254
	 * Returns true if i is a multiple of recordsPerTransaction
255
	 * @param i
256
	 * @param recordsPerTransaction
257
	 * @return
258
	 */
259
	protected boolean loopNeedsHandling(int i, int recordsPerLoop) {
260
		startTransaction();
261
		return (i % recordsPerLoop) == 0;
262
	}
263

    
264
	protected void doLogPerLoop(int count, int recordsPerLog, String pluralString){
265
		if ((count % recordsPerLog ) == 0 && count!= 0 ){ logger.info(pluralString + " handled: " + (count));}
266
	}
267

    
268

    
269
	protected void makeAuthorAndPublication(IndexFungorumImportState state, ResultSet rs, INonViralName name) throws SQLException {
270
		//authors
271
		NonViralNameParserImpl parser = NonViralNameParserImpl.NewInstance();
272
		String authorStr = rs.getString("AUTHORS");
273
		if (StringUtils.isNotBlank(authorStr)){
274
			try {
275
				parser.parseAuthors(name, authorStr);
276
			} catch (StringNotParsableException e){
277
				//logger.warn("Authorstring not parsable: " + authorStr);
278
				name.setAuthorshipCache(authorStr);
279
			}
280
		}
281

    
282
		//page
283
		String page = rs.getString("PAGE");
284
		if (StringUtils.isNotBlank(page)){
285
			name.setNomenclaturalMicroReference(page);
286
		}
287

    
288
		//Reference
289
		Reference ref = ReferenceFactory.newGeneric();
290
		boolean hasInReference = false;
291
		//publishing authors
292
		Team pubAuthor = null;
293
		String pubAuthorStr = rs.getString("PUBLISHING AUTHORS");
294
		if (StringUtils.isNotBlank(pubAuthorStr)){
295
			if (StringUtils.isNotBlank(authorStr)){
296
				if (! pubAuthorStr.equals(authorStr)){
297
					pubAuthor = Team.NewTitledInstance(pubAuthorStr,pubAuthorStr);
298
				}
299
			}else{
300
				logger.warn("'AUTHORS' is blank for not empty PUBLISHING_AUTHORS. This is not yet handled.");
301
			}
302
		}
303

    
304
		//inRef + inRefAuthor
305
		if (pubAuthor != null){
306
			Reference inRef = ReferenceFactory.newGeneric();
307
			inRef.setAuthorship(pubAuthor);
308
			ref.setInReference(inRef);
309
			hasInReference = true;
310
		}
311

    
312
		//refAuthor
313
		TeamOrPersonBase<?> refAuthor = CdmBase.deproxy(name.getCombinationAuthorship(), TeamOrPersonBase.class);
314
		if (refAuthor == null){
315
			refAuthor = Team.NewTitledInstance(authorStr, authorStr);
316
		}
317
		ref.setAuthorship(refAuthor);
318
		//location
319
		String location = rs.getString("pubIMIAbbrLoc");
320
		if (StringUtils.isNotBlank(location)){
321
			if (hasInReference){
322
				ref.getInReference().setPlacePublished(location);
323
			}else{
324
				ref.setPlacePublished(location);
325
			}
326
		}
327
		//title
328
		String titleMain = rs.getString("pubIMIAbbr");
329
		String supTitle = rs.getString("pubIMISupAbbr");
330
		String title = CdmUtils.concat(", ", titleMain, supTitle);
331
		//preliminary to comply with current Index Fungorum display
332
		if (StringUtils.isNotBlank(location)){
333
			title += " (" + location +")";
334
		}
335
		//end preliminary
336
		if (StringUtils.isNotBlank(title)){
337
			if (hasInReference){
338
				ref.getInReference().setTitle(title);
339
			}else{
340
				ref.setTitle(title);
341
			}
342
		}
343
		//Volume
344
		String volume = CdmUtils.Nz(rs.getString("VOLUME")).trim();
345
		String part = rs.getString("PART");
346
		if (StringUtils.isNotBlank(part)){
347
			volume = volume + "(" + part + ")";
348
			if (StringUtils.isBlank(volume)){
349
				logger.warn("'Part' is not blank for blank volume. This may be an inconsistency.");
350
			}
351
		}
352
		ref.setVolume(volume);
353

    
354
		//year
355
		String yearOfPubl = rs.getString("YEAR OF PUBLICATION");
356
		String yearOnPubl = rs.getString("YEAR ON PUBLICATION");
357
		String year = null;
358
		if (StringUtils.isNotBlank(yearOfPubl)){
359
			year = yearOfPubl.trim();
360
		}
361
		if (StringUtils.isNotBlank(yearOnPubl)){
362
			year = CdmUtils.concat(" ", year, "[" + yearOnPubl + "]");
363
		}
364
		if (year != null){
365
			ref.setDatePublished(TimePeriodParser.parseString(year));
366
		}
367

    
368
		//preliminary, set protected titlecache as Generic Cache Generation with in references currently doesn't fully work yet
369
		String titleCache = CdmUtils.concat(", ", pubAuthorStr, title);
370
		if  ( StringUtils.isNotBlank(pubAuthorStr)){
371
			titleCache = "in " + titleCache;
372
		}
373
		titleCache = CdmUtils.concat(" ", titleCache, volume);
374
		titleCache = CdmUtils.concat(": ", titleCache, page);
375
		titleCache = CdmUtils.concat(". ", titleCache, year);
376
		ref.setTitleCache(titleCache, true);
377

    
378
		//set nom ref
379
		if (StringUtils.isNotBlank(titleCache)){
380
			name.setNomenclaturalReference(ref);
381
		}
382
	}
383

    
384

    
385
	protected MarkerType getNoLastActionMarkerType(IndexFungorumImportState state) {
386
		return getMarkerType(state, DbLastActionMapper.uuidMarkerTypeHasNoLastAction,
387
				"has no last action", "No last action information available", "no last action");
388
	}
389

    
390

    
391
	protected void makeSource(IndexFungorumImportState state, Taxon taxon, Integer id, String namespace) {
392
		//source reference
393
		Reference sourceReference = state.getRelatedObject(NAMESPACE_REFERENCE, SOURCE_REFERENCE, Reference.class);
394
		//source
395
		String strId = (id == null ? null : String.valueOf(id));
396
		IdentifiableSource source = IdentifiableSource.NewInstance(OriginalSourceType.Import, strId, namespace, sourceReference, null);
397
		taxon.addSource(source);
398

    
399
		//no last action
400
		MarkerType hasNoLastAction = getNoLastActionMarkerType(state);
401
		taxon.addMarker(Marker.NewInstance(hasNoLastAction, true));
402
		//LSID
403
		makeLSID(taxon, strId, state);
404
	}
405

    
406
	private void makeLSID(Taxon taxon, String strId, IndexFungorumImportState state) {
407
		try {
408
			if (StringUtils.isNotBlank(strId) &&  strId != null){
409
				LSID lsid = new LSID(IndexFungorumTransformer.LSID_PREFIX + strId);
410
				taxon.setLsid(lsid);
411
			}else{
412
				logger.warn("No ID available for taxon " + taxon.getTitleCache() + ", " +  taxon.getUuid());
413
				MarkerType missingGUID = getMissingGUIDMarkerType(state);
414
				taxon.addMarker(Marker.NewInstance(missingGUID, true));
415
			}
416
		} catch (MalformedLSIDException e) {
417
			logger.error(e.getMessage());
418
		}
419
	}
420

    
421
	protected MarkerType getMissingGUIDMarkerType(IndexFungorumImportState state) {
422
		MarkerType missingGUID = getMarkerType(state, PesiTransformer.uuidMarkerGuidIsMissing, "GUID is missing", "GUID is missing", null);
423
		return missingGUID;
424
	}
425

    
426

    
427
	protected Classification getClassification(IndexFungorumImportState state) {
428
		Classification result;
429
		UUID classificationUuid = state.getTreeUuid(state.getConfig().getSourceReference());
430
		if (classificationUuid == null){
431
			Reference sourceReference = state.getRelatedObject(NAMESPACE_REFERENCE, SOURCE_REFERENCE, Reference.class);
432
			result = makeTreeMemSave(state, sourceReference);
433
		} else {
434
			result = getClassificationService().find(classificationUuid);
435
		}
436
		return result;
437
	}
438

    
439

    
440

    
441

    
442

    
443
}
(4-4/10)