Project

General

Profile

Download (13.2 KB) Statistics
| Branch: | Revision:
1
/**
2
* Copyright (C) 2009 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.pesi.out;
10

    
11
import java.sql.SQLException;
12
import java.util.Arrays;
13
import java.util.List;
14
import java.util.Set;
15
import java.util.UUID;
16

    
17
import org.apache.log4j.Logger;
18
import org.springframework.stereotype.Component;
19
import org.springframework.transaction.TransactionStatus;
20

    
21
import eu.etaxonomy.cdm.common.CdmUtils;
22
import eu.etaxonomy.cdm.io.common.mapping.out.DbExportIgnoreMapper;
23
import eu.etaxonomy.cdm.io.common.mapping.out.DbFixedIntegerMapper;
24
import eu.etaxonomy.cdm.io.common.mapping.out.DbFixedStringMapper;
25
import eu.etaxonomy.cdm.io.common.mapping.out.IdIncMapper;
26
import eu.etaxonomy.cdm.io.common.mapping.out.MethodMapper;
27
import eu.etaxonomy.cdm.io.pesi.erms.ErmsLinkImport;
28
import eu.etaxonomy.cdm.io.pesi.erms.ErmsTransformer;
29
import eu.etaxonomy.cdm.model.common.CdmBase;
30
import eu.etaxonomy.cdm.model.common.Extension;
31
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
32
import eu.etaxonomy.cdm.profiler.ProfilerController;
33
/**
34
 * The export class for PESI ecology notes (marine, brackish, fresh, terrestrial) coming from ERMS tu table.<p>
35
 * @author a.mueller
36
 * @since 28.09.2019
37
 */
