adapt app-import to v5.45
[cdmlib-apps.git] / cdm-pesi / src / main / java / eu / etaxonomy / cdm / io / pesi / erms / ErmsTaxonRelationImport.java
1 /**
2 * Copyright (C) 2007 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
10 package eu.etaxonomy.cdm.io.pesi.erms;
11
12 import java.sql.ResultSet;
13 import java.sql.SQLException;
14 import java.util.HashMap;
15 import java.util.HashSet;
16 import java.util.Map;
17 import java.util.Set;
18
19 import org.apache.logging.log4j.LogManager;
20 import org.apache.logging.log4j.Logger;
21 import org.springframework.stereotype.Component;
22
23 import eu.etaxonomy.cdm.io.common.mapping.DbImportMapping;
24 import eu.etaxonomy.cdm.io.common.mapping.DbImportNameTypeDesignationMapper;
25 import eu.etaxonomy.cdm.io.common.mapping.DbImportSynonymMapper;
26 import eu.etaxonomy.cdm.io.common.mapping.DbImportTaxIncludedInMapper;
27 import eu.etaxonomy.cdm.io.common.mapping.ICheckIgnoreMapper;
28 import eu.etaxonomy.cdm.io.common.mapping.IDbImportMapper;
29 import eu.etaxonomy.cdm.model.common.CdmBase;
30 import eu.etaxonomy.cdm.model.name.TaxonName;
31 import eu.etaxonomy.cdm.model.taxon.TaxonBase;
32
33 /**
34 * @author a.mueller
35 * @since 09.03.2010
36 */
37 @Component
38 public class ErmsTaxonRelationImport extends ErmsImportBase<TaxonBase<?>> implements ICheckIgnoreMapper{
39
40 private static final long serialVersionUID = 4092728796922591257L;
41
42 @SuppressWarnings("unused")
43 private static Logger logger = LogManager.getLogger();
44
45 private DbImportMapping<ErmsImportState, ErmsImportConfigurator> mapping;
46
47 private static final String pluralString = "taxon relations";
48 private static final String dbTableName = "tu";
49
50 private static final Class<?> cdmTargetClass = TaxonBase.class;
51
52 @Override
53 protected int divideCountBy() { return 5;} //use only 1000 records
54
55 public ErmsTaxonRelationImport(){
56 super(pluralString, dbTableName, cdmTargetClass);
57 }
58
59 @Override
60 protected DbImportMapping<ErmsImportState, ErmsImportConfigurator> getMapping() {
61 if (mapping == null){
62 mapping = new DbImportMapping<>();
63 //incldued in
64 DbImportTaxIncludedInMapper<?> includedIn
65 = DbImportTaxIncludedInMapper.NewInstance("id", TAXON_NAMESPACE, "accId", TAXON_NAMESPACE,
66 "parentAccId", TAXON_NAMESPACE, null);
67 mapping.addMapper(includedIn);//there is only one tree
68 //synonym
69 mapping.addMapper(DbImportSynonymMapper.NewInstance("id", "tu_accfinal", TAXON_NAMESPACE,
70 "tu_unacceptreason", null, null, true));
71 //type designations
72 mapping.addMapper(DbImportNameTypeDesignationMapper.NewInstance("id", "tu_typetaxon", ErmsImportBase.NAME_NAMESPACE, "tu_typedesignationstatus"));
73 }
74 return mapping;
75 }
76
77 @Override
78 protected String getIdQuery(){
79 String result = " SELECT id FROM " + getTableName() +
80 " ORDER BY tu_sp";
81 return result;
82 }
83
84 @Override
85 protected String getRecordQuery(ErmsImportConfigurator config) {
86 //TODO get automatic by second path mappers
87 String selectAttributes =
88 " myTaxon.id, myTaxon.tu_parent, myTaxon.tu_typetaxon, myTaxon.tu_typedesignation, "
89 + " myTaxon.tu_accfinal, myTaxon.tu_status, myTaxon.tu_unacceptreason, "
90 + " parent.tu_status AS parentStatus, parent.id AS parentId, "
91 + " parentAcc.id AS parentAccId,"
92 + " accTaxon.tu_parent accParentId, "
93 + " CASE WHEN myTaxon.id = parentAcc.id THEN parent.id ELSE ISNULL(parentAcc.id, parent.id) END as accId ";
94 String strRecordQuery =
95 " SELECT " + selectAttributes
96 + " FROM tu AS myTaxon "
97 + " LEFT JOIN tu AS accTaxon ON myTaxon.tu_accfinal = accTaxon.id "
98 + " LEFT JOIN tu AS parent ON myTaxon.tu_parent = parent.id "
99 + " LEFT JOIN tu AS parentAcc ON parentAcc.id = parent.tu_accfinal "
100 + " WHERE ( myTaxon.id IN (" + ID_LIST_TOKEN + ") )";
101 return strRecordQuery;
102 }
103
104 @Override
105 protected void doInvoke(ErmsImportState state) {
106 super.doInvoke(state);
107 }
108
109 @Override
110 public Map<Object, Map<String, ? extends CdmBase>> getRelatedObjectsForPartition(ResultSet rs, ErmsImportState state) {
111
112 String nameSpace;
113 Set<String> idSet;
114 Map<Object, Map<String, ? extends CdmBase>> result = new HashMap<>();
115
116 try{
117 Set<String> taxonIdSet = new HashSet<>();
118 Set<String> nameIdSet = new HashSet<>();
119 while (rs.next()){
120 handleForeignKey(rs, taxonIdSet, "accId");
121 handleForeignKey(rs, taxonIdSet, "tu_accfinal");
122 handleForeignKey(rs, taxonIdSet, "id");
123 handleForeignKey(rs, nameIdSet, "tu_typetaxon");
124 handleForeignKey(rs, nameIdSet, "id");
125 }
126
127 //name map
128 nameSpace = ErmsImportBase.NAME_NAMESPACE;
129 idSet = nameIdSet;
130 Map<String, TaxonName> nameMap = getCommonService().getSourcedObjectsByIdInSourceC(TaxonName.class, idSet, nameSpace);
131 result.put(nameSpace, nameMap);
132
133 //taxon map
134 nameSpace = ErmsImportBase.TAXON_NAMESPACE;
135 idSet = taxonIdSet;
136 @SuppressWarnings("rawtypes")
137 Map<String, TaxonBase> taxonMap = getCommonService().getSourcedObjectsByIdInSourceC(TaxonBase.class, idSet, nameSpace);
138 result.put(nameSpace, taxonMap);
139
140 return result;
141
142 } catch (SQLException e) {
143 throw new RuntimeException(e);
144 }
145 }
146
147 @Override
148 public boolean checkIgnoreMapper(@SuppressWarnings("rawtypes") IDbImportMapper mapper, ResultSet rs) throws SQLException{
149
150 boolean result = false;
151 boolean isAccepted = isAccepted(rs);
152
153 if (mapper instanceof DbImportTaxIncludedInMapper){
154 //here we should add the direct parent or the accepted taxon of the parent
155 return !isAccepted;
156 }else if (mapper instanceof DbImportSynonymMapper){
157 //the only exact rule in ERMS is that the accepted taxon (tu_accfinal)
158 // of a synonym (def: id <> tu_accfinal) never again has another
159 // accepted taxon.
160 //So the synonym relation is clearly defined, no matter which status
161 //both related taxa have.
162 //TODO: check if data were only adapted by BGBM this way
163 return isAccepted;
164 }else if (mapper instanceof DbImportNameTypeDesignationMapper){
165 Object tu_typeTaxon = rs.getObject("tu_typetaxon");
166 if (tu_typeTaxon == null){
167 return true;
168 }
169 }
170 return result;
171 }
172
173 private boolean isAccepted(ResultSet rs) throws SQLException {
174 int id = rs.getInt("id");
175 Object accTaxonId = rs.getObject("tu_accfinal");
176 Object accParentId = rs.getObject("accParentId");
177
178 boolean isAccepted = false;
179 if(accTaxonId == null){
180 isAccepted = true; //if accTaxonId == null we can only assume this taxon is accepted as we have no other accepted taxon, though in most cases the status is not accepted
181 }else if (id == (int)accTaxonId){
182 isAccepted = true;
183 }else if (accParentId != null && id == (int)accParentId){
184 //see also ErmsTaxonImport.getAcceptedTaxaKeys, there with accepted taxon (alternate representation) being there own child. These should be fully accepted as other wise the link to the higher taxon (genus) is not given
185 isAccepted = true;
186 }
187 return isAccepted;
188 }
189
190 @Override
191 protected boolean doCheck(ErmsImportState state){
192 // IOValidator<ErmsImportState> validator = new ErmsTaxonImportValidator();
193 // return validator.validate(state);
194 return true;
195 }
196
197 @Override
198 protected boolean isIgnore(ErmsImportState state){
199 return ! state.getConfig().isDoRelTaxa();
200 }
201 }