2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
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.
10 package eu
.etaxonomy
.cdm
.io
.berlinModel
.in
;
12 import static eu
.etaxonomy
.cdm
.io
.berlinModel
.BerlinModelTransformer
.REF_ARTICLE
;
13 import static eu
.etaxonomy
.cdm
.io
.berlinModel
.BerlinModelTransformer
.REF_BOOK
;
14 import static eu
.etaxonomy
.cdm
.io
.berlinModel
.BerlinModelTransformer
.REF_CONFERENCE_PROCEEDINGS
;
15 import static eu
.etaxonomy
.cdm
.io
.berlinModel
.BerlinModelTransformer
.REF_DATABASE
;
16 import static eu
.etaxonomy
.cdm
.io
.berlinModel
.BerlinModelTransformer
.REF_INFORMAL
;
17 import static eu
.etaxonomy
.cdm
.io
.berlinModel
.BerlinModelTransformer
.REF_JOURNAL
;
18 import static eu
.etaxonomy
.cdm
.io
.berlinModel
.BerlinModelTransformer
.REF_JOURNAL_VOLUME
;
19 import static eu
.etaxonomy
.cdm
.io
.berlinModel
.BerlinModelTransformer
.REF_PART_OF_OTHER_TITLE
;
20 import static eu
.etaxonomy
.cdm
.io
.berlinModel
.BerlinModelTransformer
.REF_PRINT_SERIES
;
21 import static eu
.etaxonomy
.cdm
.io
.berlinModel
.BerlinModelTransformer
.REF_UNKNOWN
;
22 import static eu
.etaxonomy
.cdm
.io
.berlinModel
.BerlinModelTransformer
.REF_WEBSITE
;
23 import static eu
.etaxonomy
.cdm
.io
.common
.ImportHelper
.NO_OVERWRITE
;
24 import static eu
.etaxonomy
.cdm
.io
.common
.ImportHelper
.OBLIGATORY
;
25 import static eu
.etaxonomy
.cdm
.io
.common
.ImportHelper
.OVERWRITE
;
28 import java
.net
.URISyntaxException
;
29 import java
.sql
.ResultSet
;
30 import java
.sql
.SQLException
;
31 import java
.util
.ArrayList
;
32 import java
.util
.Arrays
;
33 import java
.util
.HashMap
;
34 import java
.util
.HashSet
;
35 import java
.util
.List
;
38 import java
.util
.UUID
;
40 import org
.apache
.log4j
.Logger
;
41 import org
.springframework
.stereotype
.Component
;
43 import eu
.etaxonomy
.cdm
.common
.CdmUtils
;
44 import eu
.etaxonomy
.cdm
.io
.berlinModel
.CdmOneToManyMapper
;
45 import eu
.etaxonomy
.cdm
.io
.berlinModel
.CdmStringMapper
;
46 import eu
.etaxonomy
.cdm
.io
.berlinModel
.CdmUriMapper
;
47 import eu
.etaxonomy
.cdm
.io
.berlinModel
.in
.validation
.BerlinModelReferenceImportValidator
;
48 import eu
.etaxonomy
.cdm
.io
.common
.ICdmIO
;
49 import eu
.etaxonomy
.cdm
.io
.common
.IImportConfigurator
;
50 import eu
.etaxonomy
.cdm
.io
.common
.ImportHelper
;
51 import eu
.etaxonomy
.cdm
.io
.common
.ResultSetPartitioner
;
52 import eu
.etaxonomy
.cdm
.io
.common
.Source
;
53 import eu
.etaxonomy
.cdm
.io
.common
.mapping
.CdmAttributeMapperBase
;
54 import eu
.etaxonomy
.cdm
.io
.common
.mapping
.CdmIoMapping
;
55 import eu
.etaxonomy
.cdm
.io
.common
.mapping
.CdmSingleAttributeMapperBase
;
56 import eu
.etaxonomy
.cdm
.io
.common
.mapping
.DbImportExtensionMapper
;
57 import eu
.etaxonomy
.cdm
.io
.common
.mapping
.DbImportMarkerMapper
;
58 import eu
.etaxonomy
.cdm
.io
.common
.mapping
.DbSingleAttributeImportMapperBase
;
59 import eu
.etaxonomy
.cdm
.model
.agent
.Team
;
60 import eu
.etaxonomy
.cdm
.model
.agent
.TeamOrPersonBase
;
61 import eu
.etaxonomy
.cdm
.model
.common
.CdmBase
;
62 import eu
.etaxonomy
.cdm
.model
.common
.ExtensionType
;
63 import eu
.etaxonomy
.cdm
.model
.common
.IdentifiableSource
;
64 import eu
.etaxonomy
.cdm
.model
.common
.Marker
;
65 import eu
.etaxonomy
.cdm
.model
.common
.MarkerType
;
66 import eu
.etaxonomy
.cdm
.model
.reference
.IArticle
;
67 import eu
.etaxonomy
.cdm
.model
.reference
.IBookSection
;
68 import eu
.etaxonomy
.cdm
.model
.reference
.IPrintSeries
;
69 import eu
.etaxonomy
.cdm
.model
.reference
.Reference
;
70 import eu
.etaxonomy
.cdm
.model
.reference
.ReferenceFactory
;
71 import eu
.etaxonomy
.cdm
.model
.reference
.ReferenceType
;
79 public class BerlinModelReferenceImport
extends BerlinModelImportBase
{
80 private static final Logger logger
= Logger
.getLogger(BerlinModelReferenceImport
.class);
82 public static final String NOM_REFERENCE_NAMESPACE
= "NomReference";
83 public static final String BIBLIO_REFERENCE_NAMESPACE
= "BiblioReference";
85 public static final UUID REF_DEPOSITED_AT_UUID
= UUID
.fromString("23ca88c7-ce73-41b2-8ca3-2cb22f013beb");
86 public static final UUID REF_SOURCE_UUID
= UUID
.fromString("d6432582-2216-4b08-b0db-76f6c1013141");
87 public static final UUID DATE_STRING_UUID
= UUID
.fromString("e4130eae-606e-4b0c-be4f-e93dc161be7d");
88 public static final UUID IS_PAPER_UUID
= UUID
.fromString("8a326129-d0d0-4f9d-bbdf-8d86b037c65e");
91 private int modCount
= 1000;
92 private static final String pluralString
= "references";
93 private static final String dbTableName
= "reference";
96 public BerlinModelReferenceImport(){
97 super(dbTableName
, pluralString
);
100 protected void initializeMappers(BerlinModelImportState state
){
101 for (CdmAttributeMapperBase mapper
: classMappers
){
102 if (mapper
instanceof DbSingleAttributeImportMapperBase
){
103 DbSingleAttributeImportMapperBase singleMapper
= (DbSingleAttributeImportMapperBase
)mapper
;
104 singleMapper
.initialize(state
, Reference
.class);
110 protected static CdmAttributeMapperBase
[] classMappers
= new CdmAttributeMapperBase
[]{
111 new CdmStringMapper("edition", "edition"),
112 new CdmStringMapper("volume", "volume"),
113 new CdmStringMapper("publisher", "publisher"),
114 new CdmStringMapper("publicationTown", "placePublished"),
115 new CdmStringMapper("isbn", "isbn"),
116 new CdmStringMapper("isbn", "isbn"),
117 new CdmStringMapper("pageString", "pages"),
118 new CdmStringMapper("series", "series"),
119 new CdmStringMapper("issn", "issn"),
120 new CdmUriMapper("url", "uri"),
121 DbImportExtensionMapper
.NewInstance("NomStandard", ExtensionType
.NOMENCLATURAL_STANDARD()),
122 DbImportExtensionMapper
.NewInstance("DateString", DATE_STRING_UUID
, "Date String", "Date String", "dates"),
123 DbImportExtensionMapper
.NewInstance("RefDepositedAt", REF_DEPOSITED_AT_UUID
, "RefDepositedAt", "reference is deposited at", "at"),
124 DbImportExtensionMapper
.NewInstance("RefSource", REF_SOURCE_UUID
, "RefSource", "reference source", "source"),
125 DbImportMarkerMapper
.NewInstance("isPaper", IS_PAPER_UUID
, "is paper", "is paper", "paper", false)
129 protected static String
[] operationalAttributes
= new String
[]{
130 "refId", "refCache", "nomRefCache", "preliminaryFlag", "inRefFk", "title", "nomTitleAbbrev",
131 "refAuthorString", "nomAuthorTeamFk",
132 "refCategoryFk", "thesisFlag", "informalRefCategory", "idInSource"
135 protected static String
[] createdAndNotesAttributes
= new String
[]{
136 "created_When", "updated_When", "created_Who", "updated_Who", "notes"
139 protected static String
[] unclearMappers
= new String
[]{
140 /*"isPaper",*/ "exportDate",
148 //type to count the references nomReferences that have been created and saved
149 private class RefCounter
{
150 RefCounter() {nomRefCount
= 0; referenceCount
= 0;};
153 public String
toString(){return String
.valueOf(nomRefCount
) + "," +String
.valueOf(referenceCount
);};
158 * @see eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportBase#getRecordQuery(eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportConfigurator)
161 protected String
getRecordQuery(BerlinModelImportConfigurator config
) {
162 return null; //not needed
166 protected void doInvoke(BerlinModelImportState state
){
167 logger
.info("start make " + getPluralString() + " ...");
169 boolean success
= true;
170 initializeMappers(state
);
171 BerlinModelImportConfigurator config
= state
.getConfig();
172 Source source
= config
.getSource();
174 String strSelectId
= " SELECT Reference.RefId as refId ";
175 String strSelectFull
=
176 " SELECT Reference.* ,InReference.RefCategoryFk as InRefCategoryFk, RefSource.RefSource " ;
177 String strFrom
= " FROM %s " +
178 " LEFT OUTER JOIN Reference as InReference ON InReference.refId = Reference.inRefFk " +
179 " LEFT OUTER JOIN RefSource ON Reference.RefSourceFk = RefSource.RefSourceId " +
181 String strWherePartitioned
= " AND (Reference.refId IN ("+ ID_LIST_TOKEN
+ ") ) ";
183 String referenceTable
= CdmUtils
.Nz(state
.getConfig().getReferenceIdTable());
184 referenceTable
= referenceTable
.isEmpty() ?
" Reference" : referenceTable
+ " as Reference ";
185 String strIdFrom
= String
.format(strFrom
, referenceTable
);
187 String strSelectIdBase
= strSelectId
+ strIdFrom
;
189 String referenceFilter
= CdmUtils
.Nz(state
.getConfig().getReferenceIdTable());
190 if (! referenceFilter
.isEmpty()){
191 referenceFilter
= " AND " + referenceFilter
+ " ";
193 referenceFilter
= ""; //don't use it for now
195 String strIdQueryFirstPath
= strSelectId
+ strIdFrom
;
196 String strIdQuerySecondPath
= strSelectId
+ strIdFrom
+ " AND (Reference.InRefFk is NOT NULL) ";
198 // if (config.getDoReferences() == CONCEPT_REFERENCES){
199 // strIdQueryNoInRef += " AND ( Reference.refId IN ( SELECT ptRefFk FROM PTaxon) ) " + referenceFilter;
202 String strRecordQuery
= strSelectFull
+ String
.format(strFrom
, " Reference ") + strWherePartitioned
;
204 int recordsPerTransaction
= config
.getRecordsPerTransaction();
207 ResultSetPartitioner partitioner
= ResultSetPartitioner
.NewInstance(source
, strIdQueryFirstPath
, strRecordQuery
, recordsPerTransaction
);
208 while (partitioner
.nextPartition()){
209 partitioner
.doPartition(this, state
);
211 logger
.info("end make references without in-references ... " + getSuccessString(success
));
212 state
.setReferenceSecondPath(true);
214 // if (config.getDoReferences() == ALL || config.getDoReferences() == NOMENCLATURAL){
217 partitioner
= ResultSetPartitioner
.NewInstance(source
, strIdQuerySecondPath
, strRecordQuery
, recordsPerTransaction
);
218 while (partitioner
.nextPartition()){
219 partitioner
.doPartition(this, state
);
221 logger
.info("end make references with no 1 in-reference ... " + getSuccessString(success
));
222 state
.setReferenceSecondPath(false);
226 } catch (SQLException e
) {
227 logger
.error("SQLException:" + e
);
228 state
.setUnsuccessfull();
231 logger
.info("end make " + getPluralString() + " ... " + getSuccessString(success
));
233 state
.setUnsuccessfull();
242 * @see eu.etaxonomy.cdm.io.berlinModel.in.IPartitionedIO#doPartition(eu.etaxonomy.cdm.io.berlinModel.in.ResultSetPartitioner, eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportState)
244 public boolean doPartition(ResultSetPartitioner partitioner
, BerlinModelImportState state
) {
245 if (state
.isReferenceSecondPath()){
246 return doPartitionSecondPath(partitioner
, state
);
248 boolean success
= true;
250 Map
<Integer
, Reference
> nomRefToSave
= new HashMap
<Integer
, Reference
>();
251 Map
<Integer
, Reference
> biblioRefToSave
= new HashMap
<Integer
, Reference
>();
253 Map
<String
, Reference
> relatedNomReferences
= partitioner
.getObjectMap(NOM_REFERENCE_NAMESPACE
);
254 Map
<String
, Reference
> relatedBiblioReferences
= partitioner
.getObjectMap(BIBLIO_REFERENCE_NAMESPACE
);
256 BerlinModelImportConfigurator config
= state
.getConfig();
261 RefCounter refCounter
= new RefCounter();
263 ResultSet rs
= partitioner
.getResultSet();
267 if ((i
++ % modCount
) == 0 && i
!= 1 ){ logger
.info("References handled: " + (i
-1) + " in round -" );}
269 success
&= makeSingleReferenceRecord(rs
, state
, partitioner
, biblioRefToSave
, nomRefToSave
, relatedBiblioReferences
, relatedNomReferences
, refCounter
);
272 //for the concept reference a fixed uuid may be needed -> change uuid
273 Integer sourceSecId
= (Integer
)config
.getSourceSecId();
274 Reference
<?
> sec
= biblioRefToSave
.get(sourceSecId
);
276 sec
= nomRefToSave
.get(sourceSecId
);
279 sec
.setUuid(config
.getSecUuid());
280 logger
.info("SecUuid changed to: " + config
.getSecUuid());
283 //save and store in map
284 logger
.info("Save nomenclatural references (" + refCounter
.nomRefCount
+ ")");
285 getReferenceService().saveOrUpdate(nomRefToSave
.values());
286 logger
.info("Save bibliographical references (" + refCounter
.referenceCount
+")");
287 getReferenceService().saveOrUpdate(biblioRefToSave
.values());
289 // }//end resultSetList
291 // logger.info("end makeReferences ..." + getSuccessString(success));;
293 } catch (SQLException e
) {
294 logger
.error("SQLException:" + e
);
302 * Adds the inReference to the according references.
307 private boolean doPartitionSecondPath(ResultSetPartitioner partitioner
, BerlinModelImportState state
) {
308 boolean success
= true;
310 Map
<Integer
, Reference
> nomRefToSave
= new HashMap
<Integer
, Reference
>();
311 Map
<Integer
, Reference
> biblioRefToSave
= new HashMap
<Integer
, Reference
>();
313 Map
<String
, Reference
> relatedNomReferences
= partitioner
.getObjectMap(NOM_REFERENCE_NAMESPACE
);
314 Map
<String
, Reference
> relatedBiblioReferences
= partitioner
.getObjectMap(BIBLIO_REFERENCE_NAMESPACE
);
318 RefCounter refCounter
= new RefCounter();
320 ResultSet rs
= partitioner
.getResultSet();
323 if ((i
++ % modCount
) == 0 && i
!= 1 ){ logger
.info("References handled: " + (i
-1) + " in round -" );}
325 Integer refId
= rs
.getInt("refId");
326 Integer inRefFk
= rs
.getInt("inRefFk");
328 if (inRefFk
!= null){
330 Reference
<?
> thisNomRef
= getReferenceOnlyFromMaps(relatedNomReferences
, relatedBiblioReferences
, String
.valueOf(refId
));
331 Reference
<?
> thisBiblioRef
= getReferenceOnlyFromMaps(relatedBiblioReferences
, relatedNomReferences
, String
.valueOf(refId
));
333 Reference
<?
> nomInReference
= relatedNomReferences
.get(String
.valueOf(inRefFk
));
334 Reference
<?
> biblioInReference
= relatedBiblioReferences
.get(String
.valueOf(inRefFk
));
335 boolean inRefExists
= false;
336 if (thisNomRef
!= null){
337 Reference
<?
> inRef
= (nomInReference
!= null)? nomInReference
: biblioInReference
;
339 logger
.warn("No InRef found for nomRef: " + thisNomRef
.getTitleCache() + "; RefId: " + refId
+ "; inRefFK: " + inRefFk
);
341 thisNomRef
.setInReference(inRef
);
342 nomRefToSave
.put(refId
, thisNomRef
);
343 //remember that an in reference exists
344 inRefExists
|= (inRef
!= null);
345 thisNomRef
.setTitleCache(null);
346 thisNomRef
.getTitleCache();
348 if (thisBiblioRef
!= null){
349 Reference
<?
> inRef
= (biblioInReference
!= null)? biblioInReference
: nomInReference
;
351 logger
.warn("No InRef found for biblioRef: " + thisBiblioRef
.getTitleCache() + "; RefId: " + refId
+ "; inRefFK: " + inRefFk
);
353 thisBiblioRef
.setInReference(inRef
);
354 biblioRefToSave
.put(refId
, thisBiblioRef
);
355 //remember that an in reference exists
356 inRefExists
|= (inRef
!= null);
357 thisBiblioRef
.setTitleCache(null);
358 thisBiblioRef
.getTitleCache();
360 if (inRefExists
== false){
361 logger
.warn("No in reference was saved though an 'inRefFk' is available. RefId " + refId
);
368 //save and store in map
369 logger
.info("Save nomenclatural references (" + refCounter
.nomRefCount
+ ")");
370 getReferenceService().saveOrUpdate(nomRefToSave
.values());
371 logger
.info("Save bibliographical references (" + refCounter
.referenceCount
+")");
372 getReferenceService().saveOrUpdate(biblioRefToSave
.values());
374 // }//end resultSetList
376 // logger.info("end makeReferences ..." + getSuccessString(success));;
378 } catch (SQLException e
) {
379 logger
.error("SQLException:" + e
);
387 * @see eu.etaxonomy.cdm.io.berlinModel.in.IPartitionedIO#getRelatedObjectsForPartition(java.sql.ResultSet)
389 public Map
<Object
, Map
<String
, ?
extends CdmBase
>> getRelatedObjectsForPartition(ResultSet rs
) {
394 Map
<Object
, Map
<String
, ?
extends CdmBase
>> result
= new HashMap
<Object
, Map
<String
, ?
extends CdmBase
>>();
397 Set
<String
> teamIdSet
= new HashSet
<String
>();
398 Set
<String
> referenceIdSet
= new HashSet
<String
>();
401 handleForeignKey(rs
, teamIdSet
, "NomAuthorTeamFk");
402 handleForeignKey(rs
, referenceIdSet
, "InRefFk");
403 //TODO only needed in second path but state not available here to check if state is second path
404 handleForeignKey(rs
, referenceIdSet
, "refId");
408 nameSpace
= BerlinModelAuthorTeamImport
.NAMESPACE
;
409 cdmClass
= Team
.class;
411 Map
<String
, Team
> teamMap
= (Map
<String
, Team
>)getCommonService().getSourcedObjectsByIdInSource(cdmClass
, idSet
, nameSpace
);
412 result
.put(nameSpace
, teamMap
);
416 nameSpace
= NOM_REFERENCE_NAMESPACE
;
417 cdmClass
= Reference
.class;
418 idSet
= referenceIdSet
;
419 Map
<String
, Reference
> nomRefMap
= (Map
<String
, Reference
>)getCommonService().getSourcedObjectsByIdInSource(cdmClass
, idSet
, nameSpace
);
420 result
.put(nameSpace
, nomRefMap
);
422 //biblio reference map
423 nameSpace
= BIBLIO_REFERENCE_NAMESPACE
;
424 cdmClass
= Reference
.class;
425 idSet
= referenceIdSet
;
426 Map
<String
, Reference
> biblioRefMap
= (Map
<String
, Reference
>)getCommonService().getSourcedObjectsByIdInSource(cdmClass
, idSet
, nameSpace
);
427 result
.put(nameSpace
, biblioRefMap
);
429 } catch (SQLException e
) {
430 throw new RuntimeException(e
);
437 * Handles a single reference record
440 * @param biblioRefToSave
441 * @param nomRefToSave
442 * @param relatedBiblioReferences
443 * @param relatedNomReferences
447 private boolean makeSingleReferenceRecord(
449 BerlinModelImportState state
,
450 ResultSetPartitioner
<BerlinModelImportState
> partitioner
,
451 Map
<Integer
, Reference
> biblioRefToSave
,
452 Map
<Integer
, Reference
> nomRefToSave
,
453 Map
<String
, Reference
> relatedBiblioReferences
,
454 Map
<String
, Reference
> relatedNomReferences
,
455 RefCounter refCounter
){
456 boolean success
= true;
458 Integer refId
= null;
460 Map
<String
, Object
> valueMap
= getValueMap(rs
);
462 Integer categoryFk
= (Integer
)valueMap
.get("refCategoryFk".toLowerCase());
463 refId
= (Integer
)valueMap
.get("refId".toLowerCase());
464 Boolean thesisFlag
= (Boolean
)valueMap
.get("thesisFlag".toLowerCase());
467 Reference
<?
> referenceBase
;
468 logger
.debug("RefCategoryFk: " + categoryFk
);
471 referenceBase
= makeThesis(valueMap
);
472 }else if (categoryFk
== REF_JOURNAL
){
473 referenceBase
= makeJournal(valueMap
);
474 }else if(categoryFk
== REF_BOOK
){
475 referenceBase
= makeBook(valueMap
, biblioRefToSave
, nomRefToSave
, relatedBiblioReferences
, relatedNomReferences
);
476 }else if(categoryFk
== REF_DATABASE
){
477 referenceBase
= makeDatabase(valueMap
);
478 }else if(categoryFk
== REF_INFORMAL
){
479 referenceBase
= makeInformal(valueMap
);
480 }else if(categoryFk
== REF_WEBSITE
){
481 referenceBase
= makeWebSite(valueMap
);
482 }else if(categoryFk
== REF_UNKNOWN
){
483 referenceBase
= makeUnknown(valueMap
);
484 }else if(categoryFk
== REF_PRINT_SERIES
){
485 referenceBase
= makePrintSeries(valueMap
);
486 }else if(categoryFk
== REF_CONFERENCE_PROCEEDINGS
){
487 referenceBase
= makeProceedings(valueMap
);
488 }else if(categoryFk
== REF_ARTICLE
){
489 referenceBase
= makeArticle(valueMap
, biblioRefToSave
, nomRefToSave
, relatedBiblioReferences
, relatedNomReferences
);
490 }else if(categoryFk
== REF_JOURNAL_VOLUME
){
491 referenceBase
= makeJournalVolume(valueMap
);
492 }else if(categoryFk
== REF_PART_OF_OTHER_TITLE
){
493 referenceBase
= makePartOfOtherTitle(valueMap
, biblioRefToSave
, nomRefToSave
, relatedBiblioReferences
, relatedNomReferences
);
495 logger
.warn("Unknown categoryFk (" + categoryFk
+ "). Create 'Generic instead'");
496 referenceBase
= ReferenceFactory
.newGeneric();
501 String refYear
= (String
)valueMap
.get("refYear".toLowerCase());
502 referenceBase
.setDatePublished(ImportHelper
.getDatePublished(refYear
));
504 //created, updated, notes
505 doCreatedUpdatedNotes(state
, referenceBase
, rs
);
508 String idInSource
= (String
)valueMap
.get("IdInSource".toLowerCase());
509 if (isNotBlank(idInSource
)){
510 IdentifiableSource source
= IdentifiableSource
.NewDataImportInstance(idInSource
);
511 source
.setIdNamespace("import to Berlin Model");
512 referenceBase
.addSource(source
);
515 //nom&BiblioReference - must be last because a clone is created
516 success
&= makeNomAndBiblioReference(rs
, state
, partitioner
, refId
, referenceBase
, refCounter
,
517 biblioRefToSave
, nomRefToSave
);
520 } catch (Exception e
) {
521 logger
.warn("Reference with BM refId '" + CdmUtils
.Nz(refId
) + "' threw Exception and could not be saved");
530 * Creates and saves a nom. reference and a biblio. reference after checking necessity
533 * @param referenceBase
535 * @param biblioRefToSave
536 * @param nomRefToSave
540 * @throws SQLException
542 private boolean makeNomAndBiblioReference(
544 BerlinModelImportState state
,
545 ResultSetPartitioner partitioner
,
547 Reference
<?
> referenceBase
,
548 RefCounter refCounter
,
549 Map
<Integer
, Reference
> biblioRefToSave
,
550 Map
<Integer
, Reference
> nomRefToSave
551 ) throws SQLException
{
553 Map
<String
, Team
> teamMap
= partitioner
.getObjectMap(BerlinModelAuthorTeamImport
.NAMESPACE
);
555 String refCache
= rs
.getString("refCache");
556 String nomRefCache
= rs
.getString("nomRefCache");
557 String title
= rs
.getString("title");
558 String nomTitleAbbrev
= rs
.getString("nomTitleAbbrev");
559 boolean isPreliminary
= rs
.getBoolean("PreliminaryFlag");
560 String refAuthorString
= rs
.getString("refAuthorString");
561 Integer nomAuthorTeamFk
= rs
.getInt("NomAuthorTeamFk");
562 String strNomAuthorTeamFk
= String
.valueOf(nomAuthorTeamFk
);
563 TeamOrPersonBase
<?
> nomAuthor
= teamMap
.get(strNomAuthorTeamFk
);
564 Reference nomReference
= null;
566 boolean hasNomRef
= false;
567 boolean hasBiblioRef
= false;
568 Reference sourceReference
= state
.getTransactionalSourceReference();
570 //is Nomenclatural Reference
571 if ( (CdmUtils
.isNotEmpty(nomRefCache
) && isPreliminary
) || (CdmUtils
.isNotEmpty(nomTitleAbbrev
) && ! isPreliminary
) ){
572 referenceBase
.setTitle(nomTitleAbbrev
);
573 TeamOrPersonBase
<?
> author
= getAuthorTeam(refAuthorString
, nomAuthor
, true);
574 referenceBase
.setAuthorTeam(author
);
575 //referenceBase.setNomenclaturallyRelevant(true);
577 referenceBase
.setTitleCache(nomRefCache
, true);
579 if (! nomRefToSave
.containsKey(refId
)){
580 if (referenceBase
== null){
581 logger
.warn("refBase is null");
583 nomRefToSave
.put(refId
, referenceBase
);
585 logger
.warn("Duplicate refId in Berlin Model database. Second reference was not imported !!");
589 // nomRefToSave.put(refId, referenceBase);
591 nomReference
= referenceBase
;
592 refCounter
.nomRefCount
++;
594 //is bibliographical Reference
595 if ((CdmUtils
.isNotEmpty(refCache
) && isPreliminary
&& ! refCache
.equalsIgnoreCase(nomRefCache
))
596 || (CdmUtils
.isNotEmpty(title
) && ! isPreliminary
&& ! title
.equalsIgnoreCase(nomTitleAbbrev
))
597 || hasNomRef
== false){
599 referenceBase
= (Reference
)referenceBase
.clone();
600 copyCreatedUpdated(referenceBase
, nomReference
);
602 referenceBase
.setTitle(title
);
603 TeamOrPersonBase author
= getAuthorTeam(refAuthorString
, nomAuthor
, false);
604 referenceBase
.setAuthorTeam(author
);
605 referenceBase
.setNomenclaturallyRelevant(false);
607 referenceBase
.setTitleCache(refCache
, true);
609 if (! biblioRefToSave
.containsKey(refId
)){
610 biblioRefToSave
.put(refId
, referenceBase
);
612 logger
.warn("Duplicate refId in Berlin Model database. Second reference was not imported !!");
617 //biblioRefToSave.put(refId, referenceBase);
618 refCounter
.referenceCount
++;
622 ImportHelper
.setOriginalSource(nomReference
, sourceReference
, refId
, NOM_REFERENCE_NAMESPACE
);
625 ImportHelper
.setOriginalSource(referenceBase
, sourceReference
, refId
, BIBLIO_REFERENCE_NAMESPACE
);
633 * Copies the created and updated information from the nomReference to the cloned bibliographic reference
634 * @param referenceBase
635 * @param nomReference
637 private void copyCreatedUpdated(Reference
<?
> biblioReference
, Reference nomReference
) {
638 biblioReference
.setCreatedBy(nomReference
.getCreatedBy());
639 biblioReference
.setCreated(nomReference
.getCreated());
640 biblioReference
.setUpdatedBy(nomReference
.getUpdatedBy());
641 biblioReference
.setUpdated(nomReference
.getUpdated());
645 private Reference
<?
> makeArticle (Map
<String
, Object
> valueMap
, Map
<Integer
, Reference
> biblioRefToSave
, Map
<Integer
, Reference
> nomRefToSave
, Map
<String
, Reference
> relatedBiblioReferences
, Map
<String
, Reference
> relatedNomReferences
){
647 IArticle article
= ReferenceFactory
.newArticle();
648 Object inRefFk
= valueMap
.get("inRefFk".toLowerCase());
649 Integer inRefCategoryFk
= (Integer
)valueMap
.get("inRefCategoryFk".toLowerCase());
650 Integer refId
= (Integer
)valueMap
.get("refId".toLowerCase());
652 if (inRefFk
!= null){
653 if (inRefCategoryFk
!= REF_JOURNAL
){
654 logger
.warn("Wrong inrefCategory for Article (refID = " + refId
+"). Type must be 'Journal' but was not (RefCategoryFk=" + inRefCategoryFk
+ "))." +
655 " InReference was added anyway! ");
658 logger
.warn ("Article has no inreference: " + refId
);
660 makeStandardMapper(valueMap
, (Reference
)article
); //url, pages, series, volume
661 return (Reference
)article
;
664 private Reference
<?
> makePartOfOtherTitle (Map
<String
, Object
> valueMap
, Map
<Integer
, Reference
> biblioRefToSave
, Map
<Integer
, Reference
> nomRefToSave
, Map
<String
, Reference
> relatedBiblioReferences
, Map
<String
, Reference
> relatedNomReferences
){
666 Object inRefFk
= valueMap
.get("inRefFk".toLowerCase());
667 Integer inRefCategoryFk
= (Integer
)valueMap
.get("inRefCategoryFk".toLowerCase());
668 Integer refId
= (Integer
)valueMap
.get("refId".toLowerCase());
670 if (inRefCategoryFk
== null){
672 logger
.warn("Part-Of-Other-Title has no inRefCategoryFk! RefId = " + refId
+ ". ReferenceType set to Generic.");
673 result
= makeUnknown(valueMap
);
674 }else if (inRefFk
== null){
675 logger
.warn("Part-Of-Other-Title has in in reference: " + refId
);
676 result
= makeUnknown(valueMap
);
677 }else if (inRefCategoryFk
== REF_BOOK
){
679 IBookSection bookSection
= ReferenceFactory
.newBookSection();
680 result
= (Reference
<?
>)bookSection
;
681 }else if (inRefCategoryFk
== REF_ARTICLE
){
684 logger
.info("Reference (refId = " + refId
+ ") of type 'part_of_other_title' is part of 'article'." +
685 " There is no specific reference type for such in references yet. Generic reference created instead") ;
686 result
= ReferenceFactory
.newGeneric();
687 }else if (inRefCategoryFk
== REF_JOURNAL
){
689 logger
.warn("Reference (refId = " + refId
+ ") of type 'part_of_other_title' has inReference of type 'journal'." +
690 " This is not allowed! Generic reference created instead") ;
691 result
= ReferenceFactory
.newGeneric();
692 result
.addMarker(Marker
.NewInstance(MarkerType
.TO_BE_CHECKED(), true));
694 logger
.warn("InReference type (catFk = " + inRefCategoryFk
+ ") of part-of-reference not recognized for refId " + refId
+ "." +
695 " Create 'Generic' reference instead");
696 result
= ReferenceFactory
.newGeneric();
698 makeStandardMapper(valueMap
, result
); //url, pages
705 * @param biblioRefToSave
706 * @param nomRefToSave
707 * @param relatedBiblioReferences
708 * @param relatedNomReferences
711 private boolean existsInMapOrToSave(Integer inRefFkInt
, Map
<Integer
, Reference
> biblioRefToSave
, Map
<Integer
, Reference
> nomRefToSave
, Map
<String
, Reference
> relatedBiblioReferences
, Map
<String
, Reference
> relatedNomReferences
) {
712 boolean result
= false;
713 if (inRefFkInt
== null){
716 result
|= nomRefToSave
.containsKey(inRefFkInt
);
717 result
|= biblioRefToSave
.containsKey(inRefFkInt
);
718 result
|= relatedBiblioReferences
.containsKey(String
.valueOf(inRefFkInt
));
719 result
|= relatedNomReferences
.containsKey(String
.valueOf(inRefFkInt
));
723 private Reference
<?
> makeWebSite(Map
<String
, Object
> valueMap
){
724 if (logger
.isDebugEnabled()){logger
.debug("RefType 'Website'");}
725 Reference
<?
> webPage
= ReferenceFactory
.newWebPage();
726 makeStandardMapper(valueMap
, webPage
); //placePublished, publisher
730 private Reference
<?
> makeUnknown(Map
<String
, Object
> valueMap
){
731 if (logger
.isDebugEnabled()){logger
.debug("RefType 'Unknown'");}
732 Reference
<?
> generic
= ReferenceFactory
.newGeneric();
733 // generic.setSeries(series);
734 makeStandardMapper(valueMap
, generic
); //pages, placePublished, publisher, series, volume
738 private Reference
<?
> makeInformal(Map
<String
, Object
> valueMap
){
739 if (logger
.isDebugEnabled()){logger
.debug("RefType 'Informal'");}
740 Reference
<?
> generic
= ReferenceFactory
.newGeneric();
741 // informal.setSeries(series);
742 makeStandardMapper(valueMap
, generic
);//editor, pages, placePublished, publisher, series, volume
743 String informal
= (String
)valueMap
.get("InformalRefCategory".toLowerCase());
744 if (CdmUtils
.isNotEmpty(informal
) ){
745 generic
.addExtension(informal
, ExtensionType
.INFORMAL_CATEGORY());
750 private Reference
<?
> makeDatabase(Map
<String
, Object
> valueMap
){
751 if (logger
.isDebugEnabled()){logger
.debug("RefType 'Database'");}
752 Reference database
= ReferenceFactory
.newDatabase();
753 makeStandardMapper(valueMap
, database
); //?
757 private Reference
<?
> makeJournal(Map
<String
, Object
> valueMap
){
758 if (logger
.isDebugEnabled()){logger
.debug("RefType 'Journal'");}
759 Reference journal
= ReferenceFactory
.newJournal();
761 Set
<String
> omitAttributes
= new HashSet
<String
>();
762 String series
= "series";
763 // omitAttributes.add(series);
765 makeStandardMapper(valueMap
, journal
, omitAttributes
); //issn,placePublished,publisher
766 // if (valueMap.get(series) != null){
767 // logger.warn("Series not yet implemented for journal!");
772 private Reference
<?
> makeBook(
773 Map
<String
, Object
> valueMap
,
774 Map
<Integer
, Reference
> biblioRefToSave
,
775 Map
<Integer
, Reference
> nomRefToSave
,
776 Map
<String
, Reference
> relatedBiblioReferences
,
777 Map
<String
, Reference
> relatedNomReferences
){
778 if (logger
.isDebugEnabled()){logger
.debug("RefType 'Book'");}
779 Reference
<?
> book
= ReferenceFactory
.newBook();
780 Integer refId
= (Integer
)valueMap
.get("refId".toLowerCase());
782 //Set bookAttributes = new String[]{"edition", "isbn", "pages","publicationTown","publisher","volume"};
784 Set
<String
> omitAttributes
= new HashSet
<String
>();
785 String attrSeries
= "series";
786 // omitAttributes.add(attrSeries);
788 makeStandardMapper(valueMap
, book
, omitAttributes
);
791 IPrintSeries printSeries
= null;
792 if (valueMap
.get(attrSeries
) != null){
793 String series
= (String
)valueMap
.get("title".toLowerCase());
795 String nomTitle
= (String
)valueMap
.get("nomTitleAbbrev".toLowerCase());
798 printSeries
= ReferenceFactory
.newPrintSeries(series
);
799 logger
.info("Implementation of printSeries is preliminary");
801 Object inRefFk
= valueMap
.get("inRefFk".toLowerCase());
802 //Series (as Reference)
803 if (inRefFk
!= null && false){ //&&false added for first/second path implementation, following code may be removed if this is successful
804 int inRefFkInt
= (Integer
)inRefFk
;
805 if (existsInMapOrToSave(inRefFkInt
, biblioRefToSave
, nomRefToSave
, relatedBiblioReferences
, relatedNomReferences
)){
806 Reference
<?
> inSeries
= getReferenceFromMaps(inRefFkInt
, nomRefToSave
, relatedNomReferences
);
807 if (inSeries
== null){
808 inSeries
= getReferenceFromMaps(inRefFkInt
, biblioRefToSave
, relatedBiblioReferences
);
809 logger
.info("inSeries (" + inRefFkInt
+ ") found in referenceStore instead of nomRefStore.");
810 nomRefToSave
.put(inRefFkInt
, inSeries
);
812 if (inSeries
== null){
813 logger
.warn("inSeries for " + inRefFkInt
+ " is null. "+
814 " InReference relation could not be set");;
815 //}else if (PrintSeries.class.isAssignableFrom(inSeries.getClass())){
816 }else if (inSeries
.getType().equals(ReferenceType
.PrintSeries
)){
817 book
.setInSeries((IPrintSeries
)inSeries
);
820 logger
.warn("inSeries is not of type PrintSeries but of type " + inSeries
.getType().getMessage() +
821 ". In-reference relation could not be set for refId " + refId
+ " and inRefFk " + inRefFk
);
824 logger
.error("PrintSeries (refId = " + inRefFkInt
+ ") for book (refID = " + refId
+") could not be found in nomRefStore. Inconsistency error. ");
828 if (book
.getInSeries() != null && printSeries
!= null){
829 logger
.warn("Book has series string and inSeries reference. Can not take both. Series string neglected");
831 book
.setInSeries(printSeries
);
833 book
.setEditor(null);
839 * Returns the requested object if it exists in one of both maps. Prefers the refToSaveMap in ambigious cases.
841 * @param nomRefToSave
842 * @param relatedNomReferences
845 private Reference
<?
> getReferenceFromMaps(
847 Map
<Integer
, Reference
> refToSaveMap
,
848 Map
<String
, Reference
> relatedRefMap
) {
849 Reference
<?
> result
= null;
850 result
= refToSaveMap
.get(inRefFkInt
);
852 result
= relatedRefMap
.get(String
.valueOf(inRefFkInt
));
857 private Reference
<?
> makePrintSeries(Map
<String
, Object
> valueMap
){
858 if (logger
.isDebugEnabled()){logger
.debug("RefType 'PrintSeries'");}
859 Reference
<?
> printSeries
= ReferenceFactory
.newPrintSeries();
860 makeStandardMapper(valueMap
, printSeries
, null);
864 private Reference
<?
> makeProceedings(Map
<String
, Object
> valueMap
){
865 if (logger
.isDebugEnabled()){logger
.debug("RefType 'Proceedings'");}
866 Reference
<?
> proceedings
= ReferenceFactory
.newProceedings();
867 makeStandardMapper(valueMap
, proceedings
, null);
871 private Reference
<?
> makeThesis(Map
<String
, Object
> valueMap
){
872 if (logger
.isDebugEnabled()){logger
.debug("RefType 'Thesis'");}
873 Reference
<?
> thesis
= ReferenceFactory
.newThesis();
874 makeStandardMapper(valueMap
, thesis
, null);
879 private Reference
<?
> makeJournalVolume(Map
<String
, Object
> valueMap
){
880 if (logger
.isDebugEnabled()){logger
.debug("RefType 'JournalVolume'");}
881 //Proceedings proceedings = Proceedings.NewInstance();
882 Reference
<?
> journalVolume
= ReferenceFactory
.newGeneric();
883 makeStandardMapper(valueMap
, journalVolume
, null);
884 logger
.warn("Journal volumes not yet implemented. Generic created instead but with errors");
885 return journalVolume
;
888 private boolean makeStandardMapper(Map
<String
, Object
> valueMap
, Reference
<?
> ref
){
889 return makeStandardMapper(valueMap
, ref
, null);
893 private boolean makeStandardMapper(Map
<String
, Object
> valueMap
, CdmBase cdmBase
, Set
<String
> omitAttributes
){
894 boolean result
= true;
895 for (CdmAttributeMapperBase mapper
: classMappers
){
896 if (mapper
instanceof CdmSingleAttributeMapperBase
){
897 result
&= makeStandardSingleMapper(valueMap
, cdmBase
, (CdmSingleAttributeMapperBase
)mapper
, omitAttributes
);
898 }else if (mapper
instanceof CdmOneToManyMapper
){
899 result
&= makeMultipleValueAddMapper(valueMap
, cdmBase
, (CdmOneToManyMapper
)mapper
, omitAttributes
);
901 logger
.error("Unknown mapper type");
908 private boolean makeStandardSingleMapper(Map
<String
, Object
> valueMap
, CdmBase cdmBase
, CdmSingleAttributeMapperBase mapper
, Set
<String
> omitAttributes
){
909 boolean result
= true;
910 if (omitAttributes
== null){
911 omitAttributes
= new HashSet
<String
>();
913 if (mapper
instanceof DbImportExtensionMapper
){
914 result
&= ((DbImportExtensionMapper
)mapper
).invoke(valueMap
, cdmBase
);
915 }else if (mapper
instanceof DbImportMarkerMapper
){
916 result
&= ((DbImportMarkerMapper
)mapper
).invoke(valueMap
, cdmBase
);
918 String sourceAttribute
= mapper
.getSourceAttributeList().get(0).toLowerCase();
919 Object value
= valueMap
.get(sourceAttribute
);
920 if (mapper
instanceof CdmUriMapper
&& value
!= null){
922 value
= new URI (value
.toString());
923 } catch (URISyntaxException e
) {
924 logger
.error("URI syntax exception: " + value
.toString());
929 String destinationAttribute
= mapper
.getDestinationAttribute();
930 if (! omitAttributes
.contains(destinationAttribute
)){
931 result
&= ImportHelper
.addValue(value
, cdmBase
, destinationAttribute
, mapper
.getTypeClass(), OVERWRITE
, OBLIGATORY
);
939 private boolean makeMultipleValueAddMapper(Map
<String
, Object
> valueMap
, CdmBase cdmBase
, CdmOneToManyMapper
<CdmBase
, CdmBase
, CdmSingleAttributeMapperBase
> mapper
, Set
<String
> omitAttributes
){
940 if (omitAttributes
== null){
941 omitAttributes
= new HashSet
<String
>();
943 boolean result
= true;
944 String destinationAttribute
= mapper
.getSingleAttributeName();
945 List
<Object
> sourceValues
= new ArrayList
<Object
>();
946 List
<Class
> classes
= new ArrayList
<Class
>();
947 for (CdmSingleAttributeMapperBase singleMapper
: mapper
.getSingleMappers()){
948 String sourceAttribute
= singleMapper
.getSourceAttribute();
949 Object value
= valueMap
.get(sourceAttribute
);
950 sourceValues
.add(value
);
951 Class
<?
> clazz
= singleMapper
.getTypeClass();
955 result
&= ImportHelper
.addMultipleValues(sourceValues
, cdmBase
, destinationAttribute
, classes
, NO_OVERWRITE
, OBLIGATORY
);
956 // //only for testing
957 // if (cdmBase instanceof PublicationBase){
958 // PublicationBase pub = ((PublicationBase)cdmBase);
959 // pub.addPublisher("A new publisher for " + pub.getTitleCache(), "A nice place");
965 private static TeamOrPersonBase
<?
> getAuthorTeam(String authorString
, TeamOrPersonBase
<?
> nomAuthor
, boolean preferNomeclaturalAuthor
){
966 TeamOrPersonBase
<?
> result
;
967 if (preferNomeclaturalAuthor
){
968 if (nomAuthor
!= null){
971 if (CdmUtils
.isEmpty(authorString
)){
974 TeamOrPersonBase
<?
> team
= Team
.NewInstance();
975 //TODO which one to use??
976 team
.setNomenclaturalTitle(authorString
);
977 team
.setTitleCache(authorString
, true);
981 }else{ //prefer bibliographic
982 if (CdmUtils
.isNotEmpty(authorString
)){
983 TeamOrPersonBase
<?
> team
= Team
.NewInstance();
984 //TODO which one to use??
985 team
.setNomenclaturalTitle(authorString
);
986 team
.setTitleCache(authorString
, true);
1001 public Set
<String
> getObligatoryAttributes(boolean lowerCase
, BerlinModelImportConfigurator config
){
1002 Set
<String
> result
= new HashSet
<String
>();
1003 Class
<ICdmIO
>[] ioClassList
= config
.getIoClassList();
1004 logger
.warn("getObligatoryAttributes has been commented because it still needs to be adapted to the new package structure");
1005 result
.addAll(Arrays
.asList(unclearMappers
));
1006 result
.addAll(Arrays
.asList(createdAndNotesAttributes
));
1007 result
.addAll(Arrays
.asList(operationalAttributes
));
1008 CdmIoMapping mapping
= new CdmIoMapping();
1009 for (CdmAttributeMapperBase mapper
: classMappers
){
1010 mapping
.addMapper(mapper
);
1012 result
.addAll(mapping
.getSourceAttributes());
1014 Set
<String
> lowerCaseResult
= new HashSet
<String
>();
1015 for (String str
: result
){
1016 if (str
!= null){lowerCaseResult
.add(str
.toLowerCase());}
1018 result
= lowerCaseResult
;
1024 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#doCheck(eu.etaxonomy.cdm.io.common.IoStateBase)
1027 protected boolean doCheck(BerlinModelImportState state
){
1028 BerlinModelReferenceImportValidator validator
= new BerlinModelReferenceImportValidator();
1029 return validator
.validate(state
, this);
1034 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#isIgnore(eu.etaxonomy.cdm.io.common.IImportConfigurator)
1036 protected boolean isIgnore(BerlinModelImportState state
){
1037 return (state
.getConfig().getDoReferences() == IImportConfigurator
.DO_REFERENCES
.NONE
);