Project

General

Profile

Download (10.6 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.berlinModel.in;
11

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

    
21
import org.apache.log4j.Logger;
22
import org.springframework.stereotype.Component;
23

    
24
import eu.etaxonomy.cdm.common.CdmUtils;
25
import eu.etaxonomy.cdm.io.berlinModel.in.validation.BerlinModelOccurrenceSourceImportValidator;
26
import eu.etaxonomy.cdm.io.common.IOValidator;
27
import eu.etaxonomy.cdm.io.common.ResultSetPartitioner;
28
import eu.etaxonomy.cdm.io.common.Source;
29
import eu.etaxonomy.cdm.model.common.CdmBase;
30
import eu.etaxonomy.cdm.model.common.OriginalSourceType;
31
import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
32
import eu.etaxonomy.cdm.model.description.DescriptionElementSource;
33
import eu.etaxonomy.cdm.model.description.Distribution;
34
import eu.etaxonomy.cdm.model.name.INonViralName;
35
import eu.etaxonomy.cdm.model.name.TaxonName;
36
import eu.etaxonomy.cdm.model.reference.Reference;
37

    
38

    
39
/**
40
 * @author a.mueller
41
 * @since 20.03.2008
42
 */
43
@Component
44
public class BerlinModelOccurrenceSourceImport  extends BerlinModelImportBase {
45

    
46
    private static final long serialVersionUID = 1139543760239436841L;
47

    
48
    private static final Logger logger = Logger.getLogger(BerlinModelOccurrenceSourceImport.class);
49

    
50
	private static int modCount = 5000;
51
	private static final String pluralString = "occurrence sources";
52
	private static final String dbTableName = "emOccurrenceSource";  //??
53

    
54

    
55
	private Map<String, Integer> sourceNumberRefIdMap;
56
	private Set<String> unfoundReferences = new HashSet<String>();
57

    
58

    
59
	public BerlinModelOccurrenceSourceImport(){
60
		super(dbTableName, pluralString);
61
	}
62

    
63
	@Override
64
	protected String getIdQuery(BerlinModelImportState state) {
65
		String result = "SELECT occurrenceSourceId FROM " + getTableName();
66
		if (state.getConfig().getOccurrenceSourceFilter() != null){
67
			result += " WHERE " +  state.getConfig().getOccurrenceSourceFilter();
68
		}
69
		return result;
70
	}
71

    
72
	@Override
73
	protected String getRecordQuery(BerlinModelImportConfigurator config) {
74
			String strQuery =   //DISTINCT because otherwise emOccurrenceSource creates multiple records for a single distribution
75
            " SELECT * " +
76
                " FROM emOccurrenceSource " +
77
            " WHERE (OccurrenceSourceId IN (" + ID_LIST_TOKEN + ")  )" +
78
             "";
79
		return strQuery;
80
	}
81

    
82

    
83

    
84
	@Override
85
	protected void doInvoke(BerlinModelImportState state) {
86
		unfoundReferences = new HashSet<String>();
87

    
88
		try {
89
			sourceNumberRefIdMap = makeSourceNumberReferenceIdMap(state);
90
		} catch (SQLException e) {
91
			e.printStackTrace();
92
			throw new RuntimeException(e);
93
		}
94
		super.doInvoke(state);
95
		sourceNumberRefIdMap = null;
96
		if (unfoundReferences.size()>0){
97
			String unfound = "'" + CdmUtils.concat("','", unfoundReferences.toArray(new String[]{})) + "'";
98
			logger.warn("Not found references: " + unfound);
99
		}
100
		return;
101
	}
102

    
103
	@Override
104
	public boolean doPartition(ResultSetPartitioner partitioner, BerlinModelImportState state) {
105
		boolean success = true;
106
		ResultSet rs = partitioner.getResultSet();
107
		Map<String, Reference> refMap = partitioner.getObjectMap(BerlinModelReferenceImport.REFERENCE_NAMESPACE);
108

    
109
		Set<DescriptionElementBase> objectsToSave = new HashSet<DescriptionElementBase>();
110
		try {
111
			int i = 0;
112
			//for each reference
113
            while (rs.next()){
114

    
115
                if ((i++ % modCount) == 0 && i!= 1 ){ logger.info("occurrence sources handled: " + (i-1));}
116

    
117
                Integer occurrenceSourceId = rs.getInt("OccurrenceSourceId");
118
                Integer occurrenceFk =nullSafeInt(rs, "OccurrenceFk");
119
    			String sourceNumber = rs.getString("SourceNumber");
120
    			String oldName = rs.getString("OldName");
121
    			Integer oldNameFk = nullSafeInt(rs, "OldNameFk");
122

    
123
    			Distribution distribution = (Distribution)state.getRelatedObject(BerlinModelOccurrenceImport.NAMESPACE, String.valueOf(occurrenceFk));
124

    
125
    			if (distribution == null){
126
    				//distribution = duplicateMap.get(occurrenceFk);
127
    			}
128
    			if (distribution != null){
129
    				Integer refId = sourceNumberRefIdMap.get(sourceNumber);
130
    				Reference ref = refMap.get(String.valueOf(refId));
131

    
132
    				if (ref != null){
133
    					DescriptionElementSource originalSource = DescriptionElementSource.NewInstance(OriginalSourceType.PrimaryTaxonomicSource);
134
    					originalSource.setCitation(ref);
135
    					TaxonName taxonName;
136
						taxonName = TaxonName.castAndDeproxy(getName(state, oldName, oldNameFk));
137
						if (taxonName != null){
138
    						originalSource.setNameUsedInSource(taxonName);
139
    					}else if(isNotBlank(oldName)){
140
    						originalSource.setOriginalNameString(oldName);
141
    					}
142
    					distribution.addSource(originalSource);
143
    				}else{
144
    					logger.warn("reference for sourceNumber "+sourceNumber+" could not be found. OccurrenceSourceId: " + occurrenceSourceId );
145
    					unfoundReferences.add(sourceNumber);
146
    				}
147
    			}else{
148
    				logger.warn("distribution ("+occurrenceFk+") for occurrence source (" + occurrenceSourceId + ") could not be found." );
149
    			}
150

    
151
            }
152
			logger.info("Distributions to save: " + objectsToSave.size());
153
			getDescriptionService().saveDescriptionElement(objectsToSave);
154

    
155
			return success;
156
		} catch (SQLException e) {
157
			logger.error("SQLException:" +  e);
158
			return false;
159
		}
160
	}
161

    
162

    
163
	@Override
164
	public Map<Object, Map<String, ? extends CdmBase>> getRelatedObjectsForPartition(ResultSet rs, BerlinModelImportState state) {
165
		String nameSpace;
166
		Class<?> cdmClass;
167
		Set<String> idSet;
168
		Map<Object, Map<String, ? extends CdmBase>> result = new HashMap<Object, Map<String, ? extends CdmBase>>();
169

    
170
		try{
171
			Set<String> occurrenceIdSet = new HashSet<String>();
172
			Set<String> referenceIdSet = new HashSet<String>();
173
			Set<String> nameIdSet = new HashSet<String>();
174
			Set<String> sourceNumberSet = new HashSet<String>();
175
			while (rs.next()){
176
				handleForeignKey(rs, occurrenceIdSet, "occurrenceFk");
177
				handleForeignKey(rs, nameIdSet, "oldNameFk");
178
				sourceNumberSet.add(CdmUtils.NzTrim(rs.getString("SourceNumber")));
179
			}
180

    
181
			sourceNumberSet.remove("");
182
			referenceIdSet = handleSourceNumber(rs, sourceNumberSet, result);
183

    
184

    
185
			//occurrence map
186
			nameSpace = BerlinModelOccurrenceImport.NAMESPACE;
187
			cdmClass = Distribution.class;
188
			idSet = occurrenceIdSet;
189
			Map<String, Distribution> occurrenceMap = (Map<String, Distribution>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
190
			result.put(nameSpace, occurrenceMap);
191

    
192
			//name map
193
			nameSpace = BerlinModelTaxonNameImport.NAMESPACE;
194
			cdmClass = TaxonName.class;
195
			idSet =nameIdSet;
196
			Map<String, TaxonName> nameMap = (Map<String, TaxonName>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
197
			result.put(nameSpace, nameMap);
198

    
199
			//reference map
200
			nameSpace = BerlinModelReferenceImport.REFERENCE_NAMESPACE;
201
			cdmClass = Reference.class;
202
			idSet = referenceIdSet;
203
			Map<String, Reference> referenceMap = (Map<String, Reference>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
204
			result.put(nameSpace, referenceMap);
205

    
206
		} catch (SQLException e) {
207
			throw new RuntimeException(e);
208
		}
209
		return result;
210
	}
211

    
212
	private Set<String> handleSourceNumber(ResultSet rs, Set<String> sourceNumberSet, Map<Object, Map<String, ? extends CdmBase>> result) {
213
		Map<String, Integer> sourceNumberReferenceIdMap = this.sourceNumberRefIdMap;
214
		Set<String> referenceIdSet = new HashSet<String>();
215

    
216
		for(String sourceNumber : sourceNumberSet){
217
			Integer refId = sourceNumberReferenceIdMap.get(sourceNumber);
218
			referenceIdSet.add(String.valueOf(refId));
219
		}
220
		return referenceIdSet;
221
	}
222

    
223

    
224

    
225
	/**
226
	 * @param state
227
	 * @param oldName
228
	 * @param oldNameFk
229
	 * @return
230
	 */
231
	boolean isFirstTimeNoNameByService = true;
232
	private INonViralName getName(BerlinModelImportState state, String oldName, Integer oldNameFk) {
233
		TaxonName taxonName = (TaxonName)state.getRelatedObject(BerlinModelTaxonNameImport.NAMESPACE, String.valueOf(oldNameFk));
234
		if (taxonName == null && oldName != null){
235
			if (isFirstTimeNoNameByService){
236
				logger.warn("oldName not checked against names in BerlinModel. Just take it as a string");
237
				isFirstTimeNoNameByService = false;
238
			}
239
			List<INonViralName> names = new ArrayList<>();
240
//			names = getNameService().getNamesByNameCache(oldName);
241
			if (names.isEmpty()){
242
				return null;
243
			}else {
244
				if (names.size()> 1){
245
					logger.info("There is more than one name matching oldName: " + oldName + ".");
246
				}
247
				return names.get(0);
248
				//taxonName = nameParser.parseSimpleName(oldName);
249
			}
250
		}
251
		return taxonName;
252
	}
253

    
254
	/**
255
	 * Creates a map which maps source numbers on references
256
	 * @param state
257
	 * @return
258
     * @throws SQLException
259
	 */
260
	private Map<String, Integer> makeSourceNumberReferenceIdMap(BerlinModelImportState state) throws SQLException {
261
		Map<String, Integer> result = new HashMap<String, Integer>();
262

    
263
		Source source = state.getConfig().getSource();
264
		String strQuery = " SELECT RefId, IdInSource " +
265
						  " FROM Reference " +
266
						  " WHERE     (IdInSource IS NOT NULL) AND (IdInSource NOT LIKE '') ";
267

    
268
		ResultSet rs = source.getResultSet(strQuery) ;
269
		while (rs.next()){
270
			int refId = rs.getInt("RefId");
271
			String idInSource = rs.getString("IdInSource");
272
			if (idInSource != null){
273
				String[] singleSources = idInSource.split("\\|");
274
				for (String singleSource : singleSources){
275
					singleSource = singleSource.trim();
276
					result.put(singleSource, refId);
277
				}
278
			}
279
		}
280
		return result;
281
	}
282

    
283
	@Override
284
	protected boolean doCheck(BerlinModelImportState state){
285
		IOValidator<BerlinModelImportState> validator = new BerlinModelOccurrenceSourceImportValidator();
286
		return validator.validate(state);
287
	}
288

    
289
	@Override
290
	protected boolean isIgnore(BerlinModelImportState state){
291
		if (! state.getConfig().isDoOccurrence()){
292
			return true;
293
		}else{
294
			if (!this.checkSqlServerColumnExists(state.getConfig().getSource(), "emOccurrenceSource", "OccurrenceSourceId")){
295
				logger.error("emOccurrenceSource table or emOccurrenceSourceId does not exist. Must ignore occurrence import");
296
				return true;
297
			}else{
298
				return false;
299
			}
300
		}
301
	}
302

    
303
}
(11-11/21)