1 |
d3530340
|
Andreas Müller
|
/**
|
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.HashSet;
|
14 |
|
|
import java.util.List;
|
15 |
|
|
import java.util.Set;
|
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.io.common.DbExportStateBase;
|
22 |
|
|
import eu.etaxonomy.cdm.io.common.Source;
|
23 |
|
|
import eu.etaxonomy.cdm.io.common.mapping.out.DbObjectMapper;
|
24 |
|
|
import eu.etaxonomy.cdm.io.common.mapping.out.DbStringMapper;
|
25 |
|
|
import eu.etaxonomy.cdm.io.common.mapping.out.MethodMapper;
|
26 |
|
|
import eu.etaxonomy.cdm.model.common.CdmBase;
|
27 |
|
|
import eu.etaxonomy.cdm.model.common.IdentifiableSource;
|
28 |
|
|
import eu.etaxonomy.cdm.model.reference.OriginalSourceType;
|
29 |
|
|
import eu.etaxonomy.cdm.model.reference.Reference;
|
30 |
|
|
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
|
31 |
|
|
import eu.etaxonomy.cdm.profiler.ProfilerController;
|
32 |
|
|
/**
|
33 |
|
|
* The export class for PESI additional sources stored as taxon sources in the CDM (mostly coming from ERMS)<p>
|
34 |
|
|
* @author a.mueller
|
35 |
4c575756
|
Andreas Müller
|
* @since 2019-09-22
|
36 |
d3530340
|
Andreas Müller
|
*/
|
37 |
|
|
@Component
|
38 |
|
|
public class PesiAdditionalSourceExport extends PesiExportBase {
|
39 |
|
|
|
40 |
|
|
private static final long serialVersionUID = -2567615286288369111L;
|
41 |
|
|
private static final Logger logger = Logger.getLogger(PesiAdditionalSourceExport.class);
|
42 |
|
|
|
43 |
|
|
private static final Class<? extends CdmBase> standardMethodParameter = IdentifiableSource.class;
|
44 |
|
|
|
45 |
|
|
private static int modCount = 1000;
|
46 |
|
|
private static final String dbTableName = "AdditionalTaxonSource";
|
47 |
|
|
private static final String pluralString = "addtional sources";
|
48 |
|
|
private static final String parentPluralString = "Taxa";
|
49 |
|
|
|
50 |
|
|
public PesiAdditionalSourceExport() {
|
51 |
|
|
super();
|
52 |
|
|
}
|
53 |
|
|
|
54 |
|
|
int countTaxa = 0;
|
55 |
|
|
int countSources = 0;
|
56 |
|
|
|
57 |
|
|
@Override
|
58 |
|
|
public Class<? extends CdmBase> getStandardMethodParameter() {
|
59 |
|
|
return standardMethodParameter;
|
60 |
|
|
}
|
61 |
|
|
|
62 |
|
|
@Override
|
63 |
|
|
protected void doInvoke(PesiExportState state) {
|
64 |
|
|
try {
|
65 |
|
|
logger.info("*** Started making " + pluralString + " ...");
|
66 |
|
|
|
67 |
|
|
// Stores whether this invoke was successful or not.
|
68 |
|
|
boolean success = true;
|
69 |
|
|
|
70 |
|
|
success &= doDelete(state);
|
71 |
|
|
|
72 |
|
|
// Get specific mappings: (CDM) Source -> (PESI) Addtional Taxon Source
|
73 |
|
|
PesiExportMapping mapping = getMapping();
|
74 |
|
|
mapping.initialize(state);
|
75 |
|
|
|
76 |
|
|
// Taxon Sources
|
77 |
|
|
success &= doPhase01(state, mapping);
|
78 |
|
|
|
79 |
|
|
logger.info("*** Finished Making " + pluralString + " ..." + getSuccessString(success));
|
80 |
|
|
|
81 |
|
|
if (!success){
|
82 |
|
|
state.getResult().addError("An unknown problem occurred");
|
83 |
|
|
}
|
84 |
|
|
return;
|
85 |
|
|
} catch (SQLException e) {
|
86 |
|
|
e.printStackTrace();
|
87 |
|
|
logger.error(e.getMessage());
|
88 |
|
|
state.getResult().addException(e, e.getMessage());
|
89 |
|
|
}
|
90 |
|
|
}
|
91 |
|
|
|
92 |
|
|
//PHASE 01: Sources
|
93 |
79276af0
|
Andreas Müller
|
private boolean doPhase01(PesiExportState state, PesiExportMapping mapping) {
|
94 |
d3530340
|
Andreas Müller
|
|
95 |
|
|
// System.out.println("PHASE 1 of description import");
|
96 |
|
|
logger.info("PHASE 1...");
|
97 |
|
|
int count = 0;
|
98 |
|
|
int pastCount = 0;
|
99 |
|
|
boolean success = true;
|
100 |
|
|
//int limit = state.getConfig().getLimitSave();
|
101 |
|
|
int limit = 1000;
|
102 |
|
|
|
103 |
79276af0
|
Andreas Müller
|
@SuppressWarnings("rawtypes")
|
104 |
|
|
List<TaxonBase> taxonList = null;
|
105 |
d3530340
|
Andreas Müller
|
|
106 |
|
|
TransactionStatus txStatus = startTransaction(true);
|
107 |
|
|
|
108 |
|
|
if (logger.isDebugEnabled()){
|
109 |
79276af0
|
Andreas Müller
|
logger.info("Started new transaction. Fetching some " + parentPluralString + " (max: " + limit + ") ...");
|
110 |
d3530340
|
Andreas Müller
|
logger.debug("Start snapshot, before starting loop");
|
111 |
|
|
ProfilerController.memorySnapshot();
|
112 |
|
|
}
|
113 |
|
|
|
114 |
|
|
List<String> propPath = Arrays.asList(new String[]{"sources.*"});
|
115 |
|
|
int partitionCount = 0;
|
116 |
|
|
while ((taxonList = getNextTaxonPartition(TaxonBase.class, limit, partitionCount++, propPath )) != null ) {
|
117 |
|
|
|
118 |
|
|
if (logger.isDebugEnabled()) {
|
119 |
79276af0
|
Andreas Müller
|
logger.info("Fetched " + taxonList.size() + " " + parentPluralString + ". Exporting...");
|
120 |
d3530340
|
Andreas Müller
|
}
|
121 |
|
|
|
122 |
79276af0
|
Andreas Müller
|
for (TaxonBase<?> taxon : taxonList) {
|
123 |
d3530340
|
Andreas Müller
|
countTaxa++;
|
124 |
79276af0
|
Andreas Müller
|
doCount(count++, modCount, parentPluralString);
|
125 |
d3530340
|
Andreas Müller
|
state.setCurrentTaxon(taxon);
|
126 |
|
|
if (!taxon.getSources().isEmpty()){
|
127 |
|
|
success &= handleSingleTaxon(taxon, mapping);
|
128 |
|
|
}
|
129 |
|
|
}
|
130 |
|
|
taxonList = null;
|
131 |
|
|
state.setCurrentTaxon(null);
|
132 |
|
|
|
133 |
|
|
// Commit transaction
|
134 |
|
|
commitTransaction(txStatus);
|
135 |
79276af0
|
Andreas Müller
|
logger.info("Exported " + (count - pastCount) + " " + parentPluralString + ". Total taxa: " + count + ". Total sources " + countSources);
|
136 |
d3530340
|
Andreas Müller
|
pastCount = count;
|
137 |
|
|
if (logger.isDebugEnabled()) {
|
138 |
|
|
ProfilerController.memorySnapshot();
|
139 |
|
|
}
|
140 |
|
|
// Start transaction
|
141 |
|
|
txStatus = startTransaction(true);
|
142 |
|
|
if(logger.isDebugEnabled()) {
|
143 |
79276af0
|
Andreas Müller
|
logger.info("Started new transaction. Fetching some " + parentPluralString + " (max: " + limit + ") for description import ...");
|
144 |
d3530340
|
Andreas Müller
|
}
|
145 |
|
|
}
|
146 |
|
|
|
147 |
|
|
// Commit transaction
|
148 |
|
|
commitTransaction(txStatus);
|
149 |
|
|
logger.debug("Committed transaction.");
|
150 |
|
|
return success;
|
151 |
|
|
}
|
152 |
|
|
|
153 |
79276af0
|
Andreas Müller
|
private boolean handleSingleTaxon(TaxonBase<?> taxon, PesiExportMapping mapping) {
|
154 |
d3530340
|
Andreas Müller
|
|
155 |
|
|
boolean success = true;
|
156 |
|
|
|
157 |
|
|
Set<IdentifiableSource> sources = new HashSet<>();
|
158 |
|
|
sources.addAll(taxon.getSources());
|
159 |
|
|
|
160 |
|
|
for (IdentifiableSource src : sources){
|
161 |
|
|
OriginalSourceType type = src.getType();
|
162 |
|
|
if (type == OriginalSourceType.Other){
|
163 |
|
|
mapping.invoke(src);
|
164 |
|
|
countSources++;
|
165 |
|
|
}
|
166 |
|
|
}
|
167 |
|
|
if (logger.isDebugEnabled()) {
|
168 |
|
|
logger.info("number of handled sources " + countSources);
|
169 |
|
|
}
|
170 |
|
|
return success;
|
171 |
|
|
}
|
172 |
|
|
|
173 |
|
|
/**
|
174 |
|
|
* Deletes all entries of database tables related to <code>Note</code>.
|
175 |
|
|
* @param state The PesiExportState
|
176 |
|
|
* @return Whether the delete operation was successful or not.
|
177 |
|
|
*/
|
178 |
|
|
protected boolean doDelete(PesiExportState state) {
|
179 |
|
|
Source destination = state.getConfig().getDestination();
|
180 |
|
|
|
181 |
|
|
// Clear NoteSource
|
182 |
|
|
String sql = "DELETE FROM AdditionalTaxonSource";
|
183 |
|
|
destination.update(sql);
|
184 |
|
|
|
185 |
|
|
return true;
|
186 |
|
|
}
|
187 |
|
|
|
188 |
|
|
/**
|
189 |
|
|
* Returns the TaxonFk for a given TaxonName or Taxon.
|
190 |
|
|
* @param state The {@link DbExportStateBase DbExportState}.
|
191 |
|
|
* @return
|
192 |
|
|
*/
|
193 |
|
|
@SuppressWarnings("unused") //used by mapper
|
194 |
|
|
private static Integer getTaxonFk(IdentifiableSource source, PesiExportState state) {
|
195 |
|
|
TaxonBase<?> entity = state.getCurrentTaxon();
|
196 |
|
|
return state.getDbId(entity);
|
197 |
|
|
}
|
198 |
|
|
|
199 |
|
|
@SuppressWarnings("unused") //used by mapper
|
200 |
|
|
private static Integer getSourceUseFk(IdentifiableSource source, PesiExportState state) {
|
201 |
ea77fefa
|
Andreas Müller
|
Integer result = state.getTransformer().getSourceUseKeyCacheByCache(source.getOriginalNameString());
|
202 |
|
|
if (result == null){
|
203 |
|
|
logger.error("Source use for " + source.getOriginalNameString() + " does not exist. Please check if all source uses of erms.sourceuses exist exist in PESI.SourceUse" );
|
204 |
|
|
}
|
205 |
|
|
return result;
|
206 |
d3530340
|
Andreas Müller
|
}
|
207 |
|
|
|
208 |
|
|
@SuppressWarnings("unused") //used by mapper
|
209 |
|
|
private static String getSourceNameCache(IdentifiableSource source) {
|
210 |
|
|
Reference ref = source.getCitation();
|
211 |
|
|
return ref == null? null : ref.getTitleCache();
|
212 |
|
|
}
|
213 |
|
|
|
214 |
|
|
@SuppressWarnings("unused") //used by mapper
|
215 |
|
|
private static Integer getCurrentTaxonFk(PesiExportState state) {
|
216 |
|
|
return state.getDbId(state.getCurrentTaxon());
|
217 |
|
|
}
|
218 |
|
|
|
219 |
|
|
//******************************* MAPPINGS ********************************************
|
220 |
|
|
|
221 |
|
|
/**
|
222 |
|
|
* Returns the CDM to PESI specific export mappings for PESI additonal sources.
|
223 |
|
|
* @return The {@link PesiExportMapping PesiExportMapping}.
|
224 |
|
|
*/
|
225 |
|
|
private PesiExportMapping getMapping() {
|
226 |
|
|
PesiExportMapping mapping = new PesiExportMapping(dbTableName);
|
227 |
|
|
|
228 |
|
|
mapping.addMapper(MethodMapper.NewInstance("TaxonFk", this, IdentifiableSource.class, PesiExportState.class));
|
229 |
|
|
mapping.addMapper(DbObjectMapper.NewInstance("Citation", "SourceFk"));
|
230 |
|
|
mapping.addMapper(MethodMapper.NewInstance("SourceUseFk", this, IdentifiableSource.class, PesiExportState.class));
|
231 |
|
|
mapping.addMapper(DbStringMapper.NewInstance("originalNameString", "SourceUseCache"));
|
232 |
|
|
mapping.addMapper(DbObjectMapper.NewInstance("Citation", "SourceNameCache", IS_CACHE));
|
233 |
|
|
mapping.addMapper(DbStringMapper.NewInstance("citationMicroReference", "SourceDetail"));
|
234 |
|
|
|
235 |
|
|
return mapping;
|
236 |
|
|
}
|
237 |
|
|
|
238 |
|
|
@Override
|
239 |
|
|
protected boolean doCheck(PesiExportState state) {
|
240 |
|
|
boolean result = true;
|
241 |
|
|
return result;
|
242 |
|
|
}
|
243 |
|
|
|
244 |
|
|
@Override
|
245 |
|
|
protected boolean isIgnore(PesiExportState state) {
|
246 |
|
|
return ! state.getConfig().isDoAdditionalTaxonSource();
|
247 |
|
|
}
|
248 |
|
|
}
|