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.
9 package eu
.etaxonomy
.cdm
.io
.common
.mapping
;
11 import java
.sql
.ResultSet
;
12 import java
.sql
.SQLException
;
14 import org
.apache
.commons
.lang3
.StringUtils
;
15 import org
.apache
.logging
.log4j
.LogManager
;
16 import org
.apache
.logging
.log4j
.Logger
;
18 import eu
.etaxonomy
.cdm
.io
.common
.DbImportStateBase
;
19 import eu
.etaxonomy
.cdm
.io
.common
.ICdmIO
;
20 import eu
.etaxonomy
.cdm
.model
.common
.AnnotatableEntity
;
21 import eu
.etaxonomy
.cdm
.model
.common
.Annotation
;
22 import eu
.etaxonomy
.cdm
.model
.common
.CdmBase
;
23 import eu
.etaxonomy
.cdm
.model
.common
.IRelationshipType
;
24 import eu
.etaxonomy
.cdm
.model
.common
.Language
;
25 import eu
.etaxonomy
.cdm
.model
.name
.HybridRelationshipType
;
26 import eu
.etaxonomy
.cdm
.model
.name
.NameRelationshipType
;
27 import eu
.etaxonomy
.cdm
.model
.reference
.Reference
;
28 import eu
.etaxonomy
.cdm
.model
.taxon
.Synonym
;
29 import eu
.etaxonomy
.cdm
.model
.taxon
.SynonymType
;
30 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
31 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonBase
;
32 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonRelationshipType
;
35 * A mapper that can be used to create synonym relationships for real synonyms with a {@link SynonymType},
36 * synonyms relationships that are handled as concept relationships if the synonym needs to be handled
37 * as accepted taxon (misapplied names, pro parte synonyms, synonyms with attached factual data, ...)
38 * and even synonym relationships which in reality are only name relationships.
39 * The mapping is defined in the transformer.
44 * @see DbImportTaxIncludedInMapper
46 public class DbImportSynonymMapper
<STATE
extends DbImportStateBase
<?
,?
>>
47 extends DbImportMultiAttributeMapperBase
<CdmBase
, STATE
> {
49 private static final Logger logger
= LogManager
.getLogger();
51 //******************************* ATTRIBUTES ***************************************/
53 private String fromAttribute
;
54 private String toAttribute
;
55 private TaxonRelationshipType taxonRelType
;
56 private SynonymType synType
;
57 private String relatedObjectNamespace
;
58 private String citationAttribute
;
59 private String microCitationAttribute
;
60 private String relationshipTypeAttribute
;
61 boolean forceTaxonLevelRelation
= true;
62 boolean saveSourceValueAsAnnotation
;
64 //******************************** FACTORY METHOD ***************************************************/
67 * Creates a new instance of SynonymMapper.
68 * @param dbFromAttribute
69 * @param dbToAttribute
70 * @param relatedObjectNamespace
71 * @param relTypeAttribute the attribute in the source DB to compute the relationship type(s) from
72 * @param defaultTaxonRelationshipType this relationship type is taken for accepted taxa
73 * being synonyms (may be the case if data are dirty)
76 public static DbImportSynonymMapper
<?
> NewInstance(String dbFromAttribute
, String dbToAttribute
,
77 String relatedObjectTaxonNamespace
, String relTypeAttribute
, SynonymType defaultSynonymType
,
78 TaxonRelationshipType defaultTaxonRelationshipType
, boolean saveSourceValueAsAnnotation
){
79 return new DbImportSynonymMapper
<>(dbFromAttribute
, dbToAttribute
, defaultSynonymType
, defaultTaxonRelationshipType
, relatedObjectTaxonNamespace
, relTypeAttribute
, saveSourceValueAsAnnotation
);
82 //********************************* CONSTRUCTOR ****************************************/
84 protected DbImportSynonymMapper(String fromAttribute
, String toAttribute
, SynonymType synType
,
85 TaxonRelationshipType relType
, String relatedObjectNamespace
, String relTypeAttribute
86 , boolean saveSourceValueAsAnnotation
) {
87 //TODO make it a single attribute mapper (?)
88 this.fromAttribute
= fromAttribute
;
89 this.toAttribute
= toAttribute
;
90 this.taxonRelType
= relType
;
91 this.synType
= synType
;
92 this.relatedObjectNamespace
= relatedObjectNamespace
;
93 this.relationshipTypeAttribute
= relTypeAttribute
;
94 this.saveSourceValueAsAnnotation
= saveSourceValueAsAnnotation
;
97 //************************************ METHODS *******************************************/
100 public CdmBase
invoke(ResultSet rs
, CdmBase cdmBase
) throws SQLException
{
101 STATE state
= getState();
102 ICdmIO
<?
> currentImport
= state
.getCurrentIO();
103 if (currentImport
instanceof ICheckIgnoreMapper
){
104 boolean ignoreRecord
= ((ICheckIgnoreMapper
)currentImport
).checkIgnoreMapper(this, rs
);
110 TaxonBase
<?
> fromObject
= (TaxonBase
<?
>)getRelatedObject(rs
, fromAttribute
);
111 TaxonBase
<?
> toObject
= (TaxonBase
<?
>)getRelatedObject(rs
, toAttribute
);
112 String fromId
= rs
.getObject(fromAttribute
)== null ?
null: String
.valueOf(rs
.getObject(fromAttribute
));
113 String toId
= rs
.getObject(toAttribute
) == null?
null : String
.valueOf(rs
.getObject(toAttribute
));
119 Reference citation
= CdmBase
.deproxy(getRelatedObject(rs
, citationAttribute
), Reference
.class);
120 String microCitation
= null;
121 if (citationAttribute
!= null){
122 microCitation
= rs
.getString(microCitationAttribute
);
124 SynonymType synType
= this.synType
;
125 NameRelationshipType nameType
= null;
126 HybridRelationshipType hybridType
= null;
127 TaxonRelationshipType taxonRelType
= this.taxonRelType
;
129 String relTypeAttrValue
= null;
130 if (relationshipTypeAttribute
!= null){
131 relTypeAttrValue
= rs
.getString(relationshipTypeAttribute
);
132 IRelationshipType
[] relTypes
= this.getState().getTransformer().getSynonymRelationTypesByKey(relTypeAttrValue
, state
);
133 if (relTypes
[0]!= null){
134 synType
= (SynonymType
)relTypes
[0];
136 if (relTypes
[1]!=null){
137 taxonRelType
= (TaxonRelationshipType
)relTypes
[1];
139 nameType
= (NameRelationshipType
)relTypes
[2];
140 hybridType
= (HybridRelationshipType
)relTypes
[3];
143 if (fromObject
== null){
144 String warning
= "The synonym (" + fromId
+ ") could not be found. Synonym not added to accepted taxon";
145 logger
.warn(warning
);
148 checkSynonymType(fromObject
, fromId
, taxonRelType
);
150 if (toObject
== null){
151 String warning
= "The accepted taxon (" + toId
+ ") could not be found. Synonym not added to accepted taxon";
152 logger
.warn(warning
);
155 Taxon taxon
= checkTaxonType(toObject
, "Accepted taxon", toId
);
157 if(forceTaxonLevelRelation
&& synType
== null){
158 synType
= SynonymType
.SYNONYM_OF
;
161 AnnotatableEntity
[] result
= new AnnotatableEntity
[4];
162 if (fromObject
.isInstanceOf(Synonym
.class) && synType
!= null){
163 Synonym synonym
= CdmBase
.deproxy(fromObject
, Synonym
.class);
164 taxon
.addSynonym(synonym
, synType
); //citation and micro citation not in use anymore as we do not have synonym relationships anymore
166 }else if (fromObject
.isInstanceOf(Taxon
.class) && taxonRelType
!= null){
167 TaxonRelationshipType type
= taxonRelType
;
168 Taxon synonymTaxon
= CdmBase
.deproxy(fromObject
, Taxon
.class);
169 result
[1] = synonymTaxon
.addTaxonRelation(taxon
, type
, citation
, microCitation
);
171 if (forceTaxonLevelRelation
){
172 String message
= "Taxon is not a synonym and accepted taxa are not allowed as synonyms: " + fromObject
.getTitleCache() + "; " + fromObject
.getId();
173 logger
.warn(message
);
176 if(nameType
!= null){
177 result
[2] = fromObject
.getName().addRelationshipToName(toObject
.getName(), nameType
, citation
, microCitation
, null, null);
179 if(hybridType
!= null){
180 result
[3] = fromObject
.getName().addHybridParent(toObject
.getName(), hybridType
, citation
, microCitation
, null, null);
182 if (saveSourceValueAsAnnotation
&& StringUtils
.isNotBlank(relTypeAttrValue
)){
183 for (AnnotatableEntity a
: result
){
185 a
.addAnnotation(Annotation
.NewInstance(relTypeAttrValue
, Language
.UNKNOWN_LANGUAGE()));
194 * //TODO copied from DbImportObjectMapper. Maybe these can be merged again in future
196 protected CdmBase
getRelatedObject(ResultSet rs
, String dbAttribute
) throws SQLException
{
197 CdmBase result
= null;
198 if (dbAttribute
!= null){
199 Object dbValue
= rs
.getObject(dbAttribute
);
200 String id
= String
.valueOf(dbValue
);
201 DbImportStateBase
<?
,?
> state
= importMapperHelper
.getState();
202 result
= state
.getRelatedObject(relatedObjectNamespace
, id
);
208 * Checks if cdmBase is of type Taxon
210 private Taxon
checkTaxonType(TaxonBase
<?
> taxonBase
, String typeString
, String id
) {
211 if (! taxonBase
.isInstanceOf(Taxon
.class)){
212 String warning
= typeString
+ " (" + id
+ ") is not of type Taxon but of type " + taxonBase
.getClass().getSimpleName();
213 logger
.warn(warning
);
214 throw new IllegalArgumentException(warning
);
216 return (CdmBase
.deproxy(taxonBase
, Taxon
.class));
220 * Checks if cdmBase is of type Synonym
222 private TaxonBase
<?
> checkSynonymType(CdmBase cdmBase
, String id
, TaxonRelationshipType taxonRelType
) {
223 if (! cdmBase
.isInstanceOf(Synonym
.class)){
224 String warning
= "Synonym (" + id
+ ") is not of type Synonym but of type " + cdmBase
.getClass().getSimpleName();
225 if (taxonRelType
== null){
226 logger
.warn(warning
);
227 throw new IllegalArgumentException(warning
);
229 logger
.info(warning
);
232 return (CdmBase
.deproxy(cdmBase
, TaxonBase
.class));