Project

General

Profile

Download (10.3 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 eu.etaxonomy.cdm.common.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.CdmImportBase;
28
import eu.etaxonomy.cdm.io.common.TdwgAreaProvider;
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.PresenceAbsenceTerm;
35
import eu.etaxonomy.cdm.model.description.TaxonDescription;
36
import eu.etaxonomy.cdm.model.location.NamedArea;
37
import eu.etaxonomy.cdm.model.name.TaxonName;
38
import eu.etaxonomy.cdm.model.taxon.Taxon;
39
import eu.etaxonomy.cdm.persistence.query.MatchMode;
40

    
41
/**
42
 * @author a.babadshanjan
43
 * @since 10.11.2008
44
 */
45
@Component
46
public class DistributionImport
47
        extends CdmImportBase<ExcelImportConfiguratorBase, ExcelImportState<ExcelImportConfiguratorBase, ExcelRowBase>> {
48

    
49
    private static final long serialVersionUID = 7765309119416657235L;
50

    
51
    private static final Logger logger = Logger.getLogger(DistributionImport.class);
52

    
53
    /* used */
54
    private static final String EDIT_NAME_COLUMN = "EDIT";
55
    private static final String TDWG_DISTRIBUTION_COLUMN = "TDWG";
56
    private static final String STATUS_COLUMN = "Status";
57
    /* not used */
58
//    private static final String LITERATURE_NUMBER_COLUMN = "Lit.";
59
//    private static final String LITERATURE_COLUMN = "Literature";
60
//    private static final String VERNACULAR_NAME_COLUMN = "Vernacular";
61
//    private static final String HABITAT_COLUMN = "Habitat";
62
//    private static final String CONTROL_COLUMN = "Control";
63
//    private static final String TRANSLATED_COLUMN = "Translated";
64
//    private static final String ISO_DISTRIBUTION_COLUMN = "ISO";
65
//    private static final String NOTES_COLUMN = "Notes";
66
//    private static final String PAGE_NUMBER_COLUMN = "Page";
67
//    private static final String INFO_COLUMN = "Info";
68

    
69

    
70
	// Stores already processed descriptions
71
	Map<Taxon, TaxonDescription> myDescriptions = new HashMap<Taxon, TaxonDescription>();
72

    
73
	@Override
74
	protected void doInvoke(ExcelImportState<ExcelImportConfiguratorBase, ExcelRowBase> state) {
75

    
76
		if (logger.isDebugEnabled()) { logger.debug("Importing distribution data"); }
77

    
78
		// read and save all rows of the excel worksheet
79
		List<Map<String, String>> recordList;
80
		URI source = state.getConfig().getSource();
81
		try{
82
    		recordList = ExcelUtils.parseXLS(source);
83
		} catch (FileNotFoundException e) {
84
			String message = "File not found: " + source;
85
			warnProgress(state, message, e);
86
			logger.error(message);
87
			state.setUnsuccessfull();
88
			return;
89
		}
90
    	if (recordList != null) {
91
    		Map<String,String> record = null;
92
    		TransactionStatus txStatus = startTransaction();
93

    
94
    		for (int i = 0; i < recordList.size(); i++) {
95
    			record = recordList.get(i);
96
    			analyzeRecord(record);
97
    		}
98
    		commitTransaction(txStatus);
99
    	}
100

    
101
		try {
102
			if (logger.isDebugEnabled()) { logger.debug("End distribution data import"); }
103

    
104
		} catch (Exception e) {
105
    		logger.error("Error closing the application context");
106
    		e.printStackTrace();
107
		}
108

    
109
    	return;
110
	}
111

    
112

    
113
	/**
114
	 *  Reads the data of one Excel sheet row
115
	 */
116
    private void analyzeRecord(Map<String,String> record) {
117
    	/*
118
    	 * Relevant columns:
119
    	 * Name (EDIT)
120
    	 * Distribution TDWG
121
    	 * Status (only entries if not native)
122
    	 * Literature number
123
    	 * Literature
124
    	*/
125

    
126
        String editName = "";
127
        List<String> distributionList = new ArrayList<String>();
128
        String status = "";
129
        String literatureNumber = "";
130
        String literature = "";
131

    
132
    	Set<String> keys = record.keySet();
133

    
134
    	for (String key: keys) {
135

    
136
    		String value = record.get(key);
137
    		if (!value.equals("")) {
138
    			if (logger.isDebugEnabled()) { logger.debug(key + ": '" + value + "'"); }
139
    		}
140

    
141
    		if (key.contains(EDIT_NAME_COLUMN)) {
142
    			editName = (String) CdmUtils.removeDuplicateWhitespace(value.trim());
143

    
144
			} else if(key.contains(TDWG_DISTRIBUTION_COLUMN)) {
145
				distributionList =  CdmUtils.buildList(value);
146

    
147
			} else if(key.contains(STATUS_COLUMN)) {
148
				status = (String) CdmUtils.removeDuplicateWhitespace(value.trim());
149

    
150
//			} else if(key.contains(LITERATURE_NUMBER_COLUMN)) {
151
//				literatureNumber = (String) CdmUtils.removeDuplicateWhitespace(value.trim());
152
//
153
//			} else if(key.contains(LITERATURE_COLUMN)) {
154
//				literature = (String) CdmUtils.removeDuplicateWhitespace(value.trim());
155
//
156
			} else {
157
				//logger.warn("Column " + key + " ignored");
158
			}
159
    	}
160

    
161
    	// Store the data of this record in the DB
162
    	if (!editName.equals("")) {
163
    		saveRecord(editName, distributionList, status, literatureNumber, literature);
164
    	}
165
    }
166

    
167

    
168
	/**
169
	 *  Stores the data of one Excel sheet row in the database
170
	 */
171
    private void saveRecord(String taxonName, List<String> distributionList,
172
    		String status, String literatureNumber, String literature) {
173

    
174
    	IdentifiableServiceConfiguratorImpl<TaxonName> config = IdentifiableServiceConfiguratorFactory.getConfigurator(TaxonName.class);
175
    	config.setTitleSearchString(taxonName);
176
    	config.setMatchMode(MatchMode.BEGINNING);
177

    
178
		try {
179
    		// get the matching names from the DB
180
    		//List<TaxonName> taxonNames = getNameService().findByTitle(config);
181
    		List<TaxonName> taxonNames = getNameService().findByName(null, taxonName, null, null, null, null,null,null).getRecords();
182
    		if (taxonNames.isEmpty()) {
183
    			logger.error("Taxon name '" + taxonName + "' not found in DB");
184
    		} else {
185
    			if (logger.isDebugEnabled()) { logger.debug("Taxon found"); }
186
    		}
187

    
188
    		// get the taxa for the matching names
189
    		for(TaxonName dbTaxonName: taxonNames) {
190

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

    
198
    			for(Taxon taxon: taxa) {
199

    
200
    				TaxonDescription myDescription = null;
201

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

    
213
    				// Status
214
    				PresenceAbsenceTerm presenceAbsenceStatus = PresenceAbsenceTerm.NewInstance();
215
    				if (status.equals("")) {
216
    					presenceAbsenceStatus = PresenceAbsenceTerm.NATIVE();
217
    				} else {
218
    					presenceAbsenceStatus = PresenceAbsenceTerm.getPresenceAbsenceTermByAbbreviation(status);
219
    				}
220
    				// TODO: Handle absence case.
221
    				// This case has not yet occurred in the excel input file, though.
222

    
223
    				/* Set to true if taxon needs to be saved if at least one new distribution exists */
224
    				boolean save = false;
225

    
226
    				// TDWG areas
227
    				for (String distribution: distributionList) {
228

    
229
                        /* Set to true if this distribution is a new one*/
230
        				boolean ignore = false;
231

    
232
    					if(!distribution.equals("")) {
233
    						NamedArea namedArea = TdwgAreaProvider.getAreaByTdwgAbbreviation(distribution);
234
        					TaxonDescription taxonDescription = myDescriptions.get(taxon);
235
        					if (namedArea != null) {
236
    		    				// Check against existing distributions and ignore the ones that occur multiple times
237
            					Set<DescriptionElementBase> myDescriptionElements = taxonDescription.getElements();
238
    	    					for(DescriptionElementBase descriptionElement : myDescriptionElements) {
239
    	    						if (descriptionElement instanceof Distribution) {
240
    	    							if (namedArea == ((Distribution)descriptionElement).getArea()) {
241
    	    								ignore = true;
242
    	    								if (logger.isDebugEnabled()) {
243
    	    									logger.debug("Distribution ignored: " + distribution);
244
    	    								}
245
    	    		    					break;
246
     	    							}
247
    	    						}
248
    	    					}
249
    	    					// Create new distribution if not yet exist
250
    	    					if (ignore == false) {
251
    	    						save = true;
252
    	    						Distribution newDistribution = Distribution.NewInstance(namedArea, presenceAbsenceStatus);
253
    	    						myDescription.addElement(newDistribution);
254
    	    						if (logger.isDebugEnabled()) {
255
    	    							logger.debug("Distribution created: " + newDistribution.toString());
256
    	    						}
257
    	    					}
258
    						}
259
    					}
260
    				}
261
    				if (save == true) {
262
    					getTaxonService().save(taxon);
263
    					if (logger.isDebugEnabled()) { logger.debug("Taxon saved"); }
264
    				}
265
    			}
266
    		}
267
    	} catch (Exception e) {
268
    		logger.error("Error");
269
    		e.printStackTrace();
270
    	}
271
    }
272

    
273

    
274
	@Override
275
	protected boolean doCheck(ExcelImportState<ExcelImportConfiguratorBase, ExcelRowBase> state) {
276
		boolean result = true;
277
		logger.warn("No check implemented for distribution data import");
278
		return result;
279
	}
280

    
281

    
282
	@Override
283
	protected boolean isIgnore(ExcelImportState<ExcelImportConfiguratorBase, ExcelRowBase> state) {
284
		return false;
285
	}
286

    
287
}
(1-1/2)