Project

General

Profile

Download (13.4 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.name.INonViralName;
42
import eu.etaxonomy.cdm.model.reference.OriginalSourceType;
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

    
57
    private static final long serialVersionUID = -729872543287390949L;
58
    private static final Logger logger = Logger.getLogger(IndexFungorumImportBase.class);
59

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

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

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

    
72
	private final String pluralString;
73
	private final String dbTableName;
74

    
75

    
76
	public IndexFungorumImportBase(String pluralString, String dbTableName, Class cdmTargetClass) {
77
		this.pluralString = pluralString;
78
		this.dbTableName = dbTableName;
79
	}
80

    
81
	@Override
82
    protected void doInvoke(IndexFungorumImportState state){
83
		System.out.println("start make " + getPluralString() + " ...");
84
		IndexFungorumImportConfigurator config = state.getConfig();
85
		Source source = config.getSource();
86

    
87
		String strIdQuery = getIdQuery();
88
		String strRecordQuery = getRecordQuery(config);
89

    
90
		int recordsPerTransaction = config.getRecordsPerTransaction();
91
		try{
92
			ResultSetPartitioner<IndexFungorumImportState> partitioner = ResultSetPartitioner.NewInstance(source, strIdQuery, strRecordQuery, recordsPerTransaction);
93
			while (partitioner.nextPartition()){
94
				partitioner.doPartition(this, state);
95
			}
96
		} catch (SQLException e) {
97
			logger.error("SQLException:" +  e);
98
			state.setUnsuccessfull();
99
			return;
100
		}
101

    
102
		logger.info("end make " + getPluralString() + " ... " + getSuccessString(true));
103
		return;
104
	}
105

    
106
    @Override
107
    public boolean doPartition(@SuppressWarnings("rawtypes") ResultSetPartitioner partitioner, IndexFungorumImportState state) {
108

    
109
        boolean success = true ;
110
		Set<CdmBase> objectsToSave = new HashSet<>();
111

    
112
// 		DbImportMapping<?, ?> mapping = getMapping();
113
//		mapping.initialize(state, cdmTargetClass);
114

    
115
		ResultSet rs = partitioner.getResultSet();
116
		try{
117
			while (rs.next()){
118
//				success &= mapping.invoke(rs,objectsToSave);
119
			}
120
		} catch (SQLException e) {
121
			logger.error("SQLException:" +  e);
122
			return false;
123
		}
124

    
125
		partitioner.startDoSave();
126
		getCommonService().save(objectsToSave);
127
		return success;
128
	}
129

    
130
	protected abstract String getRecordQuery(IndexFungorumImportConfigurator config);
131

    
132
	protected String getIdQuery(){
133
		String result = " SELECT id FROM " + getTableName();
134
		return result;
135
	}
136

    
137
	@Override
138
    public String getPluralString(){
139
		return pluralString;
140
	}
141

    
142
	protected String getTableName(){
143
		return this.dbTableName;
144
	}
145

    
146
	protected boolean resultSetHasColumn(ResultSet rs, String columnName){
147
		try {
148
			ResultSetMetaData metaData = rs.getMetaData();
149
			for (int i = 0; i < metaData.getColumnCount(); i++){
150
				if (metaData.getColumnName(i + 1).equalsIgnoreCase(columnName)){
151
					return true;
152
				}
153
			}
154
			return false;
155
		} catch (SQLException e) {
156
            logger.warn("Exception in resultSetHasColumn");
157
            return false;
158
		}
159
	}
160

    
161
	protected boolean checkSqlServerColumnExists(Source source, String tableName, String columnName){
162
		String strQuery = "SELECT  Count(t.id) as n " +
163
				" FROM sysobjects AS t " +
164
				" INNER JOIN syscolumns AS c ON t.id = c.id " +
165
				" WHERE (t.xtype = 'U') AND " +
166
				" (t.name = '" + tableName + "') AND " +
167
				" (c.name = '" + columnName + "')";
168
		ResultSet rs = source.getResultSet(strQuery) ;
169
		int n;
170
		try {
171
			rs.next();
172
			n = rs.getInt("n");
173
			return n>0;
174
		} catch (SQLException e) {
175
			e.printStackTrace();
176
			return false;
177
		}
178
	}
179

    
180
	/**
181
	 * Returns a map that holds all values of a ResultSet. This is needed if a value needs to
182
	 * be accessed twice
183
	 * @param rs
184
	 * @return
185
	 * @throws SQLException
186
	 */
187
	protected Map<String, Object> getValueMap(ResultSet rs) throws SQLException{
188
		try{
189
			Map<String, Object> valueMap = new HashMap<>();
190
			int colCount = rs.getMetaData().getColumnCount();
191
			for (int c = 0; c < colCount ; c++){
192
				Object value = rs.getObject(c+1);
193
				String label = rs.getMetaData().getColumnLabel(c+1).toLowerCase();
194
				if (value != null && ! CdmUtils.Nz(value.toString()).trim().equals("")){
195
					valueMap.put(label, value);
196
				}
197
			}
198
			return valueMap;
199
		}catch(SQLException e){
200
			throw e;
201
		}
202
	}
203

    
204
	/**
205
	 * Reads a foreign key field from the result set and adds its value to the idSet.
206
	 * @param rs
207
	 * @param teamIdSet
208
	 * @throws SQLException
209
	 */
210
	protected void handleForeignKey(ResultSet rs, Set<String> idSet, String attributeName)
211
			throws SQLException {
212
		Object idObj = rs.getObject(attributeName);
213
		if (idObj != null){
214
			String id  = String.valueOf(idObj);
215
			idSet.add(id);
216
		}
217
	}
218

    
219
	/**
220
	 * Returns true if i is a multiple of recordsPerTransaction
221
	 * @param i
222
	 * @param recordsPerTransaction
223
	 * @return
224
	 */
225
	protected boolean loopNeedsHandling(int i, int recordsPerLoop) {
226
		startTransaction();
227
		return (i % recordsPerLoop) == 0;
228
	}
229

    
230
	protected void doLogPerLoop(int count, int recordsPerLog, String pluralString){
231
		if ((count % recordsPerLog ) == 0 && count!= 0 ){ logger.info(pluralString + " handled: " + (count));}
232
	}
233

    
234
	protected void makeAuthorAndPublication(IndexFungorumImportState state, ResultSet rs, INonViralName name) throws SQLException {
235
		//authors
236
		NonViralNameParserImpl parser = NonViralNameParserImpl.NewInstance();
237
		String authorStr = rs.getString("AUTHORS");
238
		if (StringUtils.isNotBlank(authorStr)){
239
			try {
240
				parser.parseAuthors(name, authorStr);
241
			} catch (StringNotParsableException e){
242
				//logger.warn("Authorstring not parsable: " + authorStr);
243
				name.setAuthorshipCache(authorStr);
244
			}
245
		}
246

    
247
		//page
248
		String page = rs.getString("PAGE");
249
		if (StringUtils.isNotBlank(page)){
250
			name.setNomenclaturalMicroReference(page);
251
		}
252

    
253
		//Reference
254
		Reference ref = ReferenceFactory.newGeneric();
255
		boolean hasInReference = false;
256
		//publishing authors
257
		Team pubAuthor = null;
258
		String pubAuthorStr = rs.getString("PUBLISHING AUTHORS");
259
		if (StringUtils.isNotBlank(pubAuthorStr)){
260
			if (StringUtils.isNotBlank(authorStr)){
261
				if (! pubAuthorStr.equals(authorStr)){
262
					pubAuthor = Team.NewTitledInstance(pubAuthorStr, pubAuthorStr);
263
				}
264
			}else{
265
				logger.warn("'AUTHORS' is blank for not empty PUBLISHING_AUTHORS. This is not yet handled.");
266
			}
267
		}
268

    
269
		//inRef + inRefAuthor
270
		if (pubAuthor != null){
271
			Reference inRef = ReferenceFactory.newGeneric();
272
			inRef.setAuthorship(pubAuthor);
273
			ref.setInReference(inRef);
274
			hasInReference = true;
275
		}
276

    
277
		//refAuthor
278
		TeamOrPersonBase<?> refAuthor = CdmBase.deproxy(name.getCombinationAuthorship());
279
		if (refAuthor == null){
280
			refAuthor = Team.NewTitledInstance(authorStr, authorStr);
281
		}
282
		ref.setAuthorship(refAuthor);
283
		//location
284
		String location = rs.getString("pubIMIAbbrLoc");
285
		if (StringUtils.isNotBlank(location)){
286
			if (hasInReference){
287
				ref.getInReference().setPlacePublished(location);
288
			}else{
289
				ref.setPlacePublished(location);
290
			}
291
		}
292
		//title
293
		String titleMain = rs.getString("pubIMIAbbr");
294
		String supTitle = rs.getString("pubIMISupAbbr");
295
		String title = CdmUtils.concat(", ", titleMain, supTitle);
296
		//preliminary to comply with current Index Fungorum display
297
		if (StringUtils.isNotBlank(location)){
298
			title += " (" + location +")";
299
		}
300
		//end preliminary
301
		if (StringUtils.isNotBlank(title)){
302
			if (hasInReference){
303
				ref.getInReference().setTitle(title);
304
			}else{
305
				ref.setTitle(title);
306
			}
307
		}
308
		//Volume
309
		String volume = CdmUtils.Nz(rs.getString("VOLUME")).trim();
310
		String part = rs.getString("PART");
311
		if (StringUtils.isNotBlank(part)){
312
			volume = volume + "(" + part + ")";
313
			if (StringUtils.isBlank(volume)){
314
				logger.warn("'Part' is not blank for blank volume. This may be an inconsistency.");
315
			}
316
		}
317
		ref.setVolume(volume);
318

    
319
		//year   //TODO why yearOfPubl 2x exact same value
320
		String yearOfPubl = rs.getString("YEAR OF PUBLICATION");
321
		String yearOnPubl = rs.getString("YEAR ON PUBLICATION");
322
		String year = null;
323
		if (StringUtils.isNotBlank(yearOfPubl)){
324
			year = yearOfPubl.trim();
325
		}
326
		if (StringUtils.isNotBlank(yearOnPubl)){
327
			year = CdmUtils.concat(" ", year, "[" + yearOnPubl + "]");
328
		}
329
		if (year != null){
330
			ref.setDatePublished(TimePeriodParser.parseStringVerbatim(year));
331
		}
332

    
333
		//preliminary, set protected titlecache as Generic Cache Generation with in references currently doesn't fully work yet
334
		String titleCache = CdmUtils.concat(", ", pubAuthorStr, title);
335
		if  ( StringUtils.isNotBlank(pubAuthorStr)){
336
			titleCache = "in " + titleCache;
337
		}
338
		titleCache = CdmUtils.concat(" ", titleCache, volume);
339
		titleCache = CdmUtils.concat(": ", titleCache, page);
340
		titleCache = CdmUtils.concat(". ", titleCache, year);
341
		ref.setTitleCache(titleCache, true);
342

    
343
		//set nom ref
344
		if (StringUtils.isNotBlank(titleCache)){
345
			name.setNomenclaturalReference(ref);
346
		}
347
	}
348

    
349
	protected MarkerType getNoLastActionMarkerType(IndexFungorumImportState state) {
350
		return getMarkerType(state, DbLastActionMapper.uuidMarkerTypeHasNoLastAction,
351
				"has no last action", "No last action information available", "no last action");
352
	}
353

    
354
	protected void makeSource(IndexFungorumImportState state, Taxon taxon, Integer id, String namespace) {
355
		//source reference
356
		Reference sourceReference = state.getRelatedObject(NAMESPACE_REFERENCE, SOURCE_REFERENCE, Reference.class);
357
		//source
358
		String strId = (id == null ? null : String.valueOf(id));
359
		IdentifiableSource source = IdentifiableSource.NewInstance(OriginalSourceType.Import, strId, namespace, sourceReference, null);
360
		taxon.addSource(source);
361

    
362
		//no last action
363
		MarkerType hasNoLastAction = getNoLastActionMarkerType(state);
364
		taxon.addMarker(Marker.NewInstance(hasNoLastAction, true));
365
		//LSID
366
		makeLSID(taxon, strId, state);
367
	}
368

    
369
	private void makeLSID(Taxon taxon, String strId, IndexFungorumImportState state) {
370
		try {
371
			if (StringUtils.isNotBlank(strId) &&  strId != null){
372
				LSID lsid = new LSID(IndexFungorumTransformer.LSID_PREFIX + strId);
373
				taxon.setLsid(lsid);
374
			}else{
375
				logger.warn("No ID available for taxon " + taxon.getTitleCache() + ", " +  taxon.getUuid());
376
				MarkerType missingGUID = getMissingGUIDMarkerType(state);
377
				taxon.addMarker(Marker.NewInstance(missingGUID, true));
378
			}
379
		} catch (MalformedLSIDException e) {
380
			logger.error(e.getMessage());
381
		}
382
	}
383

    
384
	protected MarkerType getMissingGUIDMarkerType(IndexFungorumImportState state) {
385
		MarkerType missingGUID = getMarkerType(state, PesiTransformer.uuidMarkerGuidIsMissing, "GUID is missing", "GUID is missing", null);
386
		return missingGUID;
387
	}
388

    
389
	protected Classification getClassification(IndexFungorumImportState state) {
390
		Classification result;
391
		UUID classificationUuid = state.getTreeUuid(state.getConfig().getSourceReference());
392
		if (classificationUuid == null){
393
			Reference sourceReference = state.getRelatedObject(NAMESPACE_REFERENCE, SOURCE_REFERENCE, Reference.class);
394
			result = makeTreeMemSave(state, sourceReference);
395
		} else {
396
			result = getClassificationService().find(classificationUuid);
397
		}
398
		return result;
399
	}
400
}
(4-4/10)