001 /*
002 * The contents of this file are subject to the Mozilla Public
003 * License Version 1.1 (the "License"); you may not use this file
004 * except in compliance with the License. You may obtain a copy of
005 * the License at http://www.mozilla.org/MPL/
006 *
007 * Software distributed under the License is distributed on an "AS
008 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
009 * implied. See the License for the specific language governing
010 * rights and limitations under the License.
011 *
012 * The Original Code is Knowtator.
013 *
014 * The Initial Developer of the Original Code is University of Colorado.
015 * Copyright (C) 2005 - 2008. All Rights Reserved.
016 *
017 * Knowtator was developed by the Center for Computational Pharmacology
018 * (http://compbio.uchcs.edu) at the University of Colorado Health
019 * Sciences Center School of Medicine with support from the National
020 * Library of Medicine.
021 *
022 * Current information about Knowtator can be obtained at
023 * http://knowtator.sourceforge.net/
024 *
025 * Contributor(s):
026 * Philip V. Ogren <philip@ogren.info> (Original Author)
027 */
028
029 package edu.uchsc.ccp.knowtator.xml;
030
031 import java.awt.Component;
032 import java.io.File;
033 import java.io.IOException;
034 import java.util.ArrayList;
035 import java.util.Collections;
036 import java.util.Iterator;
037 import java.util.List;
038
039 import javax.swing.JFileChooser;
040 import javax.swing.JOptionPane;
041
042 import org.jdom.Attribute;
043 import org.jdom.DataConversionException;
044 import org.jdom.Document;
045 import org.jdom.Element;
046 import org.jdom.JDOMException;
047 import org.jdom.input.SAXBuilder;
048
049 import edu.stanford.smi.protege.model.Cls;
050 import edu.stanford.smi.protege.model.Frame;
051 import edu.stanford.smi.protege.model.Instance;
052 import edu.stanford.smi.protege.model.KnowledgeBase;
053 import edu.stanford.smi.protege.model.Project;
054 import edu.stanford.smi.protege.model.SimpleInstance;
055 import edu.stanford.smi.protege.model.Slot;
056 import edu.stanford.smi.protege.util.CollectionUtilities;
057 import edu.uchsc.ccp.knowtator.AnnotationUtil;
058 import edu.uchsc.ccp.knowtator.FilterUtil;
059 import edu.uchsc.ccp.knowtator.KnowtatorProjectUtil;
060 import edu.uchsc.ccp.knowtator.MentionUtil;
061 import edu.uchsc.ccp.knowtator.Span;
062 import edu.uchsc.ccp.knowtator.TextSourceUtil;
063 import edu.uchsc.ccp.knowtator.textsource.TextSource;
064 import edu.uchsc.ccp.knowtator.textsource.TextSourceAccessException;
065
066 public class XMLImport {
067 public static final String XML_IMPORT_DIRECTORY = "XML_IMPORT_FILE";
068
069 private static File getRecentXMLImportDirectory(Project project) {
070 String path = (String) project.getClientInformation(XML_IMPORT_DIRECTORY);
071 if (path == null)
072 return null;
073
074 File xmlImportDirectory = new File(path);
075 if (xmlImportDirectory.exists() && xmlImportDirectory.isDirectory()) {
076 return xmlImportDirectory;
077 }
078 return null;
079 }
080
081 public static void readFromXML(Component parent, KnowledgeBase kb, KnowtatorProjectUtil kpu,
082 TextSourceUtil textSourceUtil, AnnotationUtil annotationUtil, MentionUtil mentionUtil,
083 FilterUtil filterUtil, Project project) {
084
085 int option = JOptionPane.showConfirmDialog(parent,
086 "The following dialogs allow you to import annotations from XML.\n"
087 + "Please consult available documentation before using this feature.\n"
088 + "Before importing annotations please save and/or archive your current\n"
089 + "Knowtator project. If an exception is thrown during annotation import,\n"
090 + "then importing will stop and an error message will appear stating the problem.\n"
091 + "Otherwise, a message stating successful completion will appear. If annotation\n"
092 + "import does not successfully complete, please discard all changes made by\n"
093 + "the partial import by closing your Knowtator project without saving changes\n"
094 + "and reopening.", "XML Import", JOptionPane.OK_CANCEL_OPTION);
095 if (option != JOptionPane.OK_OPTION)
096 return;
097
098 JFileChooser chooser = new JFileChooser();
099 chooser.setDialogTitle("Please choose xml files to read from.");
100 chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
101 chooser.setMultiSelectionEnabled(true);
102
103 File recentXMLImportDirectory = getRecentXMLImportDirectory(project);
104 if (recentXMLImportDirectory != null) {
105 chooser.setCurrentDirectory(recentXMLImportDirectory.getParentFile());
106 }
107
108 int returnVal = chooser.showOpenDialog(parent);
109 if (returnVal != JFileChooser.APPROVE_OPTION)
110 return;
111
112 File[] selectedFiles = chooser.getSelectedFiles();
113
114 System.out.println("selectedFiles.size()=" + selectedFiles.length);
115 if (selectedFiles.length > 0) {
116 project.setClientInformation(XML_IMPORT_DIRECTORY, selectedFiles[0].getParent());
117 }
118
119 try {
120 for (File xmlFile : selectedFiles) {
121 readFromXML(xmlFile, kb, kpu, annotationUtil, filterUtil, mentionUtil, textSourceUtil);
122 }
123 } catch (KnowtatorXMLException kxe) {
124 JOptionPane.showMessageDialog(parent, kxe, "Exception thrown while importing annotations",
125 JOptionPane.ERROR_MESSAGE);
126 JOptionPane.showMessageDialog(parent, "Please discard all changes made by this partial import\n"
127 + "by close this Knowtator project without saving changes and reopening", "Please discard changes",
128 JOptionPane.WARNING_MESSAGE);
129 kxe.printStackTrace();
130 return;
131 }
132
133 JOptionPane.showMessageDialog(parent, "XML import successfully completed.\n"
134 + "To discard changes created by import close this Protege project without saving.",
135 "XML import complete", JOptionPane.INFORMATION_MESSAGE);
136 }
137
138 public static void readFromXML(File xmlFile, KnowledgeBase kb, KnowtatorProjectUtil kpu,
139 AnnotationUtil annotationUtil, FilterUtil filterUtil, MentionUtil mentionUtil, TextSourceUtil textSourceUtil)
140 throws KnowtatorXMLException {
141 try {
142 SAXBuilder builder = new SAXBuilder();
143 Document doc = builder.build(xmlFile);
144
145 Element root = doc.getRootElement();
146 Attribute textSourceAttribute = root.getAttribute(XMLConstants.TEXT_SOURCE_ATTRIBUTE_NAME);
147 String textSourceID = textSourceAttribute.getValue();
148 SimpleInstance textSource = kb.getSimpleInstance(textSourceID);
149 if (textSource == null) {
150 TextSource ts = textSourceUtil.getCurrentTextSourceCollection().get(textSourceID);
151 textSource = textSourceUtil.getTextSourceInstance(ts, true);
152 }
153
154 readClsMentions(root, kb, kpu);
155 readInstanceMentions(root, kb, kpu);
156 readSlotMentions(root, kb, kpu);
157 readMentionSlots(root, kb, kpu, XMLConstants.CLASS_MENTION_ELEMENT_NAME);
158 readMentionSlots(root, kb, kpu, XMLConstants.INSTANCE_MENTION_ELEMENT_NAME);
159 readAnnotations(root, kb, kpu, annotationUtil, textSource);
160 } catch (IOException ioe) {
161 throw new KnowtatorXMLException(ioe);
162 } catch (JDOMException jde) {
163 throw new KnowtatorXMLException(jde);
164 } catch (TextSourceAccessException tsae) {
165 throw new KnowtatorXMLException(tsae);
166 }
167 }
168
169 /**
170 * This method iterates through all of the class mention elements and checks
171 * to see that a corresponding 'knowtator class mention' instance exists in
172 * the Protege project. If not, then they are created. The mentioned class
173 * is also set for the Protege instance.
174 *
175 * @param root
176 * @param kb
177 * @param kpu
178 */
179
180 private static void readClsMentions(Element root, KnowledgeBase kb, KnowtatorProjectUtil kpu)
181 throws KnowtatorXMLException {
182 List classMentionElements = root.getChildren(XMLConstants.CLASS_MENTION_ELEMENT_NAME);
183 Iterator classMentionElementsItr = classMentionElements.iterator();
184
185 while (classMentionElementsItr.hasNext()) {
186 Element classMentionElement = (Element) classMentionElementsItr.next();
187
188 String classMentionID = classMentionElement.getAttribute(XMLConstants.ID_ATTRIBUTE_NAME).getValue();
189 Instance classMentionInstance = kb.getInstance(classMentionID);
190 if (classMentionInstance == null) // create class mention if it does
191 // not already exist from the
192 // class mention id
193 {
194 classMentionInstance = kb.createSimpleInstance(null, classMentionID, CollectionUtilities
195 .createCollection(kpu.getClassMentionCls()), true);
196 }
197
198 String mentionedClassID = classMentionElement.getChild(XMLConstants.MENTION_CLASS_ELEMENT_NAME)
199 .getAttribute(XMLConstants.ID_ATTRIBUTE_NAME).getValue();
200 Cls mentionedCls = kb.getCls(mentionedClassID);
201 if (mentionedCls == null) {
202 throw new KnowtatorXMLException("There is no class defined in Protege with the name '"
203 + mentionedClassID + "'.");
204 }
205 classMentionInstance.setOwnSlotValue(kpu.getMentionClassSlot(), mentionedCls);
206 }
207 }
208
209 private static void readInstanceMentions(Element root, KnowledgeBase kb, KnowtatorProjectUtil kpu)
210 throws KnowtatorXMLException {
211 List instanceMentionElements = root.getChildren(XMLConstants.INSTANCE_MENTION_ELEMENT_NAME);
212 Iterator instanceMentionElementsItr = instanceMentionElements.iterator();
213
214 while (instanceMentionElementsItr.hasNext()) {
215 Element instanceMentionElement = (Element) instanceMentionElementsItr.next();
216
217 // create instance mention if it does not already exist from the
218 // class mention id
219 String instanceMentionID = instanceMentionElement.getAttribute(XMLConstants.ID_ATTRIBUTE_NAME).getValue();
220 Instance instanceMentionInstance = kb.getInstance(instanceMentionID);
221 if (instanceMentionInstance == null) {
222 instanceMentionInstance = kb.createSimpleInstance(null, instanceMentionID, CollectionUtilities
223 .createCollection(kpu.getInstanceMentionCls()), true);
224 }
225
226 // set the mentioned instance of the instance mention
227 String mentionedInstanceID = instanceMentionElement.getChild(XMLConstants.MENTION_INSTANCE_ELEMENT_NAME)
228 .getAttribute(XMLConstants.ID_ATTRIBUTE_NAME).getValue();
229 Instance mentionedInstance = kb.getInstance(mentionedInstanceID);
230 if (mentionedInstance == null) {
231 throw new KnowtatorXMLException("There is no instance defined in Protege with the name '"
232 + mentionedInstanceID + "'.");
233 }
234 instanceMentionInstance.setOwnSlotValue(kpu.getMentionClassSlot(), mentionedInstance);
235 }
236 }
237
238 private static void readSlotMentions(Element root, KnowledgeBase kb, KnowtatorProjectUtil kpu)
239 throws KnowtatorXMLException {
240
241 List<Element> slotMentionElements = getSlotMentionElements(root);
242
243 for (Element slotMentionElement : slotMentionElements) {
244 String slotMentionID = slotMentionElement.getAttribute(XMLConstants.ID_ATTRIBUTE_NAME).getValue();
245 Instance slotMentionInstance = kb.getInstance(slotMentionID);
246 // set the mentioned slot of the slot mention
247 String mentionedSlotID = slotMentionElement.getChild(XMLConstants.MENTION_SLOT_ELEMENT_NAME).getAttribute(
248 XMLConstants.ID_ATTRIBUTE_NAME).getValue();
249 Slot mentionedSlot = kb.getSlot(mentionedSlotID);
250 if (mentionedSlot == null) {
251 throw new KnowtatorXMLException("There is no slot defined in Protege with the name '" + mentionedSlotID
252 + "'.");
253 }
254
255 if (slotMentionElement.getName().equals(XMLConstants.COMPLEX_SLOT_MENTION_ELEMENT_NAME)) {
256 if (slotMentionInstance == null)
257 slotMentionInstance = kb.createSimpleInstance(null, slotMentionID, CollectionUtilities
258 .createCollection(kpu.getComplexSlotMentionCls()), true);
259 else
260 slotMentionInstance.setOwnSlotValues(kpu.getMentionSlotValueSlot(), Collections.EMPTY_LIST);
261 readComplexSlotMentionValues(slotMentionElement, slotMentionInstance, kb, kpu);
262 } else if (slotMentionElement.getName().equals(XMLConstants.BOOLEAN_SLOT_MENTION_ELEMENT_NAME)) {
263 if (slotMentionInstance == null)
264 slotMentionInstance = kb.createSimpleInstance(null, slotMentionID, CollectionUtilities
265 .createCollection(kpu.getBooleanSlotMentionCls()), true);
266 else
267 slotMentionInstance.setOwnSlotValues(kpu.getMentionSlotValueSlot(), Collections.EMPTY_LIST);
268 readSimpleSlotMentionValues(slotMentionElement, slotMentionInstance, kb, kpu,
269 XMLConstants.BOOLEAN_SLOT_MENTION_VALUE_ELEMENT_NAME);
270 } else if (slotMentionElement.getName().equals(XMLConstants.FLOAT_SLOT_MENTION_ELEMENT_NAME)) {
271 if (slotMentionInstance == null)
272 slotMentionInstance = kb.createSimpleInstance(null, slotMentionID, CollectionUtilities
273 .createCollection(kpu.getFloatSlotMentionCls()), true);
274 else
275 slotMentionInstance.setOwnSlotValues(kpu.getMentionSlotValueSlot(), Collections.EMPTY_LIST);
276 readSimpleSlotMentionValues(slotMentionElement, slotMentionInstance, kb, kpu,
277 XMLConstants.FLOAT_SLOT_MENTION_VALUE_ELEMENT_NAME);
278 } else if (slotMentionElement.getName().equals(XMLConstants.INTEGER_SLOT_MENTION_ELEMENT_NAME)) {
279 if (slotMentionInstance == null)
280 slotMentionInstance = kb.createSimpleInstance(null, slotMentionID, CollectionUtilities
281 .createCollection(kpu.getIntegerSlotMentionCls()), true);
282 else
283 slotMentionInstance.setOwnSlotValues(kpu.getMentionSlotValueSlot(), Collections.EMPTY_LIST);
284 readSimpleSlotMentionValues(slotMentionElement, slotMentionInstance, kb, kpu,
285 XMLConstants.INTEGER_SLOT_MENTION_VALUE_ELEMENT_NAME);
286 } else if (slotMentionElement.getName().equals(XMLConstants.STRING_SLOT_MENTION_ELEMENT_NAME)) {
287 if (slotMentionInstance == null)
288 slotMentionInstance = kb.createSimpleInstance(null, slotMentionID, CollectionUtilities
289 .createCollection(kpu.getStringSlotMentionCls()), true);
290 else
291 slotMentionInstance.setOwnSlotValues(kpu.getMentionSlotValueSlot(), Collections.EMPTY_LIST);
292 readSimpleSlotMentionValues(slotMentionElement, slotMentionInstance, kb, kpu,
293 XMLConstants.STRING_SLOT_MENTION_VALUE_ELEMENT_NAME);
294 }
295
296 slotMentionInstance.setOwnSlotValue(kpu.getMentionSlotSlot(), mentionedSlot);
297 }
298 }
299
300 private static void readComplexSlotMentionValues(Element slotMentionElement, Instance slotMentionInstance,
301 KnowledgeBase kb, KnowtatorProjectUtil kpu) {
302 List complexSlotMentionValueElements = slotMentionElement
303 .getChildren(XMLConstants.COMPLEX_SLOT_MENTION_VALUE_ELEMENT_NAME);
304 Iterator complexSlotMentionValueElementsItr = complexSlotMentionValueElements.iterator();
305
306 while (complexSlotMentionValueElementsItr.hasNext()) {
307 Element complexSlotMentionValueElement = (Element) complexSlotMentionValueElementsItr.next();
308 String complexSlotMentionValueID = complexSlotMentionValueElement.getAttribute(
309 XMLConstants.VALUE_ATTRIBUTE_NAME).getValue();
310 Frame complexSlotMentionValue = kb.getFrame(complexSlotMentionValueID);
311 slotMentionInstance.addOwnSlotValue(kpu.getMentionSlotValueSlot(), complexSlotMentionValue);
312 }
313 }
314
315 private static void readSimpleSlotMentionValues(Element slotMentionElement, Instance slotMentionInstance,
316 KnowledgeBase kb, KnowtatorProjectUtil kpu, String elementName) {
317
318 List simpleSlotMentionValueElements = slotMentionElement.getChildren(elementName);
319 Iterator simpleSlotMentionValueElementsItr = simpleSlotMentionValueElements.iterator();
320
321 while (simpleSlotMentionValueElementsItr.hasNext()) {
322 Element simpleSlotMentionValueElement = (Element) simpleSlotMentionValueElementsItr.next();
323 Attribute simpleSlotMentionValueAttribute = simpleSlotMentionValueElement
324 .getAttribute(XMLConstants.VALUE_ATTRIBUTE_NAME);
325 Object slotMentionValue = null;
326 try {
327 if (elementName.equals(XMLConstants.BOOLEAN_SLOT_MENTION_VALUE_ELEMENT_NAME)) {
328 slotMentionValue = new Boolean(simpleSlotMentionValueAttribute.getBooleanValue());
329 } else if (elementName.equals(XMLConstants.INTEGER_SLOT_MENTION_VALUE_ELEMENT_NAME)) {
330 slotMentionValue = new Integer(simpleSlotMentionValueAttribute.getIntValue());
331 } else if (elementName.equals(XMLConstants.STRING_SLOT_MENTION_VALUE_ELEMENT_NAME)) {
332 slotMentionValue = simpleSlotMentionValueAttribute.getValue();
333 } else if (elementName.equals(XMLConstants.FLOAT_SLOT_MENTION_VALUE_ELEMENT_NAME)) {
334 slotMentionValue = new Float(simpleSlotMentionValueAttribute.getFloatValue());
335 }
336 } catch (DataConversionException dce) {
337 slotMentionValue = simpleSlotMentionValueAttribute.getValue();
338 }
339
340 slotMentionInstance.addOwnSlotValue(kpu.getMentionSlotValueSlot(), slotMentionValue);
341 }
342 }
343
344 /**
345 * This method goes back through classMention or instanceMention elements
346 * and adds the slot mentions to the class mentions. In contrast the method
347 * readSlotMentions, reads in all the slotMentions so that they are in the
348 * knowledge base when this method is run.
349 *
350 * @param root
351 * @param kb
352 * @param kpu
353 * @param elementName
354 */
355 private static void readMentionSlots(Element root, KnowledgeBase kb, KnowtatorProjectUtil kpu, String elementName) {
356 List mentionElements = root.getChildren(elementName);
357 Iterator mentionElementsItr = mentionElements.iterator();
358
359 while (mentionElementsItr.hasNext()) {
360 Element mentionElement = (Element) mentionElementsItr.next();
361 Attribute mentionIDAttribute = mentionElement.getAttribute(XMLConstants.ID_ATTRIBUTE_NAME);
362 String mentionID = mentionIDAttribute.getValue();
363 Instance mentionInstance = kb.getInstance(mentionID);
364
365 List hasSlotMentionElements = mentionElement.getChildren(XMLConstants.HAS_SLOT_MENTION_ELEMENT_NAME);
366 Iterator hasSlotMentionElementsItr = hasSlotMentionElements.iterator();
367 while (hasSlotMentionElementsItr.hasNext()) {
368 Element hasSlotMentionElement = (Element) hasSlotMentionElementsItr.next();
369 Attribute slotMentionIDAttribute = hasSlotMentionElement.getAttribute(XMLConstants.ID_ATTRIBUTE_NAME);
370 String slotMentionID = slotMentionIDAttribute.getValue();
371 Instance slotMention = kb.getInstance(slotMentionID);
372 mentionInstance.addOwnSlotValue(kpu.getSlotMentionSlot(), slotMention);
373 }
374 }
375 }
376
377 private static void readAnnotations(Element root, KnowledgeBase kb, KnowtatorProjectUtil kpu,
378 AnnotationUtil annotationUtil, SimpleInstance textSourceInstance) throws KnowtatorXMLException {
379 List annotationElements = root.getChildren(XMLConstants.ANNOTATION_ELEMENT_NAME);
380 Iterator annotationElementsItr = annotationElements.iterator();
381
382 while (annotationElementsItr.hasNext()) {
383 Element annotationElement = (Element) annotationElementsItr.next();
384
385 SimpleInstance mentionInstance = null;
386 SimpleInstance annotatorInstance = null;
387 List<Span> spans = new ArrayList<Span>();
388 String spannedText = null;
389 String creationDate = null;
390
391 Element mentionElement = annotationElement.getChild(XMLConstants.MENTION_ELEMENT_NAME);
392 if (mentionElement != null) {
393 String mentionID = mentionElement.getAttribute(XMLConstants.ID_ATTRIBUTE_NAME).getValue();
394 mentionInstance = kb.getSimpleInstance(mentionID);
395 }
396
397 Element annotatorElement = annotationElement.getChild(XMLConstants.ANNOTATOR_ELEMENT_NAME);
398 if (annotatorElement != null) {
399 String annotatorID = annotatorElement.getAttribute(XMLConstants.ID_ATTRIBUTE_NAME).getValue();
400 annotatorInstance = kb.getSimpleInstance(annotatorID);
401 }
402
403 List spanElements = annotationElement.getChildren(XMLConstants.SPAN_ELEMENT_NAME);
404 Iterator spanElementsItr = spanElements.iterator();
405
406 try {
407 while (spanElementsItr.hasNext()) {
408 Element spanElement = (Element) spanElementsItr.next();
409 int spanStart = spanElement.getAttribute(XMLConstants.SPAN_START_ATTRIBUTE_NAME).getIntValue();
410 int spanEnd = spanElement.getAttribute(XMLConstants.SPAN_END_ATTRIBUTE_NAME).getIntValue();
411 Span span = new Span(spanStart, spanEnd);
412 spans.add(span);
413 }
414 } catch (DataConversionException dce) {
415 throw new KnowtatorXMLException(dce);
416 }
417
418 Element spannedTextElement = annotationElement.getChild(XMLConstants.SPANNED_TEXT_ELEMENT_NAME);
419 if (spannedTextElement != null)
420 spannedText = spannedTextElement.getText();
421
422 Element creationDateElement = annotationElement.getChild(XMLConstants.CREATION_DATE_ELEMENT_NAME);
423 if (creationDateElement != null) {
424 creationDate = creationDateElement.getText();
425 }
426
427 try {
428 SimpleInstance annotation = annotationUtil.createAnnotation(mentionInstance, annotatorInstance, spans,
429 spannedText, textSourceInstance, null, creationDate);
430 Element commentElement = annotationElement.getChild(XMLConstants.COMMENT_ELEMENT_NAME);
431 if (commentElement != null) {
432 String comment = commentElement.getText();
433 annotationUtil.setComment(annotation, comment);
434 }
435 } catch (TextSourceAccessException tsae) {
436 throw new KnowtatorXMLException(tsae);
437 }
438 }
439 }
440
441 private static List<Element> getSlotMentionElements(Element root) {
442 List<Element> slotMentionElements = new ArrayList<Element>();
443
444 _addSlotMentionElements(root, XMLConstants.COMPLEX_SLOT_MENTION_ELEMENT_NAME, slotMentionElements);
445 _addSlotMentionElements(root, XMLConstants.BOOLEAN_SLOT_MENTION_ELEMENT_NAME, slotMentionElements);
446 _addSlotMentionElements(root, XMLConstants.FLOAT_SLOT_MENTION_ELEMENT_NAME, slotMentionElements);
447 _addSlotMentionElements(root, XMLConstants.INTEGER_SLOT_MENTION_ELEMENT_NAME, slotMentionElements);
448 _addSlotMentionElements(root, XMLConstants.STRING_SLOT_MENTION_ELEMENT_NAME, slotMentionElements);
449 return slotMentionElements;
450 }
451
452 private static void _addSlotMentionElements(Element root, String elementName, List<Element> slotMentionElements) {
453 List elements = root.getChildren(elementName);
454 for (int i = 0; i < elements.size(); i++) {
455 slotMentionElements.add((Element) elements.get(i));
456 }
457 }
458
459 }