1
2
3
4
5
6
7
8
9
10 package eu.etaxonomy.cdm.io.tcsxml.in;
11
12 import java.util.ArrayList;
13 import java.util.HashSet;
14 import java.util.Iterator;
15 import java.util.List;
16 import java.util.Set;
17
18 import org.apache.log4j.Logger;
19 import org.jdom.Attribute;
20 import org.jdom.Element;
21 import org.jdom.Namespace;
22 import org.jdom.filter.ElementFilter;
23 import org.jdom.filter.Filter;
24 import org.springframework.stereotype.Component;
25
26 import eu.etaxonomy.cdm.api.service.ITaxonService;
27 import eu.etaxonomy.cdm.common.ResultWrapper;
28 import eu.etaxonomy.cdm.common.XmlHelp;
29 import eu.etaxonomy.cdm.io.common.ICdmIO;
30 import eu.etaxonomy.cdm.io.common.ImportHelper;
31 import eu.etaxonomy.cdm.io.common.MapWrapper;
32 import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
33 import eu.etaxonomy.cdm.model.name.NomenclaturalCode;
34 import eu.etaxonomy.cdm.model.name.NonViralName;
35 import eu.etaxonomy.cdm.model.name.Rank;
36 import eu.etaxonomy.cdm.model.name.TaxonNameBase;
37 import eu.etaxonomy.cdm.model.reference.IGeneric;
38 import eu.etaxonomy.cdm.model.reference.ReferenceBase;
39 import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
40 import eu.etaxonomy.cdm.model.taxon.Synonym;
41 import eu.etaxonomy.cdm.model.taxon.Taxon;
42 import eu.etaxonomy.cdm.model.taxon.TaxonBase;
43
44
45
46
47
48
49 @Component
50 public class TcsXmlTaxonImport extends TcsXmlImportBase implements ICdmIO<TcsXmlImportState> {
51 private static final Logger logger = Logger.getLogger(TcsXmlTaxonImport.class);
52
53 private static int modCount = 30000;
54
55 public TcsXmlTaxonImport(){
56 super();
57 }
58
59
60 @Override
61 public boolean doCheck(TcsXmlImportState state){
62 boolean result = true;
63 logger.warn("Checking for Taxa not yet implemented");
64
65
66
67 return result;
68 }
69
70
71
72
73
74
75
76 private Set<String> makeSynonymIds(List<Element> elTaxonConceptList, ResultWrapper<Boolean> success){
77
78
79 Set<String> result = new HashSet<String>();
80
81 Namespace tcsNamespace;
82
83 for (Element elTaxonConcept : elTaxonConceptList){
84 tcsNamespace = elTaxonConcept.getNamespace();
85
86 String childName = "TaxonRelationships";
87 boolean obligatory = false;
88 Element elTaxonRelationships = XmlHelp.getSingleChildElement(success, elTaxonConcept, childName, tcsNamespace, obligatory);
89
90 if (elTaxonRelationships == null){
91 continue;
92 }
93 String tcsElementName = "TaxonRelationship";
94 List<Element> elTaxonRelationshipList = elTaxonRelationships.getChildren(tcsElementName, tcsNamespace);
95 for (Element elTaxonRelationship : elTaxonRelationshipList){
96
97 String relationshipType = elTaxonRelationship.getAttributeValue("type");
98 if ("has synonym".equalsIgnoreCase(relationshipType)){
99 childName = "ToTaxonConcept";
100 obligatory = true;
101 Element elToTaxonConcept = XmlHelp.getSingleChildElement(success, elTaxonRelationship, childName, tcsNamespace, obligatory);
102
103 String linkType = elToTaxonConcept.getAttributeValue("linkType");
104 if (linkType == null || linkType.equals("local")){
105 String ref = elToTaxonConcept.getAttributeValue("ref");
106 result.add(ref);
107 }else{
108 logger.warn("External link types for synonym not yet implemented");
109 }
110 }
111 }
112 }
113 return result;
114 }
115
116
117 protected static final ReferenceBase unknownSec(){
118 ReferenceFactory refFactory = ReferenceFactory.newInstance();
119 ReferenceBase result = refFactory.newGeneric();
120 result.setTitleCache("UNKNOWN", true);
121 return result;
122 }
123
124 @Override
125 public boolean doInvoke(TcsXmlImportState state){
126
127 logger.info("start make TaxonConcepts ...");
128 MapWrapper<TaxonBase> taxonMap = (MapWrapper<TaxonBase>)state.getStore(ICdmIO.TAXON_STORE);
129 MapWrapper<TaxonNameBase<?,?>> taxonNameMap = (MapWrapper<TaxonNameBase<?,?>>)state.getStore(ICdmIO.TAXONNAME_STORE);
130 MapWrapper<ReferenceBase> referenceMap = (MapWrapper<ReferenceBase>)state.getStore(ICdmIO.REFERENCE_STORE);
131 ITaxonService taxonService = getTaxonService();
132
133 ResultWrapper<Boolean> success = ResultWrapper.NewInstance(true);
134 String childName;
135 boolean obligatory;
136 String idNamespace = "TaxonConcept";
137
138 TcsXmlImportConfigurator config = state.getConfig();
139 Element elDataSet = getDataSetElement(config);
140 Namespace tcsNamespace = config.getTcsXmlNamespace();
141
142 childName = "TaxonConcepts";
143 obligatory = false;
144 Element elTaxonConcepts = XmlHelp.getSingleChildElement(success, elDataSet, childName, tcsNamespace, obligatory);
145
146 String tcsElementName = "TaxonConcept";
147 List<Element> elTaxonConceptList = elTaxonConcepts.getChildren(tcsElementName, tcsNamespace);
148
149 Set<String> synonymIdSet = makeSynonymIds(elTaxonConceptList, success);
150
151
152 int i = 0;
153
154
155 for (Element elTaxonConcept : elTaxonConceptList){
156 if ((i++ % modCount) == 0 && i > 1){ logger.info("Taxa handled: " + (i-1));}
157 List<String> elementList = new ArrayList<String>();
158
159
160 String strId = elTaxonConcept.getAttributeValue("id");
161
162 String strConceptType = elTaxonConcept.getAttributeValue("type");
163 String strPrimary = elTaxonConcept.getAttributeValue("primary");
164 String strForm = elTaxonConcept.getAttributeValue("form");
165
166 childName = "Name";
167 obligatory = true;
168 Element elName = XmlHelp.getSingleChildElement(success, elTaxonConcept, childName, tcsNamespace, obligatory);
169 TaxonNameBase<?,?> taxonName = makeName(elName, null, taxonNameMap, success);
170 elementList.add(childName.toString());
171
172
173 childName = "Rank";
174 obligatory = false;
175 Element elRank = XmlHelp.getSingleChildElement(success, elTaxonConcept, childName, tcsNamespace, obligatory);
176 Rank rank = TcsXmlTaxonNameImport.makeRank(elRank);
177 if (rank != null){
178 logger.warn("Rank in TaxonIO not yet implemented");
179 }
180 elementList.add(childName.toString());
181
182 childName = "AccordingTo";
183 obligatory = false;
184 Element elAccordingTo = XmlHelp.getSingleChildElement(success, elTaxonConcept, childName, tcsNamespace, obligatory);
185 ReferenceBase sec = makeAccordingTo(elAccordingTo, referenceMap, success);
186 elementList.add(childName.toString());
187
188 if (sec == null){
189 sec = unknownSec();
190 }
191
192 TaxonBase taxonBase;
193 if (synonymIdSet.contains(strId)){
194 taxonBase = Synonym.NewInstance(taxonName, sec);
195 }else{
196 taxonBase = Taxon.NewInstance(taxonName, sec);
197 }
198
199 childName = "TaxonRelationships";
200 obligatory = false;
201 Element elTaxonRelationships = XmlHelp.getSingleChildElement(success, elTaxonConcept, childName, tcsNamespace, obligatory);
202 makeTaxonRelationships(taxonBase, elTaxonRelationships, success);
203 elementList.add(childName.toString());
204
205 childName = "SpecimenCircumscription";
206 obligatory = false;
207 Element elSpecimenCircumscription = XmlHelp.getSingleChildElement(success, elTaxonConcept, childName, tcsNamespace, obligatory);
208 makeSpecimenCircumscription(taxonBase, elSpecimenCircumscription, success);
209 elementList.add(childName.toString());
210
211 childName = "CharacterCircumscription";
212 obligatory = false;
213 Element elCharacterCircumscription = XmlHelp.getSingleChildElement(success, elTaxonConcept, childName, tcsNamespace, obligatory);
214 makeCharacterCircumscription(taxonBase, elCharacterCircumscription, success);
215 elementList.add(childName.toString());
216
217
218 childName = "ProviderLink";
219 obligatory = false;
220 Element elProviderLink = XmlHelp.getSingleChildElement(success, elTaxonConcept, childName, tcsNamespace, obligatory);
221 makeProviderLink(taxonBase, elProviderLink, success);
222 elementList.add(childName.toString());
223
224 childName = "ProviderSpecificData";
225 obligatory = false;
226 Element elProviderSpecificData = XmlHelp.getSingleChildElement(success, elTaxonConcept, childName, tcsNamespace, obligatory);
227 makeProviderSpecificData(taxonBase, elProviderSpecificData, success);
228 elementList.add(childName.toString());
229
230 testAdditionalElements(elTaxonConcept, elementList);
231 ImportHelper.setOriginalSource(taxonBase, config.getSourceReference(), strId, idNamespace);
232 taxonMap.put(strId, taxonBase);
233
234 }
235
236 logger.info(i + " taxa handled. Saving ...");
237 taxonService.save(taxonMap.objects());
238 logger.info("end makeTaxa ...");
239 return success.getValue();
240 }
241
242
243 private boolean hasIsSynonymRelation(Element taxonConcept, Namespace rdfNamespace){
244 boolean result = false;
245 if (taxonConcept == null || ! "TaxonConcept".equalsIgnoreCase(taxonConcept.getName()) ){
246 return false;
247 }
248
249 String elName = "relationshipCategory";
250 Filter filter = new ElementFilter(elName, taxonConcept.getNamespace());
251 Iterator<Element> relationshipCategories = taxonConcept.getDescendants(filter);
252 while (relationshipCategories.hasNext()){
253 Element relationshipCategory = relationshipCategories.next();
254 Attribute resource = relationshipCategory.getAttribute("resource", rdfNamespace);
255 String isSynonymFor = "http://rs.tdwg.org/ontology/voc/TaxonConcept#IsSynonymFor";
256 if (resource != null && isSynonymFor.equalsIgnoreCase(resource.getValue()) ){
257 return true;
258 }
259 }
260 return result;
261 }
262
263
264
265
266
267
268 private TaxonNameBase<?, ?> makeName(Element elName, NomenclaturalCode code, MapWrapper<? extends TaxonNameBase<?,?>> objectMap, ResultWrapper<Boolean> success){
269 TaxonNameBase<?, ?> result = null;
270 if (elName != null){
271
272 try {
273 String strScientific = elName.getAttributeValue("scientific");
274 boolean scientific = Boolean.valueOf(strScientific);
275 if (! scientific){
276
277 logger.warn("Non scientific names not yet implemented");
278 success.setValue(false);
279 }
280 } catch (Exception e) {
281 logger.warn("Value for scientific is not boolean");
282 }
283 String language = elName.getAttributeValue("language");
284
285
286 if (language != null){
287 logger.warn("language for name not yet implemented");
288 }
289 Class<? extends IdentifiableEntity> clazz = (Class<? extends IdentifiableEntity>)NonViralName.class;
290 if (code != null){
291 clazz = code.getCdmClass();
292 }
293 result = (TaxonNameBase<?,?>)makeReferenceType (elName, clazz , objectMap, success);
294 if(result == null){
295 logger.warn("Name not found");
296 success.setValue(false);
297 }
298 }else{
299 logger.warn("Name element is null");
300 }
301 return result;
302 }
303
304
305
306
307
308
309 private void makeTaxonRelationships(TaxonBase name, Element elTaxonRelationships, ResultWrapper<Boolean> success){
310
311 return;
312 }
313
314
315
316 private void makeSpecimenCircumscription(TaxonBase name, Element elSpecimenCircumscription, ResultWrapper<Boolean> success){
317 if (elSpecimenCircumscription != null){
318 logger.warn("makeProviderLink not yet implemented");
319 success.setValue(false);
320 }
321 }
322
323
324 private void makeCharacterCircumscription(TaxonBase name, Element elCharacterCircumscription, ResultWrapper<Boolean> success){
325 if (elCharacterCircumscription != null){
326 logger.warn("makeProviderLink not yet implemented");
327 success.setValue(false);
328 }
329 }
330
331 private void makeProviderLink(TaxonBase name, Element elProviderLink, ResultWrapper<Boolean> success){
332 if (elProviderLink != null){
333 logger.warn("makeProviderLink not yet implemented");
334 success.setValue(false);
335 }
336 }
337
338
339 private void makeProviderSpecificData(TaxonBase name, Element elProviderSpecificData, ResultWrapper<Boolean> success){
340 if (elProviderSpecificData != null){
341 logger.warn("makeProviderLink not yet implemented");
342 success.setValue(false);
343 }
344 }
345
346
347
348
349
350
351 protected boolean isIgnore(TcsXmlImportState state){
352 return ! state.getConfig().isDoTaxa();
353 }
354
355
356 }