Project

General

Profile

Download (10.5 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2008 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
package eu.etaxonomy.cdm.io.excel.distribution;
10

    
11
import java.io.FileNotFoundException;
12
import java.net.URI;
13
import java.util.ArrayList;
14
import java.util.HashMap;
15
import java.util.List;
16
import java.util.Map;
17
import java.util.Set;
18

    
19
import org.apache.log4j.Logger;
20
import org.springframework.stereotype.Component;
21
import org.springframework.transaction.TransactionStatus;
22

    
23
import eu.etaxonomy.cdm.api.service.config.IdentifiableServiceConfiguratorFactory;
24
import eu.etaxonomy.cdm.api.service.config.IdentifiableServiceConfiguratorImpl;
25
import eu.etaxonomy.cdm.common.CdmUtils;
26
import eu.etaxonomy.cdm.common.ExcelUtils;
27
import eu.etaxonomy.cdm.io.common.CdmIoBase;
28
import eu.etaxonomy.cdm.io.common.ICdmIO;
29
import eu.etaxonomy.cdm.io.excel.common.ExcelImportConfiguratorBase;
30
import eu.etaxonomy.cdm.io.excel.common.ExcelImportState;
31
import eu.etaxonomy.cdm.io.excel.common.ExcelRowBase;
32
import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
33
import eu.etaxonomy.cdm.model.description.Distribution;
34
import eu.etaxonomy.cdm.model.description.PresenceAbsenceTermBase;
35
import eu.etaxonomy.cdm.model.description.PresenceTerm;
36
import eu.etaxonomy.cdm.model.description.TaxonDescription;
37
import eu.etaxonomy.cdm.model.location.NamedArea;
38
import eu.etaxonomy.cdm.model.location.TdwgArea;
39
import eu.etaxonomy.cdm.model.name.TaxonNameBase;
40
import eu.etaxonomy.cdm.model.taxon.Taxon;
41
import eu.etaxonomy.cdm.persistence.query.MatchMode;
42

    
43
/**
44
 * @author a.babadshanjan
45
 * @created 10.11.2008
46
 * @version 1.0
47
 */
48
@Component
49
public class DistributionImport extends CdmIoBase<ExcelImportState<ExcelImportConfiguratorBase, ExcelRowBase>> implements ICdmIO<ExcelImportState<ExcelImportConfiguratorBase, ExcelRowBase>> {
50
	private static final Logger logger = Logger.getLogger(DistributionImport.class);
51

    
52
    /* used */
53
    private static final String EDIT_NAME_COLUMN = "EDIT";
54
    private static final String TDWG_DISTRIBUTION_COLUMN = "TDWG";
55
    private static final String STATUS_COLUMN = "Status";
56
    /* not used */
57
//    private static final String LITERATURE_NUMBER_COLUMN = "Lit.";
58
//    private static final String LITERATURE_COLUMN = "Literature";
59
//    private static final String VERNACULAR_NAME_COLUMN = "Vernacular";
60
//    private static final String HABITAT_COLUMN = "Habitat";
61
//    private static final String CONTROL_COLUMN = "Control";
62
//    private static final String TRANSLATED_COLUMN = "Translated";
63
//    private static final String ISO_DISTRIBUTION_COLUMN = "ISO";
64
//    private static final String NOTES_COLUMN = "Notes";
65
//    private static final String PAGE_NUMBER_COLUMN = "Page";
66
//    private static final String INFO_COLUMN = "Info";
67
    
68
	
69
	// Stores already processed descriptions
70
	Map<Taxon, TaxonDescription> myDescriptions = new HashMap<Taxon, TaxonDescription>();
71

    
72
	@Override
73
	protected void doInvoke(ExcelImportState<ExcelImportConfiguratorBase, ExcelRowBase> state) {
74
		
75
		if (logger.isDebugEnabled()) { logger.debug("Importing distribution data"); }
76
    	
77
		// read and save all rows of the excel worksheet
78
		ArrayList<HashMap<String, String>> recordList;
79
		URI source = state.getConfig().getSource();
80
		try{
81
    		recordList = ExcelUtils.parseXLS(source);
82
		} catch (FileNotFoundException e) {
83
			String message = "File not found: " + source;
84
			warnProgress(state, message, e);
85
			logger.error(message);
86
			state.setUnsuccessfull();
87
			return;
88
		}
89
    	if (recordList != null) {
90
    		HashMap<String,String> record = null;
91
    		TransactionStatus txStatus = startTransaction();
92

    
93
    		for (int i = 0; i < recordList.size(); i++) {
94
    			record = recordList.get(i);
95
    			analyzeRecord(record);
96
    		}
97
    		commitTransaction(txStatus);
98
    	}
99
    	
100
		try {
101
			if (logger.isDebugEnabled()) { logger.debug("End distribution data import"); }
102
				
103
		} catch (Exception e) {
104
    		logger.error("Error closing the application context");
105
    		e.printStackTrace();
106
		}
107
    	
108
    	return;
109
	}
110
			
111

    
112
	/** 
113
	 *  Reads the data of one Excel sheet row
114
	 */
115
    private void analyzeRecord(HashMap<String,String> record) {
116
    	/*
117
    	 * Relevant columns:
118
    	 * Name (EDIT)
119
    	 * Distribution TDWG
120
    	 * Status (only entries if not native) 
121
    	 * Literature number
122
    	 * Literature
123
    	*/
124
    	
125
        String editName = "";
126
        ArrayList<String> distributionList = new ArrayList<String>();
127
        String status = "";
128
        String literatureNumber = "";
129
        String literature = "";
130
        
131
    	Set<String> keys = record.keySet();
132
    	
133
    	for (String key: keys) {
134
    		
135
    		String value = (String) record.get(key);
136
    		if (!value.equals("")) {
137
    			if (logger.isDebugEnabled()) { logger.debug(key + ": '" + value + "'"); }
138
    		}
139
    		
140
    		if (key.contains(EDIT_NAME_COLUMN)) {
141
    			editName = (String) CdmUtils.removeDuplicateWhitespace(value.trim());
142
    			
143
			} else if(key.contains(TDWG_DISTRIBUTION_COLUMN)) {
144
				distributionList =  CdmUtils.buildList(value);
145
				
146
			} else if(key.contains(STATUS_COLUMN)) {
147
				status = (String) CdmUtils.removeDuplicateWhitespace(value.trim());
148
				
149
//			} else if(key.contains(LITERATURE_NUMBER_COLUMN)) {
150
//				literatureNumber = (String) CdmUtils.removeDuplicateWhitespace(value.trim());
151
//				
152
//			} else if(key.contains(LITERATURE_COLUMN)) {
153
//				literature = (String) CdmUtils.removeDuplicateWhitespace(value.trim());
154
//				
155
			} else {
156
				//logger.warn("Column " + key + " ignored");
157
			}
158
    	}
159
    	
160
    	// Store the data of this record in the DB
161
    	if (!editName.equals("")) {
162
    		saveRecord(editName, distributionList, status, literatureNumber, literature);
163
    	}
164
    }
165
    
166
    
167
	/** 
168
	 *  Stores the data of one Excel sheet row in the database
169
	 */
170
    private void saveRecord(String taxonName, ArrayList<String> distributionList,
171
    		String status, String literatureNumber, String literature) {
172

    
173
    	IdentifiableServiceConfiguratorImpl<TaxonNameBase> config = IdentifiableServiceConfiguratorFactory.getConfigurator(TaxonNameBase.class);
174
    	config.setTitleSearchString(taxonName);
175
    	config.setMatchMode(MatchMode.BEGINNING);
176
    	
177
		try {
178
    		// get the matching names from the DB
179
    		//List<TaxonNameBase> taxonNameBases = getNameService().findByTitle(config);
180
    		List<TaxonNameBase<?,?>> taxonNameBases = getNameService().findNamesByTitle(taxonName);
181
    		if (taxonNameBases.isEmpty()) {
182
    			logger.error("Taxon name '" + taxonName + "' not found in DB");
183
    		} else {
184
    			if (logger.isDebugEnabled()) { logger.debug("Taxon found"); }
185
    		}
186

    
187
    		// get the taxa for the matching names
188
    		for(TaxonNameBase<?,?> dbTaxonName: taxonNameBases) {
189

    
190
    			Set<Taxon> taxa = dbTaxonName.getTaxa();
191
    			if (taxa.isEmpty()) {
192
    				logger.warn("No taxon found for name '" + taxonName + "'");
193
    			} else if (taxa.size() > 1) {
194
    				logger.warn("More than one taxa found for name '" + taxonName + "'");
195
    			}
196

    
197
    			for(Taxon taxon: taxa) {
198

    
199
    				TaxonDescription myDescription = null;
200

    
201
    				// If we have created a description for this taxon earlier, take this one.
202
    				// Otherwise, create a new description.
203
    				// We don't update any existing descriptions in the database at this point.
204
    				if (myDescriptions.containsKey(taxon)) {
205
    					myDescription = myDescriptions.get(taxon);
206
    				} else {
207
    					myDescription = TaxonDescription.NewInstance(taxon);
208
    					taxon.addDescription(myDescription);
209
    					myDescriptions.put(taxon, myDescription);
210
    				}
211

    
212
    				// Status
213
    				PresenceAbsenceTermBase<?> presenceAbsenceStatus = PresenceTerm.NewInstance();
214
    				if (status.equals("")) {
215
    					presenceAbsenceStatus = PresenceTerm.NATIVE();
216
    				} else {
217
    					presenceAbsenceStatus = PresenceTerm.getPresenceTermByAbbreviation(status);
218
    				}
219
    				// TODO: Handle absence case. 
220
    				// This case has not yet occurred in the excel input file, though.
221
					
222
    				/* Set to true if taxon needs to be saved if at least one new distribution exists */
223
    				boolean save = false;
224
    				
225
    				// TDWG areas
226
    				for (String distribution: distributionList) {
227

    
228
                        /* Set to true if this distribution is a new one*/
229
        				boolean ignore = false;
230
        				
231
    					if(!distribution.equals("")) {
232
    						NamedArea namedArea = TdwgArea.getAreaByTdwgAbbreviation(distribution);
233
        					TaxonDescription taxonDescription = myDescriptions.get(taxon);
234
        					if (namedArea != null) {    
235
    		    				// Check against existing distributions and ignore the ones that occur multiple times
236
            					Set<DescriptionElementBase> myDescriptionElements = taxonDescription.getElements();
237
    	    					for(DescriptionElementBase descriptionElement : myDescriptionElements) {
238
    	    						if (descriptionElement instanceof Distribution) {
239
    	    							if (namedArea == ((Distribution)descriptionElement).getArea()) {
240
    	    								ignore = true;
241
    	    								if (logger.isDebugEnabled()) { 
242
    	    									logger.debug("Distribution ignored: " + distribution); 
243
    	    								}
244
    	    		    					break;
245
     	    							}
246
    	    						}
247
    	    					}
248
    	    					// Create new distribution if not yet exist
249
    	    					if (ignore == false) {
250
    	    						save = true;
251
    	    						Distribution newDistribution = Distribution.NewInstance(namedArea, presenceAbsenceStatus);
252
    	    						myDescription.addElement(newDistribution);
253
    	    						if (logger.isDebugEnabled()) { 
254
    	    							logger.debug("Distribution created: " + newDistribution.toString());
255
    	    						}
256
    	    					}
257
    						}
258
    					}
259
    				}
260
    				if (save == true) {
261
    					getTaxonService().save(taxon);
262
    					if (logger.isDebugEnabled()) { logger.debug("Taxon saved"); }
263
    				}
264
    			}
265
    		} 
266
    	} catch (Exception e) {
267
    		logger.error("Error");
268
    		e.printStackTrace();
269
    	}
270
    }
271
    
272
    
273
	@Override
274
	protected boolean doCheck(ExcelImportState state) {
275
		boolean result = true;
276
		logger.warn("No check implemented for distribution data import");
277
		return result;
278
	}
279
	
280

    
281
	@Override
282
	protected boolean isIgnore(ExcelImportState state) {
283
		return false;
284
	}
285

    
286
}
(1-1/2)