Project

General

Profile

Download (20.7 KB) Statistics
| Branch: | Revision:
1
// $Id$
2
/**
3
* Copyright (C) 2009 EDIT
4
* European Distributed Institute of Taxonomy 
5
* http://www.e-taxonomy.eu
6
* 
7
* The contents of this file are subject to the Mozilla Public License Version 1.1
8
* See LICENSE.TXT at the top of this package for the full license terms.
9
*/
10
package eu.etaxonomy.cdm.io.pesi.out.old;
11

    
12
import java.sql.Connection;
13
import java.sql.PreparedStatement;
14
import java.sql.SQLException;
15
import java.util.Arrays;
16
import java.util.List;
17
import java.util.Map;
18
import java.util.Set;
19

    
20
import org.apache.log4j.Logger;
21
import org.joda.time.DateTime;
22
import org.springframework.stereotype.Component;
23
import org.springframework.transaction.TransactionStatus;
24

    
25
import eu.etaxonomy.cdm.io.common.DbExportStateBase;
26
import eu.etaxonomy.cdm.io.common.Source;
27
import eu.etaxonomy.cdm.io.common.mapping.UndefinedTransformerMethodException;
28
import eu.etaxonomy.cdm.io.common.mapping.out.IdMapper;
29
import eu.etaxonomy.cdm.io.common.mapping.out.MethodMapper;
30
import eu.etaxonomy.cdm.io.pesi.out.PesiExportBase;
31
import eu.etaxonomy.cdm.io.pesi.out.PesiExportConfigurator;
32
import eu.etaxonomy.cdm.io.pesi.out.PesiExportMapping;
33
import eu.etaxonomy.cdm.io.pesi.out.PesiExportState;
34
import eu.etaxonomy.cdm.io.pesi.out.PesiTransformer;
35
import eu.etaxonomy.cdm.model.common.CdmBase;
36
import eu.etaxonomy.cdm.model.common.Extension;
37
import eu.etaxonomy.cdm.model.common.ExtensionType;
38
import eu.etaxonomy.cdm.model.common.Language;
39
import eu.etaxonomy.cdm.model.common.LanguageString;
40
import eu.etaxonomy.cdm.model.description.CommonTaxonName;
41
import eu.etaxonomy.cdm.model.description.DescriptionBase;
42
import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
43
import eu.etaxonomy.cdm.model.description.Distribution;
44
import eu.etaxonomy.cdm.model.description.IndividualsAssociation;
45
import eu.etaxonomy.cdm.model.description.TaxonDescription;
46
import eu.etaxonomy.cdm.model.description.TaxonInteraction;
47
import eu.etaxonomy.cdm.model.description.TextData;
48
import eu.etaxonomy.cdm.model.location.NamedArea;
49
import eu.etaxonomy.cdm.model.name.TaxonNameBase;
50
import eu.etaxonomy.cdm.model.taxon.Taxon;
51
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
52

    
53
/**
54
 * The export class for {@link eu.etaxonomy.cdm.model.description.DescriptionElementBase DescriptionElements}.<p>
55
 * Inserts into DataWarehouse database table <code>Note</code>.<p>
56
 * It is divided into two phases:<ul>
57
 * <li>Phase 1:	Export of DescriptionElements as Notes.
58
 * <li>Phase 2:	Export of TaxonName extensions <code>taxComment</code>, <code>fauComment</code> and <code>fauExtraCodes</code> as Notes.</ul>
59
 * @author e.-m.lee
60
 * @date 23.02.2010
61
 *
62
 */
