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 }