View Javadoc

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.tcsrdf;
11  
12  import java.util.HashSet;
13  import java.util.List;
14  import java.util.Set;
15  
16  import org.apache.log4j.Logger;
17  import org.jdom.Element;
18  import org.jdom.Namespace;
19  import org.springframework.stereotype.Component;
20  
21  import eu.etaxonomy.cdm.common.XmlHelp;
22  import eu.etaxonomy.cdm.io.common.ICdmIO;
23  import eu.etaxonomy.cdm.io.common.MapWrapper;
24  import eu.etaxonomy.cdm.model.common.RelationshipTermBase;
25  import eu.etaxonomy.cdm.model.name.TaxonNameBase;
26  import eu.etaxonomy.cdm.model.reference.ReferenceBase;
27  import eu.etaxonomy.cdm.model.taxon.Synonym;
28  import eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType;
29  import eu.etaxonomy.cdm.model.taxon.Taxon;
30  import eu.etaxonomy.cdm.model.taxon.TaxonBase;
31  import eu.etaxonomy.cdm.model.taxon.TaxonNode;
32  import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;
33  import eu.etaxonomy.cdm.model.taxon.TaxonomicTree;
34  import eu.etaxonomy.cdm.strategy.exceptions.UnknownCdmTypeException;
35  
36  
37  /**
38   * @author a.mueller
39   * @created 29.05.2008
40   * @version 1.0
41   */
42  @Component
43  public class TcsRdfTaxonRelationsImport extends TcsRdfImportBase implements ICdmIO<TcsRdfImportState> {
44  	private static final Logger logger = Logger.getLogger(TcsRdfTaxonRelationsImport.class);
45  
46  	private static int modCount = 30000;
47  
48  	public TcsRdfTaxonRelationsImport(){
49  		super();
50  	}
51  	
52  	@Override
53  	public boolean doCheck(TcsRdfImportState state){
54  		boolean result = true;
55  		logger.warn("Checking for TaxonRelations not yet implemented");
56  		logger.warn("Creation of homotypic relations is still problematic");
57  		//result &= checkArticlesWithoutJournal(bmiConfig);
58  		//result &= checkPartOfJournal(bmiConfig);
59  		
60  		return result;
61  	}
62  	
63  	@Override
64  	public boolean doInvoke(TcsRdfImportState state){ 
65  	
66  		MapWrapper<TaxonBase> taxonMap = (MapWrapper<TaxonBase>)state.getStore(ICdmIO.TAXON_STORE);
67  		MapWrapper<ReferenceBase> referenceMap = (MapWrapper<ReferenceBase>)state.getStore(ICdmIO.REFERENCE_STORE);
68  		logger.info("start makeTaxonRelationships ...");
69  		boolean success =true;
70  
71  		String xmlElementName;
72  		Namespace elementNamespace;
73  		
74  		Set<TaxonBase> taxonStore = new HashSet<TaxonBase>();
75  		
76  		TcsRdfImportConfigurator config = state.getConfig();
77  		Element root = config.getSourceRoot();
78  		Namespace taxonConceptNamespace = config.getTcNamespace();
79  
80  		xmlElementName = "TaxonConcept";
81  		elementNamespace = taxonConceptNamespace;
82  		List<Element> elTaxonConcepts = root.getChildren(xmlElementName, elementNamespace);
83  
84  		int i = 0;
85  		//for each taxonConcept
86  		for (Element elTaxonConcept : elTaxonConcepts){
87  			try {
88  				if ((i++ % modCount) == 0){ logger.info("Taxa handled: " + (i-1));}
89  				
90  				//TaxonConcept about
91  				xmlElementName = "about";
92  				elementNamespace = config.getRdfNamespace();
93  				String strTaxonAbout = elTaxonConcept.getAttributeValue(xmlElementName, elementNamespace);
94  				
95  				TaxonBase aboutTaxon = taxonMap.get(strTaxonAbout);
96  				
97  				if (aboutTaxon instanceof Taxon){
98  					success &= makeHomotypicSynonymRelations((Taxon)aboutTaxon);
99  				}
100 				
101 				xmlElementName = "hasRelationship";
102 				elementNamespace = taxonConceptNamespace;
103 				List<Element> elHasRelationships = elTaxonConcept.getChildren(xmlElementName, elementNamespace);
104 				
105 				
106 				for (Element elHasRelationship: elHasRelationships){
107 					xmlElementName = "relationship";
108 					elementNamespace = taxonConceptNamespace;
109 					List<Element> elRelationships = elHasRelationship.getChildren(xmlElementName, elementNamespace);
110 					
111 					for (Element elRelationship: elRelationships){
112 						success &= 	makeRelationship(elRelationship, strTaxonAbout, taxonMap, state, taxonStore);
113 					}//relationship
114 				}//hasRelationships
115 			} catch (Exception e) {
116 				e.printStackTrace();
117 				logger.error("Error. Taxon relationship could not be imported");
118 				success = false;
119 			}
120 		}//elTaxonConcept
121 		logger.info("Taxa to save: " + taxonStore.size());
122 		getTaxonService().save(taxonStore);
123 		
124 		logger.info("end makeRelTaxa ...");
125 		return success;
126 
127 	}
128 	
129 	private boolean makeRelationship(
130 				Element elRelationship, 
131 				String strTaxonAbout,
132 				MapWrapper<TaxonBase> taxonMap,
133 				TcsRdfImportState state,
134 				Set<TaxonBase> taxonStore){
135 		boolean success = true;
136 		String xmlElementName;
137 		String xmlAttributeName;
138 		Namespace elementNamespace;
139 		Namespace attributeNamespace;
140 		TcsRdfImportConfigurator tcsConfig = state.getConfig();
141 		//relationship
142 		xmlElementName = "relationshipCategory";
143 		elementNamespace = tcsConfig.getTcNamespace();
144 		xmlAttributeName = "resource";
145 		attributeNamespace = tcsConfig.getRdfNamespace();
146 		String strRelCategory = XmlHelp.getChildAttributeValue(elRelationship, xmlElementName, elementNamespace, xmlAttributeName, attributeNamespace);
147 		try {
148 			RelationshipTermBase relType = TcsRdfTransformer.tcsRelationshipCategory2Relationship(strRelCategory);
149 			boolean isReverse = TcsRdfTransformer.isReverseRelationshipCategory(strRelCategory);
150 			//toTaxon
151 			xmlElementName = "toTaxon";
152 			elementNamespace = tcsConfig.getTcNamespace();
153 			xmlAttributeName = "resource";
154 			attributeNamespace = tcsConfig.getRdfNamespace();
155 			String strToTaxon = XmlHelp.getChildAttributeValue(elRelationship, xmlElementName, elementNamespace, xmlAttributeName, attributeNamespace);
156 			TaxonBase toTaxon = taxonMap.get(strToTaxon);
157 			TaxonBase fromTaxon = taxonMap.get(strTaxonAbout);
158 			if (toTaxon != null && fromTaxon != null){
159 				//reverse
160 				if (isReverse == true ){
161 					TaxonBase tmp = toTaxon;
162 					toTaxon = fromTaxon;
163 					fromTaxon = tmp;
164 				}
165 				
166 				//Create relationship
167 				if (! (toTaxon instanceof Taxon)){
168 					logger.warn("TaxonBase toTaxon is not of Type 'Taxon'. Relationship is not added.");
169 					success = false;
170 				}else{
171 					Taxon taxonTo = (Taxon)toTaxon;
172 					ReferenceBase citation = null;
173 					String microReference = null;
174 					if (relType instanceof SynonymRelationshipType){
175 						success &= makeSynRelType((SynonymRelationshipType)relType, taxonTo, fromTaxon, citation, microReference);
176 					}else if (relType instanceof TaxonRelationshipType){
177 						success &= makeTaxonRelType((TaxonRelationshipType)relType, state, taxonTo, fromTaxon, strTaxonAbout , citation, microReference);
178 					}else{
179 						logger.warn("Unknown Relationshiptype");
180 						success = false;
181 					}
182 					taxonStore.add(toTaxon);
183 				}
184 			}else{
185 				if (toTaxon == null){
186 					logger.warn("toTaxon (" + strToTaxon + ") could  not be found in taxonMap. Relationship of type " + strRelCategory + " was not added to CDM");
187 				}
188 				if (fromTaxon == null){
189 					logger.warn("fromTaxon (" + strTaxonAbout + ") could not be found in taxonMap. Relationship was not added to CDM");
190 				}
191 				success = false;
192 			}
193 			
194 		} catch (UnknownCdmTypeException e) {
195 			//TODO
196 			logger.warn("tc:relationshipCategory " + strRelCategory + " not yet implemented");
197 			return false;
198 		}
199 		return success;
200 	}
201 	
202 	
203 	private boolean makeSynRelType(SynonymRelationshipType synRelType, Taxon taxonTo, TaxonBase fromTaxon, ReferenceBase citation, String microReference){
204 		boolean success = true;
205 		if (! (fromTaxon instanceof Synonym )){
206 			logger.warn("TaxonBase fromTaxon is not of Type 'Synonym'. Relationship is not added.");
207 			success = false;
208 		}else{
209 			Synonym synonym = (Synonym)fromTaxon;
210 			TaxonNameBase synName = synonym.getName();
211 			TaxonNameBase accName = taxonTo.getName();
212 			if (synName != null && accName != null && synName.isHomotypic(accName)
213 						&& ( synRelType.equals(SynonymRelationshipType.SYNONYM_OF()))){
214 				synRelType = SynonymRelationshipType.HOMOTYPIC_SYNONYM_OF(); 
215 			}
216 			if (! relationExists(taxonTo, synonym, synRelType)){
217 				taxonTo.addSynonym(synonym, synRelType,  citation, microReference);	
218 			}else{
219 				//TODO citation, microReference
220 				//TODO different synRelTypes -> warning
221 				success = false;
222 			}
223 		}
224 		return success;
225 	}
226 	
227 	private boolean makeTaxonRelType(TaxonRelationshipType relType, TcsRdfImportState state, Taxon taxonTo, TaxonBase fromTaxon, String strTaxonAbout, ReferenceBase citation, String microReference){
228 		boolean success = true;
229 		if (! (fromTaxon instanceof Taxon )){
230 			logger.warn("TaxonBase fromTaxon " + strTaxonAbout + " is not of Type 'Taxon'. Relationship is not added.");
231 			success = false;
232 		}else{
233 			Taxon taxonFrom = (Taxon)fromTaxon;
234 			if (state.getConfig().isUseTaxonomicTree() && relType.equals(TaxonRelationshipType.TAXONOMICALLY_INCLUDED_IN())){
235 				success &= makeTaxonomicallyIncluded(state, taxonTo, taxonFrom, citation, microReference);
236 			}else{
237 				taxonFrom.addTaxonRelation(taxonTo, relType, citation, microReference);
238 			}
239 		}
240 		return success;
241 	}
242 	
243 	private boolean makeTaxonomicallyIncluded(TcsRdfImportState state, Taxon toTaxon, Taxon fromTaxon, ReferenceBase citation, String microCitation){
244 		ReferenceBase sec = toTaxon.getSec();
245 		TaxonomicTree tree = state.getTree(sec);
246 		if (tree == null){
247 			tree = makeTree(state, sec);
248 		}
249 		TaxonNode childNode = tree.addParentChild(toTaxon, fromTaxon, citation, microCitation);
250 		return (childNode != null);
251 	}
252 	
253 	private boolean relationExists(Taxon taxonTo, Synonym synonym, SynonymRelationshipType synRelType){
254 		if (synonym == null){
255 			return false;
256 		}
257 		if (synonym.getRelationType(taxonTo).size() > 0){
258 			Set<SynonymRelationshipType> relTypeList = synonym.getRelationType(taxonTo);
259 			if (relTypeList.contains(synRelType)){
260 				return true;
261 			}else{
262 				logger.warn("Taxon-Synonym pair has 2 different SynonymRelationships. This is against the rules");
263 				return false;
264 			}
265 		}else{
266 			return false;
267 		}
268 	}
269 
270 	private boolean makeHomotypicSynonymRelations(Taxon aboutTaxon){
271 		if (true)return false;
272 		TaxonNameBase aboutName = aboutTaxon.getName();
273 		if (aboutName != null){
274 			Set<TaxonNameBase> typifiedNames = aboutName.getHomotypicalGroup().getTypifiedNames();
275 			for (TaxonNameBase typifiedName : typifiedNames){
276 				//TODO check if name is part of this tcs file
277 				if (typifiedName.equals(aboutName)){
278 					continue;
279 				}
280 				Set<Synonym> syns = typifiedName.getSynonyms();
281 				for(Synonym syn:syns){
282 					aboutTaxon.addSynonym(syn, SynonymRelationshipType.HOMOTYPIC_SYNONYM_OF());
283 				}
284 			}
285 			
286 			
287 		}
288 		return true;
289 	}
290 	
291 	/* (non-Javadoc)
292 	 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#isIgnore(eu.etaxonomy.cdm.io.common.IImportConfigurator)
293 	 */
294 	protected boolean isIgnore(TcsRdfImportState state){
295 		return ! state.getConfig().isDoRelTaxa();
296 	}
297 	
298 }