is homotypic name relation for BerlinModel Export
[cdmlib.git] / cdmlib-io / src / main / java / eu / etaxonomy / cdm / io / berlinModel / in / BerlinModelTaxonRelationImport.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.berlinModel.in;
11
12 import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.TAX_REL_IS_HETEROTYPIC_SYNONYM_OF;
13 import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.TAX_REL_IS_HOMOTYPIC_SYNONYM_OF;
14 import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.TAX_REL_IS_INCLUDED_IN;
15 import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.TAX_REL_IS_MISAPPLIED_NAME_OF;
16 import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.TAX_REL_IS_PARTIAL_HETEROTYPIC_SYNONYM_OF;
17 import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.TAX_REL_IS_PARTIAL_HOMOTYPIC_SYNONYM_OF;
18 import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.TAX_REL_IS_PARTIAL_SYN_OF;
19 import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.TAX_REL_IS_PROPARTE_HETEROTYPIC_SYNONYM_OF;
20 import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.TAX_REL_IS_PROPARTE_HOMOTYPIC_SYNONYM_OF;
21 import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.TAX_REL_IS_PROPARTE_SYN_OF;
22 import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.TAX_REL_IS_SYNONYM_OF;
23
24 import java.sql.ResultSet;
25 import java.sql.SQLException;
26 import java.util.HashSet;
27 import java.util.Set;
28 import java.util.UUID;
29
30 import org.apache.log4j.Logger;
31 import org.springframework.stereotype.Component;
32
33 import eu.etaxonomy.cdm.common.CdmUtils;
34 import eu.etaxonomy.cdm.common.ResultWrapper;
35 import eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer;
36 import eu.etaxonomy.cdm.io.common.ICdmIO;
37 import eu.etaxonomy.cdm.io.common.IImportConfigurator;
38 import eu.etaxonomy.cdm.io.common.MapWrapper;
39 import eu.etaxonomy.cdm.io.common.Source;
40 import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
41 import eu.etaxonomy.cdm.model.common.CdmBase;
42 import eu.etaxonomy.cdm.model.name.TaxonNameBase;
43 import eu.etaxonomy.cdm.model.reference.ReferenceBase;
44 import eu.etaxonomy.cdm.model.reference.StrictReferenceBase;
45 import eu.etaxonomy.cdm.model.taxon.Synonym;
46 import eu.etaxonomy.cdm.model.taxon.SynonymRelationship;
47 import eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType;
48 import eu.etaxonomy.cdm.model.taxon.Taxon;
49 import eu.etaxonomy.cdm.model.taxon.TaxonBase;
50 import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;
51 import eu.etaxonomy.cdm.model.taxon.TaxonomicTree;
52 import eu.etaxonomy.cdm.strategy.exceptions.UnknownCdmTypeException;
53
54 /**
55 * @author a.mueller
56 * @created 20.03.2008
57 * @version 1.0
58 */
59 @Component
60 public class BerlinModelTaxonRelationImport extends BerlinModelImportBase {
61 private static final Logger logger = Logger.getLogger(BerlinModelTaxonRelationImport.class);
62
63 private static int modCount = 30000;
64
65 public BerlinModelTaxonRelationImport(){
66 super();
67 }
68
69 /* (non-Javadoc)
70 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#doCheck(eu.etaxonomy.cdm.io.common.IImportConfigurator)
71 */
72 @Override
73 protected boolean doCheck(IImportConfigurator config){
74 boolean result = true;
75 BerlinModelImportConfigurator bmiConfig = (BerlinModelImportConfigurator)config;
76 logger.warn("Checking for TaxonRelations not yet fully implemented");
77 result &= checkInActivatedStatus(bmiConfig);
78 //result &= checkArticlesWithoutJournal(bmiConfig);
79
80 return result;
81 }
82
83 private boolean checkInActivatedStatus(BerlinModelImportConfigurator bmiConfig){
84 try {
85 boolean result = true;
86 Source source = bmiConfig.getSource();
87 String strSQL =
88 " SELECT RelPTaxon.RelPTaxonId, RelPTaxon.RelQualifierFk, FromName.FullNameCache AS FromName, RelPTaxon.PTNameFk1 AS FromNameID, " +
89 " Status.Status AS FromStatus, ToName.FullNameCache AS ToName, RelPTaxon.PTNameFk2 AS ToNameId, ToStatus.Status AS ToStatus " +
90 " FROM PTaxon AS FromTaxon " +
91 " INNER JOIN RelPTaxon ON FromTaxon.PTNameFk = RelPTaxon.PTNameFk1 AND FromTaxon.PTRefFk = RelPTaxon.PTRefFk1 " +
92 " INNER JOIN PTaxon AS ToTaxon ON RelPTaxon.PTNameFk2 = ToTaxon.PTNameFk AND RelPTaxon.PTRefFk2 = ToTaxon.PTRefFk " +
93 " INNER JOIN Name AS ToName ON ToTaxon.PTNameFk = ToName.NameId " +
94 " INNER JOIN Name AS FromName ON FromTaxon.PTNameFk = FromName.NameId " +
95 " INNER JOIN Status ON FromTaxon.StatusFk = Status.StatusId AND FromTaxon.StatusFk = Status.StatusId " +
96 " INNER JOIN Status AS ToStatus ON ToTaxon.StatusFk = ToStatus.StatusId AND ToTaxon.StatusFk = ToStatus.StatusId " +
97 " WHERE (RelPTaxon.RelQualifierFk = - 99)";
98
99 ResultSet rs = source.getResultSet(strSQL);
100 boolean firstRow = true;
101 int i = 0;
102 while (rs.next()){
103 i++;
104 if (firstRow){
105 System.out.println("========================================================");
106 logger.warn("There are TaxonRelationships with status 'inactivated'(-99)!");
107 System.out.println("========================================================");
108 }
109
110 int relPTaxonId = rs.getInt("RelPTaxonId");
111 String fromName = rs.getString("FromName");
112 int fromNameID = rs.getInt("FromNameID");
113 String fromStatus = rs.getString("FromStatus");
114
115 String toName = rs.getString("ToName");
116 int toNameId = rs.getInt("ToNameId");
117 String toStatus = rs.getString("ToStatus");
118
119 System.out.println("RelPTaxonId:" + relPTaxonId +
120 "\n FromName: " + fromName + "\n FromNameID: " + fromNameID + "\n FromStatus: " + fromStatus +
121 "\n ToName: " + toName + "\n ToNameId: " + toNameId + "\n ToStatus: " + toStatus);
122 result = firstRow = false;
123 }
124 if (i > 0){
125 System.out.println(" ");
126 }
127
128 return result;
129 } catch (SQLException e) {
130 e.printStackTrace();
131 return false;
132 }
133 }
134
135
136 private boolean makeTaxonomicTrees(BerlinModelImportState state) throws SQLException{
137 MapWrapper<ReferenceBase> referenceMap = (MapWrapper<ReferenceBase>)state.getStore(ICdmIO.REFERENCE_STORE);
138 MapWrapper<ReferenceBase> nomRefMap = (MapWrapper<ReferenceBase>)state.getStore(ICdmIO.NOMREF_STORE);
139 Source source = state.getConfig().getSource();
140
141 logger.info("start makeTaxonomicTree ...");
142
143 String strQuery = "SELECT PTaxon.PTRefFk " +
144 " FROM RelPTaxon INNER JOIN " +
145 " PTaxon AS PTaxon ON RelPTaxon.PTNameFk2 = PTaxon.PTNameFk AND RelPTaxon.PTRefFk2 = PTaxon.PTRefFk " +
146 " WHERE (RelPTaxon.RelQualifierFk = 1) " +
147 " GROUP BY PTaxon.PTRefFk ";
148 ResultSet rs = source.getResultSet(strQuery) ;
149 int i = 0;
150 //for each reference
151 try {
152 while (rs.next()){
153
154 if ((i++ % modCount) == 0 && i!= 1 ){ logger.info("RelPTaxa handled: " + (i-1));}
155
156 int ptRefFk = rs.getInt("PTRefFk");
157
158 StrictReferenceBase ref = (StrictReferenceBase)referenceMap.get(ptRefFk);
159 if (ref == null){
160 ref = (StrictReferenceBase)nomRefMap.get(ptRefFk);
161 }
162 //FIXME treeName
163 String treeName = "TaxonTree - No Name";
164 if (ref != null && CdmUtils.isNotEmpty(ref.getTitleCache())){
165 treeName = ref.getTitleCache();
166 }
167 TaxonomicTree tree = TaxonomicTree.NewInstance(treeName);
168 tree.setReference(ref);
169
170 UUID uuid = getTaxonService().saveTaxonomicTree(tree);
171 state.putTree(ref, tree);
172 }
173 } catch (SQLException e) {
174 logger.error("Error in BerlinModleTaxonRelationImport.makeTaxonomicTrees: " + e.getMessage());
175 throw e;
176 }
177 logger.info("end makeTaxonomicTree ...");
178
179 return true;
180 }
181
182
183
184 /* (non-Javadoc)
185 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#doInvoke(eu.etaxonomy.cdm.io.common.IImportConfigurator, eu.etaxonomy.cdm.api.application.CdmApplicationController, java.util.Map)
186 */
187 @Override
188 protected boolean doInvoke(BerlinModelImportState state){
189 boolean success = true;
190 //make not needed maps empty
191 MapWrapper<TaxonNameBase> taxonNameMap = (MapWrapper<TaxonNameBase>)state.getStore(ICdmIO.TAXONNAME_STORE);
192 taxonNameMap.makeEmpty();
193
194 String strTeamStore = ICdmIO.TEAM_STORE;
195 MapWrapper<? extends CdmBase> map = state.getStore(strTeamStore);
196 MapWrapper<TeamOrPersonBase> teamMap = (MapWrapper<TeamOrPersonBase>)map;
197 teamMap.makeEmpty();
198
199 MapWrapper<ReferenceBase> referenceMap = (MapWrapper<ReferenceBase>)state.getStore(ICdmIO.REFERENCE_STORE);
200 MapWrapper<ReferenceBase> nomRefMap = (MapWrapper<ReferenceBase>)state.getStore(ICdmIO.NOMREF_STORE);
201 MapWrapper<ReferenceBase> nomRefDetailMap = (MapWrapper<ReferenceBase>)state.getStore(ICdmIO.NOMREF_DETAIL_STORE);
202 MapWrapper<TaxonBase> taxonMap = (MapWrapper<TaxonBase>)state.getStore(ICdmIO.TAXON_STORE);
203
204 Set<TaxonBase> taxonStore = new HashSet<TaxonBase>();
205 BerlinModelImportConfigurator config = state.getConfig();
206 Source source = config.getSource();
207
208 try {
209 if (config.isUseTaxonomicTree()){
210 success &= makeTaxonomicTrees(state);
211 }
212
213
214 logger.info("start makeTaxonRelationships ...");
215
216 //get data from database
217 String strQuery =
218 " SELECT RelPTaxon.*, FromTaxon.RIdentifier as taxon1Id, ToTaxon.RIdentifier as taxon2Id, q.is_concept_relation " +
219 " FROM PTaxon as FromTaxon INNER JOIN " +
220 " RelPTaxon ON FromTaxon.PTNameFk = RelPTaxon.PTNameFk1 AND FromTaxon.PTRefFk = RelPTaxon.PTRefFk1 INNER JOIN " +
221 " PTaxon AS ToTaxon ON RelPTaxon.PTNameFk2 = ToTaxon.PTNameFk AND RelPTaxon.PTRefFk2 = ToTaxon.PTRefFk " +
222 " INNER JOIN RelPTQualifier q ON q.RelPTQualifierId = RelPTaxon.RelQualifierFk " +
223 " WHERE (1=1)";
224 ResultSet rs = source.getResultSet(strQuery) ;
225
226 int i = 0;
227 //for each reference
228 while (rs.next()){
229
230 if ((i++ % modCount) == 0 && i!= 1 ){ logger.info("RelPTaxa handled: " + (i-1));}
231
232 int relPTaxonId = rs.getInt("RelPTaxonId");
233 int taxon1Id = rs.getInt("taxon1Id");
234 int taxon2Id = rs.getInt("taxon2Id");
235 int relRefFk = rs.getInt("relRefFk");
236 int relQualifierFk = rs.getInt("relQualifierFk");
237 boolean isConceptRelationship = rs.getBoolean("is_concept_relation");
238
239 TaxonBase taxon1 = taxonMap.get(taxon1Id);
240 TaxonBase taxon2 = taxonMap.get(taxon2Id);
241
242 //TODO
243 ReferenceBase citation = nomRefDetailMap.get(relRefFk);
244 if (citation == null){
245 citation = referenceMap.get(relRefFk);
246 }
247 if (citation == null){
248 citation = nomRefMap.get(relRefFk);
249 }
250
251 String microcitation = null; //does not exist in RelPTaxon
252
253 if (taxon2 != null && taxon1 != null){
254 if (!(taxon2 instanceof Taxon)){
255 logger.error("TaxonBase (ID = " + taxon2.getId()+ ", RIdentifier = " + taxon2Id + ") can't be casted to Taxon");
256 success = false;
257 continue;
258 }
259 Taxon toTaxon = (Taxon)taxon2;
260 if (isTaxonRelationship(relQualifierFk)){
261 if (!(taxon1 instanceof Taxon)){
262 logger.error("TaxonBase (ID = " + taxon1.getId()+ ", RIdentifier = " + taxon1Id + ") can't be casted to Taxon");
263 success = false;
264 continue;
265 }
266 Taxon fromTaxon = (Taxon)taxon1;
267 if (relQualifierFk == TAX_REL_IS_INCLUDED_IN){
268 makeTaxonomicallyIncluded(state, fromTaxon, toTaxon, citation, microcitation);
269 }else if (relQualifierFk == TAX_REL_IS_MISAPPLIED_NAME_OF){
270 toTaxon.addMisappliedName(fromTaxon, citation, microcitation);
271 }
272 }else if (isSynonymRelationship(relQualifierFk)){
273 if (!(taxon1 instanceof Synonym)){
274 logger.error("Taxon (ID = " + taxon1.getId()+ ", RIdentifier = " + taxon1Id + ") can't be casted to Synonym");
275 success = false;
276 continue;
277 }
278 Synonym synonym = (Synonym)taxon1;
279 SynonymRelationship synRel = getSynRel(relQualifierFk, toTaxon, synonym, citation, microcitation);
280
281 if (relQualifierFk == TAX_REL_IS_SYNONYM_OF ||
282 relQualifierFk == TAX_REL_IS_HOMOTYPIC_SYNONYM_OF ||
283 relQualifierFk == TAX_REL_IS_HETEROTYPIC_SYNONYM_OF){
284 addProParteAndPartial(synRel, synonym, config);
285 }else if (relQualifierFk == TAX_REL_IS_PROPARTE_SYN_OF ||
286 relQualifierFk == TAX_REL_IS_PROPARTE_HOMOTYPIC_SYNONYM_OF ||
287 relQualifierFk == TAX_REL_IS_PROPARTE_HETEROTYPIC_SYNONYM_OF ){
288 synRel.setProParte(true);
289 }else if(relQualifierFk == TAX_REL_IS_PARTIAL_SYN_OF ||
290 relQualifierFk == TAX_REL_IS_PARTIAL_HOMOTYPIC_SYNONYM_OF ||
291 relQualifierFk == TAX_REL_IS_PARTIAL_HETEROTYPIC_SYNONYM_OF ){
292 synRel.setPartial(true);
293 }else{
294 success = false;
295 logger.warn("Proparte/Partial not yet implemented for TaxonRelationShipType " + relQualifierFk);
296 }
297 }else if (isConceptRelationship){
298 ResultWrapper<Boolean> isInverse = new ResultWrapper<Boolean>();
299 try {
300 TaxonRelationshipType relType = BerlinModelTransformer.taxonRelId2TaxonRelType(relQualifierFk, isInverse);
301 if (! (taxon1 instanceof Taxon)){
302 success = false;
303 logger.error("TaxonBase (ID = " + taxon1.getId()+ ", RIdentifier = " + taxon1Id + ") can't be casted to Taxon");
304 }else{
305 Taxon fromTaxon = (Taxon)taxon1;
306 fromTaxon.addTaxonRelation(toTaxon, relType, citation, microcitation);
307 }
308 } catch (UnknownCdmTypeException e) {
309 //TODO other relationships
310 logger.warn("TaxonRelationShipType " + relQualifierFk + " (conceptRelationship) not yet implemented");
311 success = false;
312 }
313 }else {
314 //TODO
315 logger.warn("TaxonRelationShipType " + relQualifierFk + " not yet implemented");
316 success = false;
317 }
318 taxonStore.add(taxon2);
319
320 //TODO
321 //etc.
322 }else{
323 //TODO
324 logger.warn("Taxa for RelPTaxon " + relPTaxonId + " do not exist in store");
325 success = false;
326 }
327 }
328 logger.info("Taxa to save: " + taxonStore.size());
329 getTaxonService().saveTaxonAll(taxonStore);
330
331 logger.info("end makeTaxonRelationships ..." + getSuccessString(success));
332 return success;
333 } catch (SQLException e) {
334 logger.error("SQLException:" + e);
335 return false;
336 }
337
338 }
339
340 private SynonymRelationship getSynRel (int relQualifierFk, Taxon toTaxon, Synonym synonym, ReferenceBase citation, String microcitation){
341 SynonymRelationship result;
342 if (relQualifierFk == TAX_REL_IS_HOMOTYPIC_SYNONYM_OF ||
343 relQualifierFk == TAX_REL_IS_PROPARTE_HOMOTYPIC_SYNONYM_OF ||
344 relQualifierFk == TAX_REL_IS_PARTIAL_HOMOTYPIC_SYNONYM_OF){
345 result = toTaxon.addHomotypicSynonym(synonym, citation, microcitation);
346 }else if (relQualifierFk == TAX_REL_IS_HETEROTYPIC_SYNONYM_OF ||
347 relQualifierFk == TAX_REL_IS_PROPARTE_HETEROTYPIC_SYNONYM_OF ||
348 relQualifierFk == TAX_REL_IS_PARTIAL_HETEROTYPIC_SYNONYM_OF){
349 result = toTaxon.addSynonym(synonym, SynonymRelationshipType.HETEROTYPIC_SYNONYM_OF(), citation, microcitation);
350 }else if (relQualifierFk == TAX_REL_IS_SYNONYM_OF ||
351 relQualifierFk == TAX_REL_IS_PROPARTE_SYN_OF ||
352 relQualifierFk == TAX_REL_IS_PARTIAL_SYN_OF){
353 result = toTaxon.addSynonym(synonym, SynonymRelationshipType.SYNONYM_OF(), citation, microcitation);
354 }else{
355 logger.warn("SynonymyRelationShipType could not be defined for relQualifierFk " + relQualifierFk + ". 'Unknown'-Type taken instead.");
356 result = toTaxon.addSynonym(synonym, SynonymRelationshipType.SYNONYM_OF(), citation, microcitation);
357 }
358 return result;
359
360 }
361
362 private boolean isSynonymRelationship(int relQualifierFk){
363 if (relQualifierFk == TAX_REL_IS_SYNONYM_OF ||
364 relQualifierFk == TAX_REL_IS_HOMOTYPIC_SYNONYM_OF ||
365 relQualifierFk == TAX_REL_IS_HETEROTYPIC_SYNONYM_OF ||
366 relQualifierFk == TAX_REL_IS_PROPARTE_SYN_OF ||
367 relQualifierFk == TAX_REL_IS_PARTIAL_SYN_OF ||
368 relQualifierFk == TAX_REL_IS_PROPARTE_HOMOTYPIC_SYNONYM_OF ||
369 relQualifierFk == TAX_REL_IS_PROPARTE_HETEROTYPIC_SYNONYM_OF ||
370 relQualifierFk == TAX_REL_IS_PARTIAL_HOMOTYPIC_SYNONYM_OF ||
371 relQualifierFk == TAX_REL_IS_PARTIAL_HETEROTYPIC_SYNONYM_OF
372 ){
373 return true;
374 }else{
375 return false;
376 }
377 }
378
379 private boolean isTaxonRelationship(int relQualifierFk){
380 if (relQualifierFk == TAX_REL_IS_INCLUDED_IN ||
381 relQualifierFk == TAX_REL_IS_MISAPPLIED_NAME_OF){
382 return true;
383 }else{
384 return false;
385 }
386 }
387
388 private void addProParteAndPartial(SynonymRelationship synRel, Synonym synonym, BerlinModelImportConfigurator bmiConfig){
389 if (bmiConfig.isPartialSynonym(synonym)){
390 synRel.setPartial(true);
391 }
392 if (bmiConfig.isProParteSynonym(synonym)){
393 synRel.setProParte(true);
394 }
395 }
396
397 private boolean makeTaxonomicallyIncluded(BerlinModelImportState state, Taxon child, Taxon parent, ReferenceBase citation, String microCitation){
398 if (state.getConfig().isUseTaxonomicTree() == false){
399 parent.addTaxonomicChild(child, citation, microCitation);
400 return true;
401 }else{
402 ReferenceBase toRef = parent.getSec();
403 TaxonomicTree tree = state.getTree(toRef);
404 if (tree == null){
405 throw new IllegalStateException("Tree for ToTaxon reference does not exist.");
406 }
407 return tree.addParentChild(parent, child, citation, microCitation);
408 }
409 }
410
411 /* (non-Javadoc)
412 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#isIgnore(eu.etaxonomy.cdm.io.common.IImportConfigurator)
413 */
414 protected boolean isIgnore(IImportConfigurator config){
415 return ! config.isDoRelTaxa();
416 }
417
418 }