3 * Copyright (C) 2009 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
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.
10 package eu
.etaxonomy
.cdm
.io
.pesi
.out
;
12 import java
.sql
.SQLException
;
13 import java
.util
.ArrayList
;
14 import java
.util
.HashSet
;
15 import java
.util
.List
;
18 import org
.apache
.log4j
.Logger
;
19 import org
.springframework
.stereotype
.Component
;
20 import org
.springframework
.transaction
.TransactionStatus
;
22 import eu
.etaxonomy
.cdm
.io
.common
.Source
;
23 import eu
.etaxonomy
.cdm
.io
.common
.IExportConfigurator
.DO_REFERENCES
;
24 import eu
.etaxonomy
.cdm
.io
.common
.mapping
.out
.DbExtensionMapper
;
25 import eu
.etaxonomy
.cdm
.io
.common
.mapping
.out
.DbStringMapper
;
26 import eu
.etaxonomy
.cdm
.io
.common
.mapping
.out
.DbTimePeriodMapper
;
27 import eu
.etaxonomy
.cdm
.io
.common
.mapping
.out
.DbUriMapper
;
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
.erms
.ErmsTransformer
;
31 import eu
.etaxonomy
.cdm
.model
.agent
.TeamOrPersonBase
;
32 import eu
.etaxonomy
.cdm
.model
.common
.CdmBase
;
33 import eu
.etaxonomy
.cdm
.model
.common
.ExtensionType
;
34 import eu
.etaxonomy
.cdm
.model
.common
.IdentifiableSource
;
35 import eu
.etaxonomy
.cdm
.model
.reference
.Reference
;
36 import eu
.etaxonomy
.cdm
.model
.reference
.ReferenceType
;
39 * The export class for {@link eu.etaxonomy.cdm.model.reference.Reference References}.<p>
40 * Inserts into DataWarehouse database table <code>Source</code>.
46 public class PesiSourceExport
extends PesiExportBase
{
47 private static final Logger logger
= Logger
.getLogger(PesiSourceExport
.class);
48 private static final Class
<?
extends CdmBase
> standardMethodParameter
= Reference
.class;
50 private static int modCount
= 1000;
51 private static final String dbTableName
= "Source";
52 private static final String pluralString
= "Sources";
53 List
<Integer
> storedSourceIds
= new ArrayList
<Integer
>();
55 public PesiSourceExport() {
60 * @see eu.etaxonomy.cdm.io.pesi.out.PesiExportBase#getStandardMethodParameter()
63 public Class
<?
extends CdmBase
> getStandardMethodParameter() {
64 return standardMethodParameter
;
68 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#doCheck(eu.etaxonomy.cdm.io.common.IoStateBase)
71 protected boolean doCheck(PesiExportState state
) {
72 boolean result
= true;
77 * Checks whether a sourceId was stored already.
81 protected boolean isStoredSourceId(Integer sourceId
) {
82 if (storedSourceIds
.contains(sourceId
)) {
90 * Adds a sourceId to the list of storedSourceIds.
93 protected void addToStoredSourceIds(Integer sourceId
) {
94 if (! storedSourceIds
.contains(sourceId
)) {
95 this.storedSourceIds
.add(sourceId
);
100 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#doInvoke(eu.etaxonomy.cdm.io.common.IoStateBase)
103 protected void doInvoke(PesiExportState state
) {
105 logger
.info("*** Started Making " + pluralString
+ " ...");
107 PesiExportConfigurator pesiExportConfigurator
= state
.getConfig();
109 // Get the limit for objects to save within a single transaction.
110 int limit
= pesiExportConfigurator
.getLimitSave();
112 // Stores whether this invoke was successful or not.
113 boolean success
= true ;
115 // PESI: Clear the database table Source.
118 // Get specific mappings: (CDM) Reference -> (PESI) Source
119 PesiExportMapping mapping
= getMapping();
121 // Initialize the db mapper
122 mapping
.initialize(state
);
124 // Create the Sources
127 TransactionStatus txStatus
= null;
128 List
<Reference
> list
= null;
130 // logger.error("PHASE 1...");
132 txStatus
= startTransaction(true);
133 logger
.info("Started new transaction. Fetching some " + pluralString
+ " (max: " + limit
+ ") ...");
134 while ((list
= getReferenceService().list(null, limit
, count
, null, null)).size() > 0) {
136 logger
.debug("Fetched " + list
.size() + " " + pluralString
+ ". Exporting...");
137 for (Reference
<?
> reference
: list
) {
138 doCount(count
++, modCount
, pluralString
);
139 success
&= mapping
.invoke(reference
);
142 // Commit transaction
143 commitTransaction(txStatus
);
144 logger
.debug("Committed transaction.");
145 logger
.info("Exported " + (count
- pastCount
) + " " + pluralString
+ ". Total: " + count
);
149 txStatus
= startTransaction(true);
150 logger
.info("Started new transaction. Fetching some " + pluralString
+ " (max: " + limit
+ ") ...");
152 if (list
.size() == 0) {
153 logger
.info("No " + pluralString
+ " left to fetch.");
155 // Commit transaction
156 commitTransaction(txStatus
);
157 logger
.info("Committed transaction.");
159 logger
.info("*** Finished Making " + pluralString
+ " ..." + getSuccessString(success
));
162 state
.setUnsuccessfull();
165 } catch (SQLException e
) {
167 logger
.error(e
.getMessage());
168 state
.setUnsuccessfull();
174 * Deletes all entries of database tables related to <code>Source</code>.
175 * @param state The {@link PesiExportState PesiExportState}.
176 * @return Whether the delete operation was successful or not.
178 protected boolean doDelete(PesiExportState state
) {
179 PesiExportConfigurator pesiConfig
= (PesiExportConfigurator
) state
.getConfig();
182 Source destination
= pesiConfig
.getDestination();
185 sql
= "DELETE FROM Occurrence";
186 destination
.setQuery(sql
);
187 destination
.update(sql
);
190 sql
= "DELETE FROM Taxon";
191 destination
.setQuery(sql
);
192 destination
.update(sql
);
195 sql
= "DELETE FROM " + dbTableName
;
196 destination
.setQuery(sql
);
197 destination
.update(sql
);
203 * Returns the <code>IMIS_Id</code> attribute.
204 * @param reference The {@link Reference Reference}.
205 * @return The <code>IMIS_Id</code> attribute.
208 @SuppressWarnings("unused")
209 private static Integer
getIMIS_Id(Reference
<?
> reference
) {
214 * Returns the <code>SourceCategoryFK</code> attribute.
215 * @param reference The {@link Reference Reference}.
216 * @return The <code>SourceCategoryFK</code> attribute.
219 @SuppressWarnings("unused")
220 private static Integer
getSourceCategoryFK(Reference
<?
> reference
) {
221 Integer result
= null;
223 result
= PesiTransformer
.reference2SourceCategoryFK(reference
);
224 } catch (Exception e
) {
231 * Returns the <code>SourceCategoryCache</code> attribute.
232 * @param reference The {@link Reference Reference}.
233 * @return The <code>SourceCategoryCache</code> attribute.
236 @SuppressWarnings("unused")
237 private static String
getSourceCategoryCache(Reference
<?
> reference
) {
238 String result
= null;
240 result
= PesiTransformer
.getSourceCategoryCache(reference
);
241 } catch (Exception e
) {
248 * Returns the <code>Name</code> attribute. The corresponding CDM attribute is <code>title</code>.
249 * @param reference The {@link Reference Reference}.
250 * @return The <code>Name</code> attribute.
253 @SuppressWarnings("unused")
254 private static String
getName(Reference
<?
> reference
) {
255 if (reference
!= null) {
256 return reference
.getTitleCache(); // was getTitle()
263 * Returns the <code>AuthorString</code> attribute. The corresponding CDM attribute is the <code>titleCache</code> of an <code>authorTeam</code>.
264 * @param reference The {@link Reference Reference}.
265 * @return The <code>AuthorString</code> attribute.
268 @SuppressWarnings("unused")
269 private static String
getAuthorString(Reference
<?
> reference
) {
270 String result
= null;
273 if (reference
!= null) {
274 TeamOrPersonBase team
= reference
.getAuthorTeam();
276 result
= team
.getTitleCache();
277 // result = team.getNomenclaturalTitle();
282 } catch (Exception e
) {
290 * Returns the <code>NomRefCache</code> attribute. The corresponding CDM attribute is <code>titleCache</code>.
291 * @param reference The {@link Reference Reference}.
292 * @return The <code>NomRefCache</code> attribute.
295 @SuppressWarnings("unused")
296 private static String
getNomRefCache(Reference
<?
> reference
) {
298 // if (reference != null) {
299 // return reference.getTitleCache();
306 * Returns the <code>Notes</code> attribute.
307 * @param reference The {@link Reference Reference}.
308 * @return The <code>Notes</code> attribute.
311 @SuppressWarnings("unused")
312 private static String
getNotes(Reference
<?
> reference
) {
318 * Returns the <code>RefIdInSource</code> attribute.
319 * @param reference The {@link Reference Reference}.
320 * @return The <code>RefIdInSource</code> attribute.
323 @SuppressWarnings("unused")
324 private static String
getRefIdInSource(Reference
<?
> reference
) {
325 String result
= null;
328 if (reference
!= null) {
329 Set
<IdentifiableSource
> sourceAll
= reference
.getSources();
330 Set
<IdentifiableSource
> sourceCandidates
= filterOriginalPesiDbSources(sourceAll
);
332 if (sourceCandidates
.size() == 1) {
333 result
= sourceCandidates
.iterator().next().getIdInSource();
334 } else if (sourceCandidates
.size() > 1) {
335 logger
.warn("Reference for RefIdInSource has multiple IdentifiableSources which are candidates for a PESI originalDbSource. RefIdInSource can't be determined correctly and will be left out: " + reference
.getUuid() + " (" + reference
.getTitleCache() + ")");
337 // for (IdentifiableSource source : sources) {
338 // result += source.getIdInSource();
339 // if (count < sources.size()) {
346 } catch (Exception e
) {
353 private static Set
<IdentifiableSource
> filterOriginalPesiDbSources(
354 Set
<IdentifiableSource
> sourceAll
) {
355 Set
<IdentifiableSource
> sourceCandidates
= new HashSet
<IdentifiableSource
>();
356 for (IdentifiableSource source
: sourceAll
){
357 if (isOriginalPesiDbSource(source
)){
358 sourceCandidates
.add(source
);
361 return sourceCandidates
;
364 private static boolean isOriginalPesiDbSource(IdentifiableSource source
) {
365 return (source
.getCitation() != null) &&
366 source
.getCitation().getType().equals(ReferenceType
.Database
);
370 * Returns the <code>OriginalDB</code> attribute. The corresponding CDM attribute is the <code>titleCache</code> of a <code>citation</code>.
371 * @param reference The {@link Reference Reference}.
372 * @return The <code>OriginalDB</code> attribute.
375 @SuppressWarnings("unused")
376 private static String
getOriginalDB(Reference
<?
> reference
) {
380 if (reference
!= null) {
381 Set
<IdentifiableSource
> sourcesAll
= reference
.getSources();
382 Set
<IdentifiableSource
> sourceCandidates
= filterOriginalPesiDbSources(sourcesAll
);
384 if (sourceCandidates
.size() == 1) {
385 Reference citation
= sourceCandidates
.iterator().next().getCitation();
386 if (citation
!= null) {
387 result
= PesiTransformer
.databaseString2Abbreviation(citation
.getTitleCache()); //or just title
389 logger
.warn("OriginalDB can not be determined because the citation of this source is NULL: " + sourceCandidates
.iterator().next().getUuid());
391 } else if (sourceCandidates
.size() > 1) {
392 logger
.warn("Taxon has multiple IdentifiableSources: " + reference
.getUuid() + " (" + reference
.getTitleCache() + ")");
394 for (IdentifiableSource source
: sourceCandidates
) {
395 Reference citation
= source
.getCitation();
396 if (citation
!= null) {
397 result
+= PesiTransformer
.databaseString2Abbreviation(citation
.getTitleCache());
398 if (count
< sourceCandidates
.size()) {
408 } catch (Exception e
) {
416 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#isIgnore(eu.etaxonomy.cdm.io.common.IoStateBase)
419 protected boolean isIgnore(PesiExportState state
) {
420 return ! state
.getConfig().getDoReferences().equals(DO_REFERENCES
.ALL
);
424 * Returns the CDM to PESI specific export mappings.
425 * @return The {@link PesiExportMapping PesiExportMapping}.
427 private PesiExportMapping
getMapping() {
428 PesiExportMapping mapping
= new PesiExportMapping(dbTableName
);
429 ExtensionType extensionType
= null;
431 mapping
.addMapper(IdMapper
.NewInstance("SourceId"));
434 extensionType
= (ExtensionType
)getTermService().find(ErmsTransformer
.IMIS_UUID
);
435 if (extensionType
!= null) {
436 mapping
.addMapper(DbExtensionMapper
.NewInstance(extensionType
, "IMIS_Id"));
438 mapping
.addMapper(MethodMapper
.NewInstance("IMIS_Id", this));
441 mapping
.addMapper(MethodMapper
.NewInstance("SourceCategoryFK", this));
442 mapping
.addMapper(MethodMapper
.NewInstance("SourceCategoryCache", this));
443 mapping
.addMapper(MethodMapper
.NewInstance("Name", this));
444 mapping
.addMapper(DbStringMapper
.NewInstance("referenceAbstract", "Abstract"));
445 mapping
.addMapper(DbStringMapper
.NewInstance("title", "Title"));
446 mapping
.addMapper(MethodMapper
.NewInstance("AuthorString", this));
447 mapping
.addMapper(DbTimePeriodMapper
.NewInstance("datePublished", "RefYear"));
448 mapping
.addMapper(MethodMapper
.NewInstance("NomRefCache", this));
449 mapping
.addMapper(DbUriMapper
.NewInstance("uri", "Link"));
450 mapping
.addMapper(MethodMapper
.NewInstance("Notes", this));
451 mapping
.addMapper(MethodMapper
.NewInstance("RefIdInSource", this));
452 mapping
.addMapper(MethodMapper
.NewInstance("OriginalDB", this));