63
@Component
64
public class PesiNoteExport extends PesiExportBase {
65
	private static final Logger logger = Logger.getLogger(PesiNoteExport.class);
66
	private static final Class<? extends CdmBase> standardMethodParameter = DescriptionElementBase.class;
67

    
68
	private static int modCount = 1000;
69
	private static final String dbTableName = "Note";
70
	private static final String pluralString = "Notes";
71
	private static final String parentPluralString = "Taxa";
72

    
73
	public PesiNoteExport() {
74
		super();
75
	}
76

    
77
	/* (non-Javadoc)
78
	 * @see eu.etaxonomy.cdm.io.common.DbExportBase#getStandardMethodParameter()
79
	 */
80
	@Override
81
	public Class<? extends CdmBase> getStandardMethodParameter() {
82
		return standardMethodParameter;
83
	}
84

    
85
	/* (non-Javadoc)
86
	 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#doCheck(eu.etaxonomy.cdm.io.common.IoStateBase)
87
	 */
88
	@Override
89
	protected boolean doCheck(PesiExportState state) {
90
		boolean result = true;
91
		return result;
92
	}
93

    
94
	/* (non-Javadoc)
95
	 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#doInvoke(eu.etaxonomy.cdm.io.common.IoStateBase)
96
	 */
97
	@Override
98
	protected void doInvoke(PesiExportState state) {
99
		try {
100
			logger.info("*** Started Making " + pluralString + " ...");
101

    
102
			// Get the limit for objects to save within a single transaction.
103
			int limit = state.getConfig().getLimitSave();
104
			
105
			// Stores whether this invoke was successful or not.
106
			boolean success = true;
107
	
108
			// PESI: Clear the database table Note.
109
			doDelete(state);
110
		
111
			// Start transaction
112
			success &= doPhase01(state);
113

    
114
			
115
			logger.info("PHASE 2...");
116
			doPhase02(state, limit);
117

    
118

    
119
			logger.info("*** Finished Making " + pluralString + " ..." + getSuccessString(success));
120
			
121
			if (!success){
122
				state.setUnsuccessfull();
123
			}
124
			return;
125
		} catch (SQLException e) {
126
			e.printStackTrace();
127
			logger.error(e.getMessage());
128
			state.setUnsuccessfull();
129
		}
130
	}
131

    
132
	//PHASE 01: Description Elements
133
	private boolean doPhase01(PesiExportState state) throws SQLException {
134
		logger.info("PHASE 1...");
135
		int count = 0;
136
		int pastCount = 0;
137
		 boolean success = true;
138
		
139
		 // Calculate the pageNumber
140
		int pageNumber = 1;
141
		int pageSize = 1000;
142

    
143

    
144
		// Get specific mappings: (CDM) DescriptionElement -> (PESI) Note
145
		PesiExportMapping mapping = getMapping();
146

    
147
		// Initialize the db mapper
148
		mapping.initialize(state);
149

    
150
		
151
		List<DescriptionElementBase> list = null;
152
		
153
		TransactionStatus txStatus = startTransaction(true);
154
		logger.info("Started new transaction. Fetching some " + pluralString + " (max: " + pageSize + ") ...");
155
		List<String> propPath = Arrays.asList(new String[]{"inDescription.taxon"});
156
		while ((list = getDescriptionService().listDescriptionElements(null, null, null, pageSize, pageNumber, propPath)).size() > 0) {
157

    
158
			logger.info("Fetched " + list.size() + " " + pluralString + ". Exporting...");
159
			for (DescriptionElementBase descriptionElement : list) {
160
				if (getNoteCategoryFk(descriptionElement) != null) {
161
					doCount(count++, modCount, pluralString);
162
					success &= mapping.invoke(descriptionElement);
163
				}
164
			}
165

    
166
			// Commit transaction
167
			commitTransaction(txStatus);
168
			logger.debug("Committed transaction.");
169
			logger.info("Exported " + (count - pastCount) + " " + pluralString + ". Total: " + count);
170
			pastCount = count;
171

    
172
			// Start transaction
173
			txStatus = startTransaction(true);
174
			logger.info("Started new transaction. Fetching some " + pluralString + " (max: " + pageSize + ") ...");
175
			
176
			// Increment pageNumber
177
			pageNumber++;
178
		}
179
		if (list.size() == 0) {
180
			logger.info("No " + pluralString + " left to fetch.");
181
		}
182
		// Commit transaction
183
		commitTransaction(txStatus);
184
		logger.info("Committed transaction.");
185
		return success;
186
	}
187

    
188
	//PHASE 02: Taxa extensions
189
	private void doPhase02(PesiExportState state, int limit) {
190
		TransactionStatus txStatus;
191
		txStatus = startTransaction(true);
192
		ExtensionType taxCommentExtensionType = (ExtensionType)getTermService().find(PesiTransformer.taxCommentUuid);
193
		ExtensionType fauCommentExtensionType = (ExtensionType)getTermService().find(PesiTransformer.fauCommentUuid);
194
		ExtensionType fauExtraCodesExtensionType = (ExtensionType)getTermService().find(PesiTransformer.fauExtraCodesUuid);
195
		List<TaxonBase> taxonBaseList = null;
196
		
197
		int count = 0;
198
		int pastCount = 0;
199
		Connection connection = state.getConfig().getDestination().getConnection();
200
		logger.info("Started new transaction. Fetching some " + parentPluralString + " first (max: " + limit + ") ...");
201
		//logger.warn("TODO handle extensions on taxon level, not name level (");
202
		while ((taxonBaseList = getTaxonService().list(null, limit, count, null, null)).size() > 0) {
203

    
204
			logger.info("Fetched " + taxonBaseList.size() + " names. Exporting...");
205
			for (TaxonBase<?> taxon : taxonBaseList) {
206
				Set<Extension> extensions = taxon.getExtensions();
207
				for (Extension extension : extensions) {
208
					if (extension.getType().equals(taxCommentExtensionType)) {
209
						String taxComment = extension.getValue();
210
						invokeNotes(taxComment, 
211
								PesiTransformer.getNoteCategoryFk(PesiTransformer.taxCommentUuid), 
212
								PesiTransformer.getNoteCategoryCache(PesiTransformer.taxCommentUuid),
213
								null, null, getTaxonFk(taxon.getName(), state),connection);
214
					} else if (extension.getType().equals(fauCommentExtensionType)) {
215
						String fauComment = extension.getValue();
216
						invokeNotes(fauComment, 
217
								PesiTransformer.getNoteCategoryFk(PesiTransformer.fauCommentUuid), 
218
								PesiTransformer.getNoteCategoryCache(PesiTransformer.fauCommentUuid),
219
								null, null, getTaxonFk(taxon.getName(), state),connection);
220
					} else if (extension.getType().equals(fauExtraCodesExtensionType)) {
221
						String fauExtraCodes = extension.getValue();
222
						invokeNotes(fauExtraCodes, 
223
								PesiTransformer.getNoteCategoryFk(PesiTransformer.fauExtraCodesUuid), 
224
								PesiTransformer.getNoteCategoryCache(PesiTransformer.fauExtraCodesUuid),
225
								null, null, getTaxonFk(taxon.getName(), state),connection);
226
					}
227
				}
228
				
229
				doCount(count++, modCount, pluralString);
230
			}
231

    
232
			// Commit transaction
233
			commitTransaction(txStatus);
234
			logger.debug("Committed transaction.");
235
			logger.info("Exported " + (count - pastCount) + " names. Total: " + count);
236
			pastCount = count;
237

    
238
			// Start transaction
239
			txStatus = startTransaction(true);
240
			logger.info("Started new transaction. Fetching some taxa first (max: " + limit + ") ...");
241
		}
242
		if (taxonBaseList.size() == 0) {
243
			logger.info("No taxa left to fetch.");
244
		}
245
		// Commit transaction
246
		commitTransaction(txStatus);
247
		logger.debug("Committed transaction.");
248
	}
249

    
250
	/**
251
	 * @param taxComment
252
	 * @param noteCategoryFk
253
	 * @param noteCategoryCache
254
	 * @param object
255
	 * @param object2
256
	 */
257
	private void invokeNotes(String note, Integer noteCategoryFk,
258
			String noteCategoryCache, Integer languageFk, String languageCache, 
259
			Integer taxonFk, Connection connection) {
260
		String notesSql = "UPDATE Note SET Note_1 = ?, NoteCategoryFk = ?, NoteCategoryCache = ?, LanguageFk = ?, LanguageCache = ? WHERE TaxonFk = ?"; 
261
		try {
262
			PreparedStatement notesStmt = connection.prepareStatement(notesSql);
263
			
264
			if (note != null) {
265
				notesStmt.setString(1, note);
266
			} else {
267
				notesStmt.setObject(1, null);
268
			}
269
			
270
			if (noteCategoryFk != null) {
271
				notesStmt.setInt(2, noteCategoryFk);
272
			} else {
273
				notesStmt.setObject(2, null);
274
			}
275
			
276
			if (noteCategoryCache != null) {
277
				notesStmt.setString(3, noteCategoryCache);
278
			} else {
279
				notesStmt.setObject(3, null);
280
			}
281
			
282
			if (languageFk != null) {
283
				notesStmt.setInt(4, languageFk);
284
			} else {
285
				notesStmt.setObject(4, null);
286
			}
287
			
288
			if (languageCache != null) {
289
				notesStmt.setString(5, languageCache);
290
			} else {
291
				notesStmt.setObject(5, null);
292
			}
293
			
294
			if (taxonFk != null) {
295
				notesStmt.setInt(6, taxonFk);
296
			} else {
297
				notesStmt.setObject(6, null);
298
			}
299
			
300
			notesStmt.executeUpdate();
301
		} catch (SQLException e) {
302
			logger.error("Note could not be created: " + note);
303
			e.printStackTrace();
304
		}
305

    
306

    
307
	}
308

    
309
	/**
310
	 * Deletes all entries of database tables related to <code>Note</code>.
311
	 * @param state The PesiExportState
312
	 * @return Whether the delete operation was successful or not.
313
	 */
314
	protected boolean doDelete(PesiExportState state) {
315
		PesiExportConfigurator pesiConfig = (PesiExportConfigurator) state.getConfig();
316
		
317
		String sql;
318
		Source destination =  pesiConfig.getDestination();
319

    
320
		// Clear NoteSource
321
		sql = "DELETE FROM NoteSource";
322
		destination.setQuery(sql);
323
		destination.update(sql);
324

    
325
		// Clear Note
326
		sql = "DELETE FROM " + dbTableName;
327
		destination.setQuery(sql);
328
		destination.update(sql);
329
		return true;
330
	}
331

    
332
	/* (non-Javadoc)
333
	 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#isIgnore(eu.etaxonomy.cdm.io.common.IoStateBase)
334
	 */
335
	@Override
336
	protected boolean isIgnore(PesiExportState state) {
337
		return ! state.getConfig().isDoNotes();
338
	}
339

    
340
	/**
341
	 * Returns the <code>Note_1</code> attribute.
342
	 * @param descriptionElement The {@link DescriptionElementBase DescriptionElement}.
343
	 * @return The <code>Note_1</code> attribute.
344
	 * @see MethodMapper
345
	 */
346
	@SuppressWarnings("unused")
347
	private static String getNote_1(DescriptionElementBase descriptionElement) {
348
		String result = null;
349

    
350
		if (descriptionElement.isInstanceOf(TextData.class)) {
351
			TextData textData = CdmBase.deproxy(descriptionElement, TextData.class);
352
			result = textData.getText(Language.DEFAULT());
353
		}
354

    
355
		return result;
356
	}
357

    
358
	/**
359
	 * Returns the <code>Note_2</code> attribute.
360
	 * @param descriptionElement The {@link DescriptionElementBase DescriptionElement}.
361
	 * @return The <code>Note_2</code> attribute.
362
	 * @see MethodMapper
363
	 */
364
	@SuppressWarnings("unused")
365
	private static String getNote_2(DescriptionElementBase descriptionElement) {
366
		logger.warn("Not yet implemented");
367
		return null;
368
	}
369

    
370
	/**
371
	 * Returns the <code>NoteCategoryFk</code> attribute.
372
	 * @param descriptionElement The {@link DescriptionElementBase DescriptionElement}.
373
	 * @return The <code>NoteCategoryFk</code> attribute.
374
	 * @see MethodMapper
375
	 */
376
	private static Integer getNoteCategoryFk(DescriptionElementBase descriptionElement) {
377
		Integer result = null;
378
		result = PesiTransformer.feature2NoteCategoryFk(descriptionElement.getFeature());
379
		return result;
380
	}
381
	
382
	/**
383
	 * Returns the <code>NoteCategoryCache</code> attribute.
384
	 * @param descriptionElement The {@link DescriptionElementBase DescriptionElement}.
385
	 * @return The <code>NoteCategoryCache</code> attribute.
386
	 * @see MethodMapper
387
	 */
388
	@SuppressWarnings("unused")
389
	private static String getNoteCategoryCache(DescriptionElementBase descriptionElement, PesiExportState state) {
390
		return state.getTransformer().getCacheByFeature(descriptionElement.getFeature());
391
	}
392

    
393
	/**
394
	 * Returns the <code>LanguageFk</code> attribute.
395
	 * @param descriptionElement The {@link DescriptionElementBase DescriptionElement}.
396
	 * @return The <code>LanguageFk</code> attribute.
397
	 * @see MethodMapper
398
	 */
399
	@SuppressWarnings("unused")
400
	private static Integer getLanguageFk(DescriptionElementBase descriptionElement) {
401
		Language language = getLanguage(descriptionElement);
402

    
403
		return PesiTransformer.language2LanguageId(language);
404
	}
405

    
406
	/**
407
	 * Returns the <code>LanguageCache</code> attribute.
408
	 * @param descriptionElement The {@link DescriptionElementBase DescriptionElement}.
409
	 * @return The <code>LanguageCache</code> attribute.
410
	 * @throws UndefinedTransformerMethodException 
411
	 * @see MethodMapper
412
	 */
413
	@SuppressWarnings("unused")
414
	private static String getLanguageCache(DescriptionElementBase descriptionElement, PesiExportState state) throws UndefinedTransformerMethodException {
415
		Language language = getLanguage(descriptionElement);
416
		return state.getTransformer().getCacheByLanguage(language);
417
	}
418

    
419
	private static Language getLanguage(DescriptionElementBase descriptionElement) {
420
		Language language = null;
421

    
422
		Map<Language, LanguageString> multilanguageText = null;
423
		if (descriptionElement.isInstanceOf(CommonTaxonName.class)) {
424
			CommonTaxonName commonTaxonName = CdmBase.deproxy(descriptionElement, CommonTaxonName.class);
425
			language = commonTaxonName.getLanguage();
426
		} else if (descriptionElement.isInstanceOf(TextData.class)) {
427
			TextData textData = CdmBase.deproxy(descriptionElement, TextData.class);
428
			multilanguageText = textData.getMultilanguageText();
429
		} else if (descriptionElement.isInstanceOf(IndividualsAssociation.class)) {
430
			IndividualsAssociation individualsAssociation = CdmBase.deproxy(descriptionElement, IndividualsAssociation.class);
431
			multilanguageText = individualsAssociation.getDescription();
432
		} else if (descriptionElement.isInstanceOf(TaxonInteraction.class)) {
433
			TaxonInteraction taxonInteraction = CdmBase.deproxy(descriptionElement, TaxonInteraction.class);
434
			multilanguageText = taxonInteraction.getDescriptions();
435
		} else {
436
			logger.debug("Given descriptionElement does not support languages. Hence LanguageCache could not be determined: " + descriptionElement.getUuid());
437
		}
438
		
439
		if (multilanguageText != null) {
440
			Set<Language> languages = multilanguageText.keySet();
441

    
442
			// TODO: Think of something more sophisticated than this
443
			if (languages.size() > 0) {
444
				language = languages.iterator().next();
445
			}
446
			if (languages.size() > 1){
447
				logger.warn("There is more than 1 language for a given description (" + descriptionElement.getClass().getSimpleName() + "):" + descriptionElement.getUuid());
448
			}
449
		}
450
		return language;
451
	}
452

    
453
	/**
454
	 * Returns the <code>Region</code> attribute.
455
	 * @param descriptionElement The {@link DescriptionElementBase DescriptionElement}.
456
	 * @return The <code>Region</code> attribute.
457
	 * @see MethodMapper
458
	 */
459
	@SuppressWarnings("unused")
460
	private static String getRegion(DescriptionElementBase descriptionElement) {
461
		String result = null;
462
		DescriptionBase<?> inDescription = descriptionElement.getInDescription();
463
		
464
		try {
465
			// Area information are associated to TaxonDescriptions and Distributions.
466
			if (descriptionElement.isInstanceOf(Distribution.class)) {
467
				Distribution distribution = CdmBase.deproxy(descriptionElement, Distribution.class);
468
				//TODO not working any more after transformer refactoring
469
				result = new PesiTransformer(null).getCacheByNamedArea(distribution.getArea());
470
			} else if (inDescription != null && inDescription.isInstanceOf(TaxonDescription.class)) {
471
				TaxonDescription taxonDescription = CdmBase.deproxy(inDescription, TaxonDescription.class);
472
				Set<NamedArea> namedAreas = taxonDescription.getGeoScopes();
473
				if (namedAreas.size() == 1) {
474
					result = new PesiTransformer(null).getCacheByNamedArea(namedAreas.iterator().next());
475
				} else if (namedAreas.size() > 1) {
476
					logger.warn("This TaxonDescription contains more than one NamedArea: " + taxonDescription.getTitleCache());
477
				}
478
			}
479
		} catch (ClassCastException e) {
480
			// TODO Auto-generated catch block
481
			e.printStackTrace();
482
		} catch (UndefinedTransformerMethodException e) {
483
			// TODO Auto-generated catch block
484
			e.printStackTrace();
485
		}
486
		return result;
487
	}
488

    
489
	/**
490
	 * Returns the <code>TaxonFk</code> attribute.
491
	 * @param descriptionElement The {@link DescriptionElementBase DescriptionElement}.
492
	 * @param state The {@link PesiExportState PesiExportState}.
493
	 * @return The <code>TaxonFk</code> attribute.
494
	 * @see MethodMapper
495
	 */
496
	@SuppressWarnings("unused")
497
	private static Integer getTaxonFk(DescriptionElementBase descriptionElement, DbExportStateBase<?, PesiTransformer> state) {
498
		Integer result = null;
499
		DescriptionBase<?> inDescription = descriptionElement.getInDescription();
500
		if (inDescription != null && inDescription.isInstanceOf(TaxonDescription.class)) {
501
			TaxonDescription taxonDescription = CdmBase.deproxy(inDescription, TaxonDescription.class);
502
			Taxon taxon = taxonDescription.getTaxon();
503
			result = state.getDbId(taxon.getName());
504
		}
505
		return result;
506
	}
507
	
508
	/**
509
	 * Returns the TaxonFk for a given TaxonName.
510
	 * @param taxonName The {@link TaxonNameBase TaxonName}.
511
	 * @param state The {@link DbExportStateBase DbExportState}.
512
	 * @return
513
	 */
514
	private static Integer getTaxonFk(TaxonNameBase<?,?> taxonName, DbExportStateBase<?, PesiTransformer> state) {
515
		return state.getDbId(taxonName);
516
	}
517
	
518
	/**
519
	 * Returns the <code>LastAction</code> attribute.
520
	 * @param descriptionElement The {@link DescriptionElementBase DescriptionElement}.
521
	 * @return The <code>LastAction</code> attribute.
522
	 * @see MethodMapper
523
	 */
524
	@SuppressWarnings("unused")
525
	private static String getLastAction(DescriptionElementBase descriptionElement) {
526
		// TODO
527
		return null;
528
	}
529

    
530
	/**
531
	 * Returns the <code>LastActionDate</code> attribute.
532
	 * @param descriptionElement The {@link DescriptionElementBase DescriptionElement}.
533
	 * @return The <code>LastActionDate</code> attribute.
534
	 * @see MethodMapper
535
	 */
536
	@SuppressWarnings("unused")
537
	private static DateTime getLastActionDate(DescriptionElementBase descriptionElement) {
538
		DateTime result = null;
539
		return result;
540
	}
541

    
542
	/**
543
	 * Returns the CDM to PESI specific export mappings.
544
	 * @return The {@link PesiExportMapping PesiExportMapping}.
545
	 */
546
	private PesiExportMapping getMapping() {
547
		PesiExportMapping mapping = new PesiExportMapping(dbTableName);
548
		
549
		mapping.addMapper(IdMapper.NewInstance("NoteId"));
550
		mapping.addMapper(MethodMapper.NewInstance("Note_1", this));
551
		mapping.addMapper(MethodMapper.NewInstance("Note_2", this));
552
		mapping.addMapper(MethodMapper.NewInstance("NoteCategoryFk", this));
553
		mapping.addMapper(MethodMapper.NewInstance("NoteCategoryCache", this));
554
		mapping.addMapper(MethodMapper.NewInstance("LanguageFk", this));
555
		mapping.addMapper(MethodMapper.NewInstance("LanguageCache", this));
556
		mapping.addMapper(MethodMapper.NewInstance("Region", this));
557
		mapping.addMapper(MethodMapper.NewInstance("TaxonFk", this.getClass(), "getTaxonFk", standardMethodParameter, DbExportStateBase.class));
558
		mapping.addMapper(MethodMapper.NewInstance("LastAction", this));
559
		mapping.addMapper(MethodMapper.NewInstance("LastActionDate", this));
560

    
561
		return mapping;
562
	}
563

    
564
}
(3-3/6)