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; 030 031 import java.util.ArrayList; 032 import java.util.Collection; 033 import java.util.Collections; 034 import java.util.Comparator; 035 import java.util.HashMap; 036 import java.util.HashSet; 037 import java.util.LinkedHashSet; 038 import java.util.List; 039 import java.util.Set; 040 import java.util.TreeSet; 041 042 import javax.swing.JOptionPane; 043 044 import org.apache.log4j.Logger; 045 046 import edu.stanford.smi.protege.event.FrameAdapter; 047 import edu.stanford.smi.protege.event.FrameEvent; 048 import edu.stanford.smi.protege.model.Cls; 049 import edu.stanford.smi.protege.model.Frame; 050 import edu.stanford.smi.protege.model.FrameID; 051 import edu.stanford.smi.protege.model.Instance; 052 import edu.stanford.smi.protege.model.KnowledgeBase; 053 import edu.stanford.smi.protege.model.SimpleInstance; 054 import edu.stanford.smi.protege.model.Slot; 055 import edu.stanford.smi.protege.ui.FrameComparator; 056 import edu.uchsc.ccp.knowtator.event.AnnotationCreatedEvent; 057 import edu.uchsc.ccp.knowtator.event.AnnotationCreatedListener; 058 import edu.uchsc.ccp.knowtator.event.CurrentAnnotationsChangeEvent; 059 import edu.uchsc.ccp.knowtator.event.CurrentAnnotationsChangedListener; 060 import edu.uchsc.ccp.knowtator.event.EventHandler; 061 import edu.uchsc.ccp.knowtator.event.RefreshAnnotationsDisplayListener; 062 import edu.uchsc.ccp.knowtator.textsource.TextSource; 063 import edu.uchsc.ccp.knowtator.textsource.TextSourceAccessException; 064 import edu.uchsc.ccp.knowtator.textsource.TextSourceChangeEvent; 065 import edu.uchsc.ccp.knowtator.textsource.TextSourceChangeListener; 066 import edu.uchsc.ccp.knowtator.ui.ColorFrameRenderer; 067 import edu.uchsc.ccp.knowtator.ui.KnowtatorTextPane; 068 import edu.uchsc.ccp.knowtator.ui.TextViewer; 069 import edu.uchsc.ccp.knowtator.util.ConsensusAnnotations; 070 import edu.uchsc.ccp.knowtator.util.ConsensusException; 071 import edu.uchsc.ccp.knowtator.util.ConsensusSet; 072 073 public class KnowtatorManager implements CurrentAnnotationsChangedListener, AnnotationCreatedListener, 074 TextSourceChangeListener { 075 private KnowledgeBase kb; 076 077 private KnowtatorProjectUtil kpu; 078 079 private AnnotationUtil annotationUtil; 080 081 private TextSourceUtil textSourceUtil; 082 083 private SpanUtil spanUtil; 084 085 private FilterUtil filterUtil; 086 087 private MentionUtil mentionUtil; 088 089 private DisplayColors displayColors; 090 091 private BrowserTextUtil browserTextUtil; 092 093 private KnowtatorTextPane textPane; 094 095 private TextViewer textViewer; 096 097 /* 098 * key is a class or instance that is annotated, value is a list of the 099 * annotations for that class or instance. Only annotations in 100 * partiallyFilteredAnnotations are included. 101 */ 102 java.util.Map<Frame, List<SimpleInstance>> frameAnnotationsMap; 103 104 ColorFrameRenderer renderer; 105 106 List<SimpleInstance> filteredAnnotations; 107 108 List<SimpleInstance> visibleFilteredAnnotations; 109 110 List<SimpleInstance> partiallyFilteredAnnotations; 111 112 List<SimpleInstance> selectableFilteredAnnotations; 113 114 Cls selectedCls; 115 116 SimpleInstance selectedAnnotation; 117 118 SimpleInstance lastSelectedAnnotation; // the selectedAnnotation if not 119 120 // null else the last non-null 121 // selectedAnnotation 122 123 List<Span> selectedSpans; 124 125 Comparator<SimpleInstance> annotationComparator; 126 127 Frame fastAnnotateFrame = null; 128 129 /** Set of Frames (classes) that will be shown in the fast annotate tool bar */ 130 Set<FrameID> fastAnnotateFrameSet = null; 131 132 boolean fastAnnotateMode = false; 133 134 SimpleInstance selectedFilter = null; 135 136 boolean consensusMode = false; 137 138 ConsensusSet consensusSet = null; 139 140 Logger logger = Logger.getLogger(KnowtatorManager.class); 141 142 public KnowtatorManager(KnowtatorProjectUtil kpu) { 143 this.kpu = kpu; 144 this.kb = kpu.getKnowledgeBase(); 145 146 annotationUtil = new AnnotationUtil(this); 147 textSourceUtil = new TextSourceUtil(annotationUtil, kpu); 148 annotationUtil.setTextSourceUtil(textSourceUtil); 149 mentionUtil = new MentionUtil(kpu); 150 annotationUtil.setMentionUtil(mentionUtil); 151 mentionUtil.setAnnotationUtil(annotationUtil); 152 filterUtil = new FilterUtil(this); 153 displayColors = new DisplayColors(this); 154 browserTextUtil = new BrowserTextUtil(annotationUtil, mentionUtil, kpu); 155 spanUtil = new SpanUtil(this); 156 157 frameAnnotationsMap = new HashMap<Frame, List<SimpleInstance>>(); 158 renderer = new ColorFrameRenderer(this); 159 160 filteredAnnotations = new ArrayList<SimpleInstance>(); 161 visibleFilteredAnnotations = new ArrayList<SimpleInstance>(); 162 partiallyFilteredAnnotations = new ArrayList<SimpleInstance>(); 163 selectableFilteredAnnotations = new ArrayList<SimpleInstance>(); 164 165 EventHandler.getInstance().setKnowtatorManager(this); 166 EventHandler.getInstance().addCurrentAnnotationsChangedListener(this); 167 EventHandler.getInstance().addAnnotationCreatedListener(this); 168 169 fastAnnotateFrameSet = new LinkedHashSet<FrameID>(); 170 initListener(); 171 } 172 173 private void initListener() { 174 logger.debug(""); 175 176 SimpleInstance configuration = ProjectSettings.getActiveConfiguration(kb.getProject()); 177 configuration.addFrameListener(new FrameAdapter() { 178 public void ownSlotValueChanged(FrameEvent frameEvent) { 179 updateFilter(frameEvent.getSlot()); 180 } 181 182 public void ownSlotAdded(FrameEvent frameEvent) { 183 updateFilter(frameEvent.getSlot()); 184 } 185 186 public void ownSlotRemoved(FrameEvent frameEvent) { 187 updateFilter(frameEvent.getSlot()); 188 } 189 190 private void updateFilter(Slot slot) { 191 if (slot.equals(kpu.getSelectedFilterSlot())) { 192 SimpleInstance configuration = ProjectSettings.getActiveConfiguration(kpu.kb.getProject()); 193 SimpleInstance configurationFilter = (SimpleInstance) configuration.getDirectOwnSlotValue(kpu 194 .getSelectedFilterSlot()); 195 // prevent infinite loop 196 if (configurationFilter != null 197 && (selectedFilter == null || !selectedFilter.equals(configurationFilter))) { 198 try { 199 setSelectedFilter(configurationFilter); 200 } catch (ConsensusException ce) { 201 ce.printStackTrace(); 202 } 203 } 204 } 205 } 206 }); 207 208 } 209 210 public KnowledgeBase getKnowledgeBase() { 211 return kb; 212 } 213 214 public void setNotifyText(String text) { 215 logger.debug(""); 216 EventHandler.getInstance().fireNotifyTextChanged(text); 217 } 218 219 public List<SimpleInstance> getCurrentAnnotationsForFrame(Frame frame) { 220 logger.debug(""); 221 List<SimpleInstance> annotations = frameAnnotationsMap.get(frame); 222 if (annotations == null) 223 return Collections.emptyList(); 224 return Collections.unmodifiableList(frameAnnotationsMap.get(frame)); 225 } 226 227 public int getCurrentAnnotationCountForFrame(Frame frame) { 228 int returnValue = 0; 229 if (frameAnnotationsMap.containsKey(frame)) 230 returnValue = frameAnnotationsMap.get(frame).size(); 231 logger.debug("count = " + returnValue); 232 return returnValue; 233 } 234 235 public int getConsolidatedAnnotationCountForFrame(Frame frame) { 236 logger.debug(""); 237 int returnValue = 0; 238 if (frameAnnotationsMap.containsKey(frame)) { 239 List<SimpleInstance> frameAnnotations = frameAnnotationsMap.get(frame); 240 SimpleInstance teamAnnotator = consensusSet.getTeamAnnotator(); 241 for (SimpleInstance frameAnnotation : frameAnnotations) { 242 if (teamAnnotator.equals(annotationUtil.getAnnotator(frameAnnotation))) 243 returnValue++; 244 } 245 } 246 return returnValue; 247 } 248 249 /** 250 * @return the next annotation 251 * @see #selectNextAnnotation() 252 */ 253 public SimpleInstance getNextAnnotation() { 254 logger.debug(""); 255 return getNextPreviousAnnotation(1); 256 } 257 258 /** 259 * 260 * @return the previous annotation 261 * @see #selectPreviousAnnotation 262 */ 263 public SimpleInstance getPreviousAnnotation() { 264 logger.debug(""); 265 return getNextPreviousAnnotation(-1); 266 } 267 268 private SimpleInstance getNextPreviousAnnotation(int delta) { 269 logger.debug(""); 270 SimpleInstance mention = annotationUtil.getMention(selectedAnnotation); 271 Frame mentionFrame = mentionUtil.getMentionFrame(mention); 272 if (mentionFrame != null) { 273 List<SimpleInstance> frameAnnotations = frameAnnotationsMap.get(mentionFrame); 274 Comparator<SimpleInstance> annotationComparator = getAnnotationComparator(); 275 if (annotationComparator != null) 276 Collections.sort(frameAnnotations, annotationComparator); 277 else 278 Collections.sort(frameAnnotations, new FrameComparator()); 279 280 for (int i = 0; i < frameAnnotations.size(); i++) { 281 SimpleInstance frameAnnotation = frameAnnotations.get(i); 282 if (frameAnnotation.equals(selectedAnnotation)) { 283 if (i + delta >= 0 && i + delta < frameAnnotations.size()) 284 return frameAnnotations.get(i + delta); 285 } 286 } 287 if (frameAnnotations.size() > 0) { 288 if (delta > 0) 289 return frameAnnotations.get(0); 290 else 291 return frameAnnotations.get(frameAnnotations.size() - 1); 292 } 293 } 294 return selectedAnnotation; 295 } 296 297 /** 298 * Returns the annotations for the current text source that satisfy the 299 * currently selected filter. 300 */ 301 302 public List<SimpleInstance> getCurrentFilteredAnnotations() { 303 logger.debug(""); 304 if (filteredAnnotations == null) 305 return Collections.emptyList(); 306 return Collections.unmodifiableList(filteredAnnotations); 307 } 308 309 public List<SimpleInstance> getVisibleFilteredAnnotations() { 310 if (visibleFilteredAnnotations == null) 311 return Collections.emptyList(); 312 return Collections.unmodifiableList(visibleFilteredAnnotations); 313 } 314 315 /** 316 * returns the annotations for the current text source that satisfy the 317 * currently selected filter ignoring the type constraint. 318 */ 319 public List<SimpleInstance> getCurrentPartiallyFilteredAnnotations() { 320 logger.debug(""); 321 if (partiallyFilteredAnnotations == null) 322 return Collections.emptyList(); 323 return Collections.unmodifiableList(partiallyFilteredAnnotations); 324 } 325 326 public List<SimpleInstance> getCurrentSelectableFilteredAnnotations() { 327 logger.debug(""); 328 if (selectableFilteredAnnotations == null) 329 return Collections.emptyList(); 330 return Collections.unmodifiableList(selectableFilteredAnnotations); 331 } 332 333 public void updateCurrentAnnotations() { 334 logger.debug(""); 335 TextSource currentTextSource = textSourceUtil.getCurrentTextSource(); 336 if (currentTextSource == null) 337 return; 338 Collection<SimpleInstance> annotations = annotationUtil.getAnnotations(currentTextSource); 339 filteredAnnotations.clear(); 340 visibleFilteredAnnotations.clear(); 341 partiallyFilteredAnnotations.clear(); 342 selectableFilteredAnnotations.clear(); 343 344 if (annotations != null) { 345 SimpleInstance currentFilter = getSelectedFilter(); 346 if (currentFilter != null) { 347 partiallyFilteredAnnotations.addAll(filterUtil.filterAnnotations(annotations, currentFilter, true)); 348 filteredAnnotations.addAll(filterUtil.filterAnnotations(partiallyFilteredAnnotations, currentFilter)); 349 selectableFilteredAnnotations.addAll(filterUtil.filterAnnotations(filteredAnnotations, currentFilter, 350 false, true)); 351 } else { 352 filteredAnnotations.addAll(annotations); 353 partiallyFilteredAnnotations.addAll(annotations); 354 selectableFilteredAnnotations.addAll(annotations); 355 } 356 } 357 358 EventHandler.getInstance().fireCurrentAnnotationsChanged(); 359 SimpleInstance selectedAnnotation = getSelectedAnnotation(); 360 if (!filteredAnnotations.contains(selectedAnnotation)) 361 setSelectedAnnotation(null); 362 Collections.sort(filteredAnnotations, spanUtil.comparator(browserTextUtil.comparator())); 363 updateVisibleFilteredAnnotations(); 364 refreshAnnotationsDisplay(true); 365 } 366 367 /* 368 * this method would be faster if we did a binary search for the first 369 * visible annotation. However, this will take a bit of doing because there 370 * needs to be a comparator for the SimpleInstance's that make use of the 371 * spans 372 */ 373 public void updateVisibleFilteredAnnotations() { 374 visibleFilteredAnnotations.clear(); 375 Span visibleSpan = getVisibleSpan(); 376 if (visibleSpan == null) 377 return; 378 logger 379 .debug("visibleSpan = " + visibleSpan + " filteredAnnotations = " 380 + selectableFilteredAnnotations.size()); 381 382 for (SimpleInstance filteredAnnotation : selectableFilteredAnnotations) { 383 List<Span> spans = annotationUtil.getSpans(filteredAnnotation); 384 if (spans != null && spans.size() > 0) { 385 if (visibleSpan.contains(spans.get(0))) { 386 visibleFilteredAnnotations.add(filteredAnnotation); 387 } 388 } 389 } 390 // we sort them by span length because that is how KnowtatorTextPane 391 // needs them 392 // so that spans are highlighted with the correct precedence. 393 // we do it here because then we don't have to do it as often. 394 Collections.sort(visibleFilteredAnnotations, spanUtil.lengthComparator()); 395 logger.debug("visible filtered annotations = " + visibleFilteredAnnotations.size()); 396 } 397 398 /** 399 * This is the preferred way to obtain the currently selected cls (i.e. the 400 * cls selected in the annotation schema pane/tree.) 401 * 402 * @return the currently selected cls. 403 */ 404 public Cls getSelectedCls() { 405 logger.debug(""); 406 return selectedCls; 407 } 408 409 /** 410 * This is the preferred way to set the curently selected cls (i.e. the cls 411 * that is highlighted in the annotation schema pane/tree.) This method will 412 * call the appropriate event firing method in EventHandler. 413 * 414 * @param cls 415 */ 416 public void setSelectedCls(Cls cls) { 417 logger.debug(""); 418 logger.debug("selcected cls = \"" + cls.getBrowserText() + "\""); 419 selectedCls = cls; 420 EventHandler.getInstance().fireSelectedClsChanged(cls); 421 } 422 423 /** 424 * This is the preferred way to obtain the currently selected annotation 425 * 426 * @return the currently selected annotation. 427 */ 428 public SimpleInstance getSelectedAnnotation() { 429 logger.debug(""); 430 return selectedAnnotation; 431 } 432 433 /** 434 * @return the currently selected annotation if it is not null. Otherwise, 435 * it returns the previously selected annotation or null if there 436 * has never been an annotation selected. 437 */ 438 public SimpleInstance getLastSelectedAnnotation() { 439 logger.debug(""); 440 return lastSelectedAnnotation; 441 } 442 443 /** 444 * This is the preferred way to set the curently selected annotation. This 445 * method will call the appropriate event firing method in EventHandler. 446 * 447 * @param annotation 448 */ 449 public void setSelectedAnnotation(SimpleInstance annotation) { 450 logger.debug("selected annotation=\"" + browserTextUtil.getBrowserText(annotation, 100) + "\""); 451 selectedAnnotation = annotation; 452 if (annotation != null) 453 lastSelectedAnnotation = annotation; 454 EventHandler.getInstance().fireSelectedAnnotationChanged(annotation); 455 refreshAnnotationsDisplay(true); 456 setNotifyText(getBrowserTextUtil().getBrowserText(annotation)); 457 } 458 459 /** 460 * The "next" annotation is defined as the annotation (if it exists) that is 461 * of the same type as the currently selected annotation that is 'next' 462 * according to the sort order defined by the currently selected comparator. 463 */ 464 public void selectNextAnnotation() { 465 logger.debug(""); 466 setSelectedAnnotation(getNextAnnotation()); 467 } 468 469 /** 470 * The "previous" annotation is defined as the annotation (if it exists) 471 * that is of the same type as the currently selected annotation that is 472 * 'next' according to the sort order defined by the currently selected 473 * comparator. 474 */ 475 public void selectPreviousAnnotation() { 476 logger.debug(""); 477 setSelectedAnnotation(getPreviousAnnotation()); 478 } 479 480 /** 481 * This is the preferred way to obtain the currently selected spans (i.e. 482 * the spans selected in the text pane.) 483 * 484 * @return a list of currenly selected spans highlighted by the user 485 */ 486 public List<Span> getSelectedSpans() { 487 logger.debug(""); 488 if (selectedSpans == null) 489 return Collections.emptyList(); 490 return Collections.unmodifiableList(selectedSpans); 491 } 492 493 /** 494 * This is the preferred way to set the currently selected spans. This 495 * method will call the appropriate event firing method in EventHandler. 496 * 497 * @param selectedSpans 498 * @see EventHandler#fireSelectedSpanChanged(List) 499 */ 500 public void setSelectedSpans(List<Span> selectedSpans) { 501 if (selectedSpans == null) { 502 this.selectedSpans.clear(); 503 } else { 504 logger.debug(""); 505 if (logger.isDebugEnabled()) { 506 StringBuffer sb = new StringBuffer(); 507 for (Span span : selectedSpans) 508 sb.append(" " + span.getStart() + "|" + span.getEnd()); 509 logger.debug(sb.toString()); 510 } 511 this.selectedSpans = new ArrayList<Span>(selectedSpans); 512 } 513 EventHandler.getInstance().fireSelectedSpanChanged(selectedSpans); 514 } 515 516 public List<SimpleInstance> getColorAssignments() { 517 logger.debug(""); 518 SimpleInstance configuration = ProjectSettings.getActiveConfiguration(kb.getProject()); 519 Collection<SimpleInstance> colorAssignments = (Collection<SimpleInstance>) configuration 520 .getDirectOwnSlotValues(kpu.getColorAssignmentsSlot()); 521 List<SimpleInstance> returnValues = new ArrayList<SimpleInstance>(); 522 if (colorAssignments != null) { 523 returnValues.addAll(colorAssignments); 524 } 525 return returnValues; 526 } 527 528 public List<Cls> getRootClses() { 529 logger.debug(""); 530 SimpleInstance configuration = ProjectSettings.getActiveConfiguration(kb.getProject()); 531 Collection<Cls> rootClses = (Collection<Cls>) configuration.getDirectOwnSlotValues(kpu.getRootClsesSlot()); 532 List<Cls> returnValues = new ArrayList<Cls>(); 533 if (rootClses == null || rootClses.size() == 0) { 534 returnValues.add(kb.getRootCls()); 535 } else { 536 returnValues.addAll(rootClses); 537 } 538 return returnValues; 539 } 540 541 public SimpleInstance getSelectedAnnotator() { 542 logger.debug(""); 543 SimpleInstance configuration = ProjectSettings.getActiveConfiguration(kb.getProject()); 544 return (SimpleInstance) configuration.getDirectOwnSlotValue(kpu.getSelectedAnnotatorSlot()); 545 } 546 547 public void setSelectedAnnotator(SimpleInstance annotator) { 548 logger.debug("selected annotator = \"" + annotator.getBrowserText() + "\""); 549 SimpleInstance configuration = ProjectSettings.getActiveConfiguration(kb.getProject()); 550 configuration.setDirectOwnSlotValue(kpu.getSelectedAnnotatorSlot(), annotator); 551 } 552 553 public SimpleInstance getSelectedAnnotationSet() { 554 logger.debug(""); 555 SimpleInstance configuration = ProjectSettings.getActiveConfiguration(kb.getProject()); 556 return (SimpleInstance) configuration.getDirectOwnSlotValue(kpu.getSelectedAnnotationSetSlot()); 557 } 558 559 public void setSelectedAnnotationSet(SimpleInstance annotationSet) { 560 logger.debug("selected annotation set = \"" + annotationSet.getBrowserText() + "\""); 561 SimpleInstance configuration = ProjectSettings.getActiveConfiguration(kb.getProject()); 562 configuration.setDirectOwnSlotValue(kpu.getSelectedAnnotationSetSlot(), annotationSet); 563 } 564 565 public String getTokenRegex() { 566 logger.debug(""); 567 SimpleInstance configuration = ProjectSettings.getActiveConfiguration(kb.getProject()); 568 return (String) configuration.getDirectOwnSlotValue(kpu.getTokenRegexSlot()); 569 } 570 571 public void currentAnnotationsChanged(CurrentAnnotationsChangeEvent cace) { 572 logger.debug(""); 573 frameAnnotationsMap.clear(); 574 List<SimpleInstance> currentFilteredAnnotations = cace.getFilteredAnnotations(); 575 logger.debug("currentFilteredAnnotations.size()=" + currentFilteredAnnotations.size()); 576 for (SimpleInstance annotation : currentFilteredAnnotations) { 577 SimpleInstance mention = annotationUtil.getMention(annotation); 578 Frame annotatedFrame = mentionUtil.getMentionFrame(mention); 579 if (!frameAnnotationsMap.containsKey(annotatedFrame)) 580 frameAnnotationsMap.put(annotatedFrame, new ArrayList<SimpleInstance>()); 581 frameAnnotationsMap.get(annotatedFrame).add(annotation); 582 } 583 } 584 585 public void annotationCreated(AnnotationCreatedEvent event) { 586 logger.debug(""); 587 SimpleInstance annotation = event.getCreatedAnnotation(); 588 SimpleInstance mention = annotationUtil.getMention(annotation); 589 Frame annotatedFrame = mentionUtil.getMentionFrame(mention); 590 if (!frameAnnotationsMap.containsKey(annotatedFrame)) 591 frameAnnotationsMap.put(annotatedFrame, new ArrayList<SimpleInstance>()); 592 frameAnnotationsMap.get(annotatedFrame).add(annotation); 593 594 int insertionPoint = Collections.binarySearch(filteredAnnotations, annotation, spanUtil 595 .comparator(browserTextUtil.comparator())); 596 if (insertionPoint < 0) { 597 insertionPoint = -(insertionPoint + 1); 598 } 599 filteredAnnotations.add(insertionPoint, annotation); 600 partiallyFilteredAnnotations.add(annotation); 601 selectableFilteredAnnotations.add(annotation); 602 visibleFilteredAnnotations.add(annotation); 603 } 604 605 /** 606 * @param scrollToSelection please see javadoc for RefreshAnnotationsDisplayListener 607 * @see RefreshAnnotationsDisplayListener#refreshAnnotationsDisplay(boolean) 608 */ 609 public void refreshAnnotationsDisplay(boolean scrollToSelection) { 610 logger.debug(""); 611 EventHandler.getInstance().fireRefreshAnnotationsDisplay(scrollToSelection); 612 } 613 614 public void deleteSelectedAnnotation() { 615 logger.debug(""); 616 SimpleInstance nextAnnotation = getNextAnnotation(); 617 if (nextAnnotation.equals(getSelectedAnnotation())) { 618 nextAnnotation = null; 619 } 620 deleteAnnotation(getSelectedAnnotation()); 621 setSelectedAnnotation(nextAnnotation); 622 } 623 624 public void deleteAnnotation(SimpleInstance annotation) { 625 logger.debug(""); 626 if (annotation != null) { 627 annotationUtil.deleteMention((SimpleInstance) annotation); 628 kb.deleteInstance(annotation); 629 filteredAnnotations.remove(annotation); 630 partiallyFilteredAnnotations.remove(annotation); 631 selectableFilteredAnnotations.remove(annotation); 632 visibleFilteredAnnotations.remove(annotation); 633 EventHandler.getInstance().fireCurrentAnnotationsChanged(); 634 } 635 } 636 637 // TODO what should the cls of the new annotation be? 638 public void duplicateSelectedAnnotation() { 639 logger.debug(""); 640 SimpleInstance annotation = getSelectedAnnotation(); 641 if (annotation != null) { 642 logger.debug("creating duplicate annotation"); 643 SimpleInstance duplicateAnnotation; 644 try { 645 SimpleInstance mention = mentionUtil.createMention(null); 646 List<Span> spans = annotationUtil.getSpans(annotation); 647 648 duplicateAnnotation = annotationUtil.createAnnotation(mention, getSelectedAnnotator(), spans, 649 textSourceUtil.getCurrentTextSource(), getSelectedAnnotationSet()); 650 if (duplicateAnnotation == null) 651 return; 652 653 EventHandler.getInstance().fireAnnotationCreated(duplicateAnnotation); 654 setSelectedAnnotation(duplicateAnnotation); 655 refreshAnnotationsDisplay(true); 656 } 657 // TODO why is the parent component of this dialog null? 658 catch (TextSourceAccessException tsae) { 659 JOptionPane.showMessageDialog(null, "There was a problem retrieving the text from the text source: " 660 + tsae.getMessage(), "Text Source Error", JOptionPane.ERROR_MESSAGE); 661 } 662 } 663 } 664 665 /** 666 * calls createAnnotation(selectedClsOrInstance, true) 667 * 668 * @param selectedClsOrInstance 669 * - a Cls or Instance frame in Protege that specifies the type 670 * of annotation to create. all other settings for the new 671 * annotation will be derived from the current settings and 672 * selections. 673 * @return the created annotation 674 */ 675 public SimpleInstance createAnnotation(Instance selectedClsOrInstance) { 676 logger.debug(""); 677 return createAnnotation(selectedClsOrInstance, true); 678 } 679 680 /** 681 * @param selectedClsOrInstance 682 * @param selectCreatedAnnotation 683 * determines whether the newly created annotation should be 684 * selected. If the new annotation is a slot filler, then you 685 * might not want it to be selected as the annotation of focus 686 * for Knowtator. 687 * @return the created annotation or null if something went wrong. 688 */ 689 public SimpleInstance createAnnotation(Instance selectedClsOrInstance, boolean selectCreatedAnnotation) { 690 logger.debug("creating annotation for \"" + selectedClsOrInstance.getBrowserText() + "\""); 691 SimpleInstance createdAnnotation; 692 try { 693 SimpleInstance mention = mentionUtil.createMention(selectedClsOrInstance); 694 List<Span> selectedSpans = getSelectedSpans(); 695 696 createdAnnotation = annotationUtil.createAnnotation(mention, getSelectedAnnotator(), selectedSpans, 697 textSourceUtil.getCurrentTextSource(), getSelectedAnnotationSet()); 698 if (createdAnnotation == null) 699 return null; 700 701 EventHandler.getInstance().fireAnnotationCreated(createdAnnotation); 702 if (selectCreatedAnnotation) 703 setSelectedAnnotation(createdAnnotation); 704 705 refreshAnnotationsDisplay(true); 706 return createdAnnotation; 707 } 708 // TODO why is the parent component of this dialog null? 709 catch (TextSourceAccessException tsae) { 710 JOptionPane.showMessageDialog(null, "There was a problem retrieving the text from the text source: " 711 + tsae.getMessage(), "Text Source Error", JOptionPane.ERROR_MESSAGE); 712 return null; 713 } 714 } 715 716 public AnnotationUtil getAnnotationUtil() { 717 logger.debug(""); 718 return annotationUtil; 719 } 720 721 public BrowserTextUtil getBrowserTextUtil() { 722 logger.debug(""); 723 return browserTextUtil; 724 } 725 726 public DisplayColors getDisplayColors() { 727 logger.debug(""); 728 return displayColors; 729 } 730 731 public FilterUtil getFilterUtil() { 732 logger.debug(""); 733 return filterUtil; 734 } 735 736 public MentionUtil getMentionUtil() { 737 logger.debug(""); 738 return mentionUtil; 739 } 740 741 public SpanUtil getSpanUtil() { 742 logger.debug(""); 743 return spanUtil; 744 } 745 746 public TextSourceUtil getTextSourceUtil() { 747 logger.debug(""); 748 return textSourceUtil; 749 } 750 751 public KnowtatorProjectUtil getKnowtatorProjectUtil() { 752 logger.debug(""); 753 return kpu; 754 } 755 756 public ColorFrameRenderer getRenderer() { 757 logger.debug(""); 758 return renderer; 759 } 760 761 public KnowtatorTextPane getTextPane() { 762 logger.debug(""); 763 return textPane; 764 } 765 766 public void setTextPane(KnowtatorTextPane textPane) { 767 logger.debug(""); 768 this.textPane = textPane; 769 } 770 771 public Comparator<SimpleInstance> getAnnotationComparator() { 772 logger.debug(""); 773 return annotationComparator; 774 } 775 776 public Comparator<SimpleInstance> getPositionComparator(SimpleInstance annotation) { 777 logger.debug(""); 778 return textViewer.comparator(annotation); 779 } 780 781 public void setAnnotationComparator(Comparator<SimpleInstance> annotationComparator) { 782 logger.debug(""); 783 this.annotationComparator = annotationComparator; 784 } 785 786 /** 787 * 788 * @return the fast annotation cls. May return null if it has not been set 789 * yet (or set to null). 790 */ 791 public Frame getFastAnnotateFrame() { 792 logger.debug(""); 793 return fastAnnotateFrame; 794 } 795 796 public void setFastAnnotateFrame(Frame fastAnnotateFrame) { 797 logger.debug(""); 798 this.fastAnnotateFrame = fastAnnotateFrame; 799 if (fastAnnotateFrame != null) { 800 fastAnnotateFrameSet.add(fastAnnotateFrame.getFrameID()); 801 } 802 803 EventHandler.getInstance().fireFastAnnotateAddCls(fastAnnotateFrame); 804 EventHandler.getInstance().fireFastAnnotateClsChange(); 805 } 806 807 public void startFastAnnotate() { 808 logger.debug(""); 809 fastAnnotateMode = true; 810 EventHandler.getInstance().fireFastAnnotateStart(); 811 } 812 813 /** 814 * This method allows you to start fast annotation mode and set the fast 815 * annotation class in one convenient method. If this method is called when 816 * KnowtatorManager.isFastAnnotateMode() is true, then this method has the 817 * same effect as calling setFastAnnotateCls. 818 * 819 * @param fastAnnotateFrame 820 * the class with which to annotate with 821 * @see #isFastAnnotateMode() 822 * @see #setFastAnnotateFrame(Frame) 823 */ 824 public void startFastAnnotate(Frame fastAnnotateFrame) { 825 logger.debug(""); 826 setFastAnnotateFrame(fastAnnotateFrame); 827 828 if (!fastAnnotateMode) { 829 fastAnnotateMode = true; 830 EventHandler.getInstance().fireFastAnnotateStart(); 831 } 832 } 833 834 /** 835 * Removes the given frame (class) from the fast annotate tool bar. 836 * 837 * @param frame 838 * The frame (or Cls) to be removed. 839 */ 840 public void removeFastAnnotateFrame(Frame frame) { 841 if (frame != null) { 842 fastAnnotateFrameSet.remove(frame.getFrameID()); 843 } 844 EventHandler.getInstance().fireFastAnnotateRemoveCls(frame); 845 } 846 847 /** 848 * Finds out if the given frame is being shown in the fast annotate tool 849 * bar. 850 * 851 * @param frame 852 * The frame to lookup 853 * @return True if the frame (Cls) is being shown in the tool bar, returns 854 * false otherwise. 855 */ 856 public boolean fastAnnotateToolBarContains(Frame frame) { 857 if (frame != null) { 858 return fastAnnotateFrameSet.contains(frame.getFrameID()); 859 } else { 860 return false; 861 } 862 } 863 864 public void quitFastAnnotate() { 865 logger.debug(""); 866 fastAnnotateMode = false; 867 EventHandler.getInstance().fireFastAnnotateQuit(); 868 } 869 870 public boolean isFastAnnotateMode() { 871 logger.debug(""); 872 return fastAnnotateMode; 873 } 874 875 public void setSelectedFilter(SimpleInstance filter) throws ConsensusException { 876 logger.debug(""); 877 if (filter == null) 878 logger.debug("filter == null"); 879 selectedFilter = filter; 880 SimpleInstance configuration = ProjectSettings.getActiveConfiguration(kpu.kb.getProject()); 881 configuration.setDirectOwnSlotValue(kpu.getSelectedFilterSlot(), selectedFilter); 882 updateCurrentAnnotations(); 883 884 if (!getActiveFilters().contains(filter)) 885 addActiveFilter(filter); 886 887 if (FilterUtil.isConsensusFilter(filter)) { 888 Set<SimpleInstance> consensusAnnotations = new HashSet<SimpleInstance>(getCurrentFilteredAnnotations()); 889 SimpleInstance consensusSetInstance = (SimpleInstance) getSelectedFilter().getOwnSlotValue( 890 kpu.getFilterSetSlot()); 891 consensusSet = new ConsensusSet(consensusAnnotations, consensusSetInstance, this); 892 consensusMode = true; 893 kpu.displayAnnotationAuthor(); 894 } else { 895 consensusMode = false; 896 } 897 EventHandler.getInstance().fireFilterChanged(filter, consensusMode); 898 899 // List<SimpleInstance> filterAnnotators = 900 // filterUtil.getAnnotators(filter); 901 // if(filterAnnotators != null && filterAnnotators.size() > 0) 902 // { 903 // setSelectedAnnotator(filterAnnotators.get(0)); 904 // } 905 906 } 907 908 public SimpleInstance getSelectedFilter() { 909 logger.debug(""); 910 if (selectedFilter != null) 911 return selectedFilter; 912 913 SimpleInstance configuration = ProjectSettings.getActiveConfiguration(kpu.kb.getProject()); 914 SimpleInstance configurationFilter = (SimpleInstance) configuration.getDirectOwnSlotValue(kpu 915 .getSelectedFilterSlot()); 916 if (configurationFilter == null) { 917 SimpleInstance showAllFilter = kpu.getShowAllFilter(); 918 try { 919 setSelectedFilter(showAllFilter); 920 } catch (ConsensusException ce) { 921 ce.printStackTrace(); 922 } // should never throw a consensus exception here 923 return showAllFilter; 924 } else { 925 try { 926 setSelectedFilter(configurationFilter); 927 return configurationFilter; 928 } catch (ConsensusException ce) { 929 SimpleInstance showAllFilter = kpu.getShowAllFilter(); 930 try { 931 setSelectedFilter(showAllFilter); 932 } catch (ConsensusException ex) { 933 ex.printStackTrace(); 934 } // should never throw a consensus exception here 935 return showAllFilter; 936 } 937 } 938 } 939 940 public List<SimpleInstance> getActiveFilters() { 941 logger.debug(""); 942 SimpleInstance configuration = ProjectSettings.getActiveConfiguration(kpu.kb.getProject()); 943 Collection<SimpleInstance> activeFilters = (Collection<SimpleInstance>) configuration 944 .getDirectOwnSlotValues(kpu.getActiveFiltersSlot()); 945 List<SimpleInstance> returnValues = new ArrayList<SimpleInstance>(); 946 if (activeFilters != null && activeFilters.size() > 0) { 947 returnValues.addAll(activeFilters); 948 } else { 949 SimpleInstance selectedFilter = null; 950 selectedFilter = getSelectedFilter(); 951 returnValues.add(getSelectedFilter()); 952 addActiveFilter(selectedFilter); 953 } 954 if (returnValues.size() == 0) { 955 returnValues.add(kpu.getShowAllFilter()); 956 returnValues.add(kpu.getShowNoneFilter()); 957 } 958 return returnValues; 959 } 960 961 public void setActiveFilters(Collection<SimpleInstance> activeFilters) { 962 logger.debug(""); 963 SimpleInstance configuration = ProjectSettings.getActiveConfiguration(kpu.kb.getProject()); 964 configuration.setDirectOwnSlotValues(kpu.getActiveFiltersSlot(), activeFilters); 965 } 966 967 public void addActiveFilter(SimpleInstance filter) { 968 logger.debug(""); 969 SimpleInstance configuration = ProjectSettings.getActiveConfiguration(kpu.kb.getProject()); 970 configuration.addOwnSlotValue(kpu.getActiveFiltersSlot(), filter); 971 } 972 973 public boolean getFadeUnselectedAnnotations() { 974 logger.debug(""); 975 SimpleInstance configuration = ProjectSettings.getActiveConfiguration(kpu.kb.getProject()); 976 Boolean fadeUnselectedAnnotations = (Boolean) configuration.getDirectOwnSlotValue(kpu 977 .getFadeUnselectedAnnotationsSlot()); 978 if (fadeUnselectedAnnotations == null) 979 return false; 980 return fadeUnselectedAnnotations; 981 } 982 983 public Slot getSubtextSlot() { 984 logger.debug(""); 985 SimpleInstance configuration = ProjectSettings.getActiveConfiguration(kpu.kb.getProject()); 986 return (Slot) configuration.getDirectOwnSlotValue(kpu.getSubtextSlotSlot()); 987 } 988 989 public void restartConsensusMode() throws ConsensusException { 990 logger.debug(""); 991 if (isConsensusMode()) { 992 consensusSet = ConsensusAnnotations.recreateConsensusAnnotations(textSourceUtil.getTextSourceInstance( 993 textSourceUtil.getCurrentTextSource(), false), getSelectedAnnotationSet(), this); 994 } 995 } 996 997 public boolean isConsensusMode() { 998 logger.debug(""); 999 return consensusMode; 1000 } 1001 1002 public int getConsensusModeProgress() { 1003 logger.debug(""); 1004 if (isConsensusMode()) { 1005 List<SimpleInstance> annotations = getCurrentFilteredAnnotations(); 1006 SimpleInstance teamAnnotator = consensusSet.getTeamAnnotator(); 1007 int progress = 0; 1008 for (SimpleInstance annotation : annotations) { 1009 if (teamAnnotator.equals(annotationUtil.getAnnotator(annotation))) 1010 progress++; 1011 } 1012 return progress; 1013 } else 1014 return -1; 1015 } 1016 1017 public void textSourceChanged(TextSourceChangeEvent event) { 1018 logger.debug(""); 1019 updateCurrentAnnotations(); 1020 setSelectedAnnotation(null); 1021 1022 if (isConsensusMode()) { 1023 try { 1024 Set<SimpleInstance> consensusAnnotations = new HashSet<SimpleInstance>(getCurrentFilteredAnnotations()); 1025 SimpleInstance consensusSetInstance = (SimpleInstance) getSelectedFilter().getOwnSlotValue( 1026 kpu.getFilterSetSlot()); 1027 consensusSet = new ConsensusSet(consensusAnnotations, consensusSetInstance, this); 1028 } catch (ConsensusException ce) { 1029 ce.printStackTrace(); 1030 } 1031 } 1032 refreshAnnotationsDisplay(true); 1033 } 1034 1035 public void consolidateAnnotation(SimpleInstance deleteAnnotation, SimpleInstance consolidateAnnotation) { 1036 logger.debug(""); 1037 consensusSet.consolidateAnnotations(consolidateAnnotation, deleteAnnotation); 1038 setSelectedAnnotation(consolidateAnnotation); 1039 } 1040 1041 public void setTextViewer(TextViewer textViewer) { 1042 logger.debug(""); 1043 this.textViewer = textViewer; 1044 } 1045 1046 public boolean isAnnotationVisible(SimpleInstance annotation) { 1047 logger.debug(""); 1048 return textViewer.isVisible(annotation); 1049 } 1050 1051 public Span getVisibleSpan() { 1052 logger.debug(""); 1053 if (textViewer == null) 1054 return null; 1055 return textViewer.getVisibleSpan(); 1056 } 1057 1058 public int getVerticalDistance(SimpleInstance annotation1, SimpleInstance annotation2) { 1059 logger.debug(""); 1060 return textViewer.getVerticalDistance(annotation1, annotation2); 1061 } 1062 1063 }