38
@Component
39
public class PesiEcologyAndLinkExport extends PesiExportBase {
40

    
41
    private static final long serialVersionUID = -2567615286288369111L;
42
    private static final Logger logger = Logger.getLogger(PesiEcologyAndLinkExport.class);
43

    
44
	private static final Class<? extends CdmBase> standardMethodParameter = TaxonBase.class;
45

    
46
	private static int modCount = 1000;
47
	private static final String dbTableName = "Note";
48
	private static final String pluralString = "ecology or link notes";
49
	private static final String parentPluralString = "Taxa";
50

    
51
	public PesiEcologyAndLinkExport() {
52
		super();
53
	}
54

    
55
	int countNotes = 0;
56
	int countUrls = 0;
57
	String currentValue;
58

    
59
	@Override
60
	public Class<? extends CdmBase> getStandardMethodParameter() {
61
		return standardMethodParameter;
62
	}
63

    
64
	@Override
65
	protected void doInvoke(PesiExportState state) {
66
		try {
67
			logger.info("*** Started making " + pluralString + " ...");
68

    
69
			// Stores whether this invoke was successful or not.
70
			boolean success = true;
71

    
72
			// Get specific mappings: (CDM) TaxonBase.marker -> (PESI) Note (ecology)
73
			PesiExportMapping mapping = getEcologyMapping();
74
			mapping.initialize(state);
75

    
76
			PesiExportMapping urlMapping = getUrlMapping();
77
			urlMapping.initialize(state);
78

    
79
			//All
80
			success &= doPhase01(state, mapping, urlMapping);
81

    
82
			logger.info("*** Finished Making " + pluralString + " ..." + getSuccessString(success));
83

    
84
			if (!success){
85
				state.getResult().addError("An unknown problem occurred");
86
			}
87
			return;
88
		} catch (SQLException e) {
89
			e.printStackTrace();
90
			logger.error(e.getMessage());
91
			state.getResult().addException(e, e.getMessage());
92
		}
93
	}
94

    
95
	//PHASE 01: All
96
	private boolean doPhase01(PesiExportState state, PesiExportMapping mapping, PesiExportMapping urlMapping) throws SQLException {
97

    
98
//	    logger.info("PHASE 1 (ecology...");
99
		int count = 0;
100
		int pastCount = 0;
101
		boolean success = true;
102
		int limit = state.getConfig().getLimitSave();
103

    
104
		List<TaxonBase> taxonList = null;
105

    
106
		TransactionStatus txStatus = startTransaction(true);
107

    
108
		if (logger.isDebugEnabled()){
109
		    logger.info("Started new transaction. Fetching some " + parentPluralString + " (max: " + limit + ") ...");
110
		    logger.debug("Start snapshot, before starting loop");
111
		    ProfilerController.memorySnapshot();
112
		}
113

    
114
		List<String> propPath = Arrays.asList(new String[]{"markers.*","extensions.*"});
115
		int partitionCount = 0;
116
		while ((taxonList = getNextTaxonPartition(TaxonBase.class, limit, partitionCount++, propPath )) != null   ) {
117

    
118
			if (logger.isDebugEnabled()) {
119
                logger.info("Fetched " + taxonList.size() + " " + parentPluralString + ". Exporting...");
120
            }
121

    
122
			for (TaxonBase<?> taxon : taxonList) {
123
				doCount(count++, modCount, pluralString);
124
				state.setCurrentTaxon(taxon);
125
				if (!taxon.getMarkers().isEmpty()){
126
					success &= handleSingleEcologyTaxon(taxon, mapping);
127
				}
128
				if (!taxon.getExtensions().isEmpty()){
129
                    success &= handleSingleLinkTaxon(taxon, urlMapping);
130
                }
131
			}
132
			taxonList = null;
133
			state.setCurrentTaxon(null);
134

    
135
			// Commit transaction
136
			commitTransaction(txStatus);
137
			logger.info("Exported " + (count - pastCount) + " " + parentPluralString + ". Total taxa: " + count + ". Ecology notes: " + countNotes + ". Link notes: " + countUrls);
138
			pastCount = count;
139
			if (logger.isDebugEnabled()) {
140
                ProfilerController.memorySnapshot();
141
            }
142
			// Start transaction
143
			txStatus = startTransaction(true);
144
			if(logger.isDebugEnabled()) {
145
                logger.info("Started new transaction. Fetching some " + pluralString + " (max: " + limit + ") for description import ...");
146
            }
147
		}
148

    
149

    
150
		// Commit transaction
151
		commitTransaction(txStatus);
152
		logger.debug("Committed transaction.");
153
		return success;
154
	}
155

    
156
	private boolean handleSingleEcologyTaxon(TaxonBase<?> taxon, PesiExportMapping mapping) {
157

    
158
	    boolean success = true;
159
	    String ecologyStr = getEcologyString(taxon);
160
	    if (isNotBlank(ecologyStr)){
161
	        success &= mapping.invoke(taxon);
162
	        countNotes++;
163
	    }
164
		return success;
165
	}
166

    
167
    private static String getEcologyString(TaxonBase<?> taxon) {
168
        String ecologyStr = null;
169
	    ecologyStr = CdmUtils.concat(", ", ecologyStr, createEcologyStr(taxon, "marine", ErmsTransformer.uuidMarkerMarine));
170
	    ecologyStr = CdmUtils.concat(", ", ecologyStr, createEcologyStr(taxon, "brackish", ErmsTransformer.uuidMarkerBrackish));
171
	    ecologyStr = CdmUtils.concat(", ", ecologyStr, createEcologyStr(taxon, "fresh", ErmsTransformer.uuidMarkerFreshwater));
172
	    ecologyStr = CdmUtils.concat(", ", ecologyStr, createEcologyStr(taxon, "terrestrial", ErmsTransformer.uuidMarkerTerrestrial));
173
        return ecologyStr;
174
    }
175

    
176
    private static String createEcologyStr(TaxonBase<?> taxon, String strEcology, UUID markerUuid) {
177
        Boolean value = taxon.markerValue(markerUuid);
178
        if (value == null){
179
            return null;
180
        }else if (value == true){
181
            return strEcology;
182
        }else{
183
            return "not " + strEcology;
184
        }
185
    }
186

    
187
    private boolean handleSingleLinkTaxon(TaxonBase<?> taxon, PesiExportMapping mapping) {
188

    
189
        boolean success = true;
190
        Set<Extension> urlExtensions = taxon.getFilteredExtensions(ErmsTransformer.uuidExtErmsLink);
191
        for (Extension extension : urlExtensions){
192
            mapping.invoke(extension);
193
            countUrls++;
194
        }
195
        return success;
196
    }
197

    
198
	protected boolean doDelete(PesiExportState state) {
199
	    //Note table is already filled by Description import
200
	    //=> we do not empty any table here
201
		return true;
202
	}
203

    
204
    @SuppressWarnings("unused")  //used by mapper
205
    private static Integer getTaxonFk(TaxonBase<?> taxonBase, PesiExportState state) {
206
        return state.getDbId(taxonBase);
207
    }
208

    
209
    @SuppressWarnings("unused")  //used by mapper
210
    private static Integer getCurrentTaxonFk(Extension extension, PesiExportState state) {
211
        return state.getDbId(state.getCurrentTaxon());
212
    }
213

    
214
    @SuppressWarnings("unused")  //used by mapper
215
    private static String getNote_1(TaxonBase<?> taxon) {
216
        return getEcologyString(taxon);
217
    }
218

    
219
    @SuppressWarnings("unused")  //used by mapper
220
    private static String getUrlNote_1(Extension extension) {
221
        String value = extension.getValue();
222
        if (value == null){
223
            return null;
224
        }else{
225
            //TODO use regex grouping
226
            String result = value.split(ErmsLinkImport.TOKEN_LINKTEXT)[0];
227
            result = result.replace(ErmsLinkImport.TOKEN_URL, "").trim();
228
            return result;
229
        }
230
    }
231

    
232
//  @SuppressWarnings("unused")  //used by mapper
233
    private static String getUrlNote_2(Extension extension) {
234
        String value = extension.getValue();
235
        if (value == null){
236
            return null;
237
        }else{
238
            //TODO use regex grouping
239
            String[] split = value.split(ErmsLinkImport.TOKEN_LINKTEXT);
240
            if (split.length > 1){
241
                String result = split[1];
242
                result = result.trim();
243
                return CdmUtils.Ne(result);
244
            }else{
245
                return null;
246
            }
247
        }
248
    }
249

    
250
//  @SuppressWarnings("unused")  //used by mapper
251
    private static Integer getNoteCategoryFk(Extension extension) {
252
        String linktext = getUrlNote_2(extension);
253
        int catFk = categoryByLinkText(linktext);
254
        return catFk;
255
    }
256

    
257
    private static int categoryByLinkText(String linktext) {
258
        if (linktext == null){
259
            return PesiTransformer.NoteCategory_undefined_link;
260
        }else if (linktext.matches("(?i)(to fishbase|marine life inf).*")){
261
            return PesiTransformer.NoteCategory_Link_to_general_information;
262
        }else if (linktext.matches("(?i).*(clemam|nemys|algaebase|fishbase).*")){
263
            return PesiTransformer.NoteCategory_Link_to_taxonomy;
264
        }else{
265
            return PesiTransformer.NoteCategory_undefined_link;
266
        }
267
    }
268

    
269
    @SuppressWarnings("unused")  //used by mapper
270
    private static String getNoteCategoryCache(Extension extension) {
271
        int catFk = getNoteCategoryFk(extension);
272
        String result = categoryByLinkText(catFk);
273
        return result;
274
    }
275

    
276
    private static String categoryByLinkText(int catFk) {
277
        if(catFk == 22){
278
            return "";
279
        }else if (catFk == 23){
280
            return "";
281
        }else if (catFk == 24){
282
            return "";
283
        }else{
284
            logger.warn("Link category fk not yet supported: " + catFk);
285
            return null;
286
        }
287
    }
288

    
289
//******************************* MAPPINGS ********************************************
290

    
291
    private IdIncMapper idIncMapperEcology = IdIncMapper.NewComputedInstance("NoteId");
292
    private PesiExportMapping getEcologyMapping() {
293
        PesiExportMapping mapping = new PesiExportMapping(dbTableName);
294

    
295
        mapping.addMapper(idIncMapperEcology);
296
        mapping.addMapper(MethodMapper.NewInstance("Note_1", this, standardMethodParameter));
297

    
298
        mapping.addMapper(DbFixedIntegerMapper.NewInstance(PesiTransformer.NoteCategory_ecology, "NoteCategoryFk"));
299
        mapping.addMapper(DbFixedStringMapper.NewInstance("ecology", "NoteCategoryCache"));
300
        mapping.addMapper(DbFixedIntegerMapper.NewInstance(12, "LanguageFk"));
301
        mapping.addMapper(DbFixedStringMapper.NewInstance("English", "LanguageCache"));
302

    
303
        mapping.addMapper(MethodMapper.NewInstance("TaxonFk", this, standardMethodParameter, PesiExportState.class));
304

    
305
        mapping.addMapper(DbExportIgnoreMapper.NewInstance("Note_2", "not used for ecology fact"));
306
        mapping.addMapper(DbExportIgnoreMapper.NewInstance("Region", "not used for ecology fact"));
307
        mapping.addMapper(DbExportIgnoreMapper.NewInstance("SpeciesExpertGUID", "not used for ecology fact"));
308
        mapping.addMapper(DbExportIgnoreMapper.NewInstance("SpeciesExpertName", "not used for ecology fact"));
309
        mapping.addMapper(DbExportIgnoreMapper.NewInstance("LastAction", "not used for ecology fact"));
310
        mapping.addMapper(DbExportIgnoreMapper.NewInstance("LastActionDate", "not used for ecology fact"));
311

    
312
        return mapping;
313
    }
314
    private PesiExportMapping getUrlMapping() {
315
        PesiExportMapping mapping = new PesiExportMapping(dbTableName);
316
        IdIncMapper idIncMapper = IdIncMapper.NewDependendInstance("NoteId", idIncMapperEcology);
317
        mapping.addMapper(idIncMapper);
318
        mapping.addMapper(MethodMapper.NewInstance("Note_1", this.getClass(), "getUrlNote_1", Extension.class));
319
        mapping.addMapper(MethodMapper.NewInstance("Note_2", this.getClass(), "getUrlNote_2", Extension.class));
320
        mapping.addMapper(MethodMapper.NewInstance("NoteCategoryFk", this.getClass(), Extension.class));
321
        mapping.addMapper(MethodMapper.NewInstance("NoteCategoryCache", this.getClass(), Extension.class));
322
        mapping.addMapper(MethodMapper.NewInstance("TaxonFk", this.getClass(), "getCurrentTaxonFk", Extension.class, PesiExportState.class));
323

    
324
        mapping.addMapper(DbExportIgnoreMapper.NewInstance("LanguageFk", "not used for link fact"));
325
        mapping.addMapper(DbExportIgnoreMapper.NewInstance("LanguageCache", "not used for link fact"));
326
        mapping.addMapper(DbExportIgnoreMapper.NewInstance("Region", "not used for link fact"));
327
        mapping.addMapper(DbExportIgnoreMapper.NewInstance("SpeciesExpertGUID", "not used for link fact"));
328
        mapping.addMapper(DbExportIgnoreMapper.NewInstance("SpeciesExpertName", "not used for link fact"));
329
        mapping.addMapper(DbExportIgnoreMapper.NewInstance("LastAction", "not used for link fact"));
330
        mapping.addMapper(DbExportIgnoreMapper.NewInstance("LastActionDate", "not used for link fact"));
331

    
332
        return mapping;
333
    }
334

    
335
    @Override
336
    protected boolean doCheck(PesiExportState state) {
337
        boolean result = true;
338
        return result;
339
    }
340

    
341
    @Override
342
    protected boolean isIgnore(PesiExportState state) {
343
        return ! state.getConfig().isDoEcologyAndLink();
344
    }
345
}
(5-5/14)