ctakes-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From seanfi...@apache.org
Subject svn commit: r1660963 [2/19] - in /ctakes/sandbox/timelanes: META-INF/ edu/ edu/mayo/ edu/mayo/bmi/ edu/mayo/bmi/annotation/ edu/mayo/bmi/annotation/knowtator/ org/ org/chboston/ org/chboston/cnlp/ org/chboston/cnlp/anafora/ org/chboston/cnlp/anafora/an...
Date Thu, 19 Feb 2015 18:06:17 GMT
Added: ctakes/sandbox/timelanes/edu/mayo/bmi/annotation/knowtator/KnowtatorProject.java
URL: http://svn.apache.org/viewvc/ctakes/sandbox/timelanes/edu/mayo/bmi/annotation/knowtator/KnowtatorProject.java?rev=1660963&view=auto
==============================================================================
--- ctakes/sandbox/timelanes/edu/mayo/bmi/annotation/knowtator/KnowtatorProject.java (added)
+++ ctakes/sandbox/timelanes/edu/mayo/bmi/annotation/knowtator/KnowtatorProject.java Thu Feb 19 18:06:13 2015
@@ -0,0 +1,748 @@
+package edu.mayo.bmi.annotation.knowtator;
+
+import edu.stanford.smi.protege.model.*;
+import edu.uchsc.ccp.knowtator.*;
+import edu.uchsc.ccp.knowtator.textsource.TextSource;
+import edu.uchsc.ccp.knowtator.textsource.TextSourceAccessException;
+import edu.uchsc.ccp.knowtator.textsource.TextSourceCollection;
+import edu.uchsc.ccp.knowtator.textsource.TextSourceIterator;
+import edu.uchsc.ccp.knowtator.textsource.filelines.FileLinesTextSourceCollection;
+import edu.uchsc.ccp.knowtator.textsource.files.FileTextSourceCollection;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import static edu.uchsc.ccp.knowtator.KnowtatorProjectUtil.*;
+
+/**
+ * Represents a Knowtator Project. The only public constructor takes a string
+ * parameter representing a protege-project-file-name to initialize instance
+ * variables.
+ * <p/>
+ * Intended use: Extend this class to implement the processes that you may want to
+ * apply to the loaded knowtator project.
+ *
+ * @author Vinod C Kaggal
+ */
+public class KnowtatorProject {
+   //--public Knowtator Project ----
+
+   // These two are for use for the textSourceType argument
+   public static String TEXT_SOURCE_TYPE_DIR = "dir_with_each_file_a_sourcetext";
+   public static String TEXT_SOURCE_TYPE_FILE_LINES = "file_with_each_line_a_sourcetext";
+
+   public KnowtatorProject( String protegeProjectFile, String textSourceName, String textSourceType )
+         throws TextSourceAccessException, IOException {
+      init( protegeProjectFile, textSourceName, textSourceType );
+   }
+
+   public KnowtatorProject( String protegeProjectFile, String textSourceDirName )
+         throws TextSourceAccessException, IOException {
+      init( protegeProjectFile, textSourceDirName, TEXT_SOURCE_TYPE_DIR ); // if not specified, default is a directory
+   }
+
+
+   //  //super(true, protegeProjectFile, protegeProjectFileToAddAnnosTo, textSourceDirectory);
+   //  public KnowtatorProject(boolean b, String fromProject, String toProject, String textSourceDirName)
+   //  throws TextSourceAccessException, IOException
+   //  {
+   //      init(toProject, textSourceDirName, TEXT_SOURCE_TYPE_DIR); // if not specified, default is a directory
+   //  }
+   //
+   //  //super(true, protegeProjectFile, protegeProjectFileToAddAnnosTo, textSourceDirectory, typeOfTextSource);
+   //  public KnowtatorProject(boolean b, String fromProject, String toProject, String textSourceDirName, String typeOfTextSource)
+   //  throws TextSourceAccessException, IOException
+   //  {
+   //      init(toProject, textSourceDirName, TEXT_SOURCE_TYPE_DIR); // if not specified, default is a directory
+   //  }
+
+
+   public AnnotationUtil getAnnotationUtil() {
+      return annotationUtil;
+   }
+
+   public MentionUtil getMentionUtil() {
+      return mentionUtil;
+   }
+
+   public TextSourceCollection getTsc() {
+      return tsc;
+   }
+
+   public Project getProtegeProject() {
+
+      return protegeProject;
+   }
+
+   private void init( String protegeProjectFile, String textSourceName, String textSourceType )
+         throws TextSourceAccessException, IOException {
+
+      errors = new ArrayList();
+      //directory containing text source
+
+      //load project
+      protegeProject = new Project( protegeProjectFile, errors );
+      //access knowledgebase
+      kb = protegeProject.getKnowledgeBase();
+      //create ProjectUtil
+      kpu = new KnowtatorProjectUtil( kb );
+
+      //version 3.2.1 -- start --
+      //annotationUtil = new AnnotationUtil(kpu, null);
+      //version 3.2.1 -- end ---
+      //--- version 3.3.1 --start--
+      km = new KnowtatorManager( kpu );
+      annotationUtil = new AnnotationUtil( km );
+      //--- version 3.3.1 --end--
+
+      if ( textSourceName == null ) {
+         System.out.println( "be aware textSourceName was null so not setting tsc" );
+      } else {
+         textSourceDirectory = new File( textSourceName );
+         //Source ids
+         textSourceIds = textSourceDirectory.list();
+         tsu = new TextSourceUtil( annotationUtil, kpu );
+
+         if ( textSourceType.equals( TEXT_SOURCE_TYPE_DIR ) ) {
+            tsc = new FileTextSourceCollection( textSourceName, Charset.defaultCharset() );
+         } else if ( textSourceType.equals( TEXT_SOURCE_TYPE_FILE_LINES ) ) {
+            tsc = new FileLinesTextSourceCollection( textSourceName );
+         } else {
+            System.err.println( "textSourceType not valid: " + textSourceType );
+            return;
+         }
+         tscItr = tsc.iterator();
+
+         tsu.setCurrentTextSourceCollection( tsc );
+         annotationUtil.setTextSourceUtil( tsu );
+         mentionUtil = new MentionUtil( kpu );
+         annotationUtil.setMentionUtil( mentionUtil );
+      }
+   }
+
+   private int countOfAnnotationsRemoved = 0;
+
+   public int getCountOfAnnotationsRemoved() {
+      return countOfAnnotationsRemoved;
+   }
+
+   // http://knowtator.sourceforge.net/api/src-html/edu/uchsc/ccp/knowtator/KnowtatorManager.html#line.624
+   public void deleteAnnotationAndMention( SimpleInstance si ) {
+      //SimpleInstance mention = mentionUtil.getMentionedBy(si);
+      SimpleInstance mention = annotationUtil.getMention( si );
+      if ( km == null ) {
+         throw new RuntimeException(
+               "failed to init the KnowtatorManager, unable to delete the annotation or the mention" );
+      } else {
+         km.deleteAnnotation( si );
+         annotationUtil.deleteMention( mention );
+         countOfAnnotationsRemoved++;
+      }
+
+   }
+
+   public void saveProjectIfDirty( boolean printInfoMessages ) {
+      if ( this.getProtegeProject().isDirty() ) {
+         saveProject( printInfoMessages );
+      }
+   }
+
+   public void saveProject( boolean printInfoMessages ) {
+      List saveErrors = new ArrayList();
+      System.out.println( "INFO: saving project " + this.getProtegeProject().getName() );
+      protegeProject.save( saveErrors );
+      if ( saveErrors.size() > 0 ) {
+         System.err.println( saveErrors );
+         // throw new Exception(saveErrors.get(0).toString(), null);
+      } else {
+         System.out.println( "INFO: project saved." );
+      }
+   }
+
+   public void saveProject() {
+      saveProject( false ); // don't print info messages unless asked specifically to
+   }
+
+   //-- utility methods -----
+   public int getDocId( TextSource ts ) {
+      return tsc.getIndex( ts );
+   }
+
+   public void next()
+         throws TextSourceAccessException {
+      textDoc = tscItr.next();
+   }
+
+   public boolean hasNextDoc() {
+      return tscItr.hasNext();
+   }
+
+   public TextSource getNextTextSource()
+         throws TextSourceAccessException {
+      return textDoc;
+   }
+
+   public String getNextTextSourceString()
+         throws TextSourceAccessException {
+      return textDoc.getText();
+   }
+
+   public TextSource getDocTextByDocId( int id )
+         throws TextSourceAccessException {
+      return tsc.get( id );
+   }
+
+
+   protected Cls getMentionCls( SimpleInstance mention ) {
+      return mentionUtil.getMentionCls( mention );
+   }
+
+   public List getMentionAnnotations( SimpleInstance mention ) {
+      //-- knowtator--3.2.1 --start--
+      //return mentionUtil.getMentionAnnotations(mention);
+      //-- knowtator--3.2.1 --end--
+
+      //-- knowtator--3.3.1 --start--
+      /**
+       * According to Philip 3.3.1 enforces
+       * one-to-one correspondence between annotations and mentions
+       */
+      List l = new ArrayList();
+      info( "m =" + mention );
+      info( "ma =" + mentionUtil.getMentionAnnotation( mention ) );
+      l.add( mentionUtil.getMentionAnnotation( mention ) );
+      return l;
+      //-- knowtator 3.3.1--end--
+   }
+
+   private void info( String s ) {
+      boolean SHOW_INFO_MESSAGES = false;
+      if ( SHOW_INFO_MESSAGES ) {
+         System.out.println( "INFO: " + s );
+      }
+   }
+
+   public String getMentionClsName( SimpleInstance mention ) {
+      return mentionUtil.getMentionCls( mention ).getName();
+   }
+
+   public String getKnowtatorClsName( SimpleInstance si ) {
+      if ( annotationUtil.isAnnotation( si ) ) {
+         return mentionUtil.getMentionCls( annotationUtil.getMention( si ) ).getName();
+      } else if ( mentionUtil.isMention( si ) ) {
+         return mentionUtil.getMentionCls( si ).getName();
+      } else {
+         System.err.println( "WARNING: Not an annotation and not a mention: " + si );
+         return null;
+      }
+
+   }
+
+   protected String getAnnotator( SimpleInstance annotation ) {
+      SimpleInstance annotator = annotationUtil.getAnnotator( annotation );
+      if ( annotator != null ) {
+         return annotator.getBrowserText();
+      }
+      return "";
+   }
+
+   protected SimpleInstance getAnnotatorAsSimpleInstance( SimpleInstance annotation ) {
+      SimpleInstance annotator = annotationUtil.getAnnotator( annotation );
+      return annotator;
+   }
+
+   /**
+    * Better would be to get by last name or by first name etc, using these constants:
+    * public static final String ANNOTATOR_AFFILIATION_SLOT_NAME = "knowtator_annotation_annotator_affiliation";
+    * public static final String ANNOTATOR_FIRST_NAME_SLOT_NAME = "knowtator_annotation_annotator_firstname";
+    * public static final String ANNOTATOR_LAST_NAME_SLOT_NAME = "knowtator_annotation_annotator_lastname";
+    * public static final String ANNOTATOR_TEAM_CLS_NAME = "knowtator annotator team";
+    * For now just use .contains()
+    *
+    * @param partOfName -
+    * @return null if did not find one that matches input criteria
+    */
+   protected SimpleInstance getAnnotatorContainingName( String partOfName ) throws UnsupportedOperationException {
+      SimpleInstance returnValue = null; // return null if did not find one that matches input criteria
+      Collection<Instance> c = kb.getDirectInstances( kb.getCls( KnowtatorProjectUtil.HUMAN_ANNOTATOR_CLS_NAME ) );
+
+      for ( Instance instance : c ) {
+         if ( instance instanceof SimpleInstance ) {
+            SimpleInstance si = (SimpleInstance)instance;
+            String annotator = si.getBrowserText();
+            if ( annotator.contains( partOfName ) ) {
+               if ( returnValue != null ) {
+                  throw new UnsupportedOperationException(
+                        "More than one annotator found that matches criteria: " + quoted( partOfName ) );
+               }
+               returnValue = si;
+            }
+         }
+      }
+      return returnValue;
+   }
+
+
+   private String quoted( String s ) {
+      return "'" + s + "'";
+   }
+
+
+   public SimpleInstance getAnnotatorStartsWithArg1ContainsArg2( String startsWithValue, String containsValue ) {
+      //KnowledgeBase kb = getProtegeProject().getKnowledgeBase();
+      Collection<Instance> c = kb.getDirectInstances( kb.getCls( KnowtatorProjectUtil.HUMAN_ANNOTATOR_CLS_NAME ) );
+      for ( Instance instance : c ) {
+         if ( instance instanceof SimpleInstance ) {
+            SimpleInstance si = (SimpleInstance)instance;
+            String name = si.getBrowserText();
+            //if (name.startsWith("Guergana") && name.contains("Savova")) {
+            if ( name.startsWith( startsWithValue ) && name.contains( containsValue ) ) {
+               return si;
+            }
+            // System.out.println("is a SimpleInstance " + si.getBrowserText() + " " + si.getName());
+            // outputs, for example:
+            // is a SimpleInstance howarda , Relations_May24Schema_Instance_50003
+
+         }
+         // System.out.println("instance = " + instance);
+         // outputs, for example:
+         // instance = SimpleInstance(Relations_May24Schema_Instance_100019 of [Cls(knowtator human annotator, FrameID(8:11184 1))])
+      }
+      return null; // not found one that matches input criteria
+   }
+
+
+   protected String getComment( SimpleInstance annotation ) {
+      String comment = annotationUtil.getComment( annotation );
+      if ( comment != null && comment.length() > 0 ) {
+         return comment;
+      }
+      return "";
+   }
+
+   /**
+    * add all spans from the mention to the KnowtatorAnnotation
+    *
+    * @param ka
+    * @param mention
+    */
+   protected void addAllSpans( KnowtatorAnnotation ka, SimpleInstance mention ) {
+      info( "mention = " + mention );
+      List list = getMentionAnnotations( mention );
+      SimpleInstance si = (SimpleInstance)list.get( 0 );
+
+      List spans = annotationUtil.getSpans( si );
+
+      if ( spans == null || spans.size() < 1 ) {
+         info( "The 'mention' itself has spans" );
+         spans = annotationUtil.getSpans( mention );
+      }
+
+      for ( int i = 0; i < spans.size(); i++ ) {
+         Span span = ((Span)spans.get( i ));
+         ka.addSpan( span.getStart(), span.getEnd() );
+      }
+   }
+
+   protected String getInstanceId( SimpleInstance annotation ) {
+      int idx = annotation.getName().lastIndexOf( "_" ) + 1;
+      return annotation.getName().substring( idx );
+   }
+
+   protected SimpleInstance getMention( SimpleInstance annotation ) {
+      return annotationUtil.getMention( annotation );
+   }
+
+
+   private int countDebugMsgs = 0;
+
+   protected SimpleInstance getSlotFillerAnnotation( SimpleInstance annoWithSlots, String whichSlot ) {
+      SimpleInstance returnValue = null;
+      if ( annoWithSlots == null ) {
+         return null;
+      }
+
+      //SimpleInstance mentionUnknown = mentionUtil.getMentionInstance(umlsRelationAnnotation);
+      SimpleInstance mention = annotationUtil
+            .getMention( annoWithSlots ); // use this when annoWithSlots is a "knowtator annotation" rather than a "knowtator class mention"
+
+      List slotMentions = mentionUtil.getSlotMentions( mention );
+      for ( int i = 0; i < slotMentions.size(); i++ ) {
+
+         SimpleInstance slotMention = (SimpleInstance)slotMentions.get( i );
+
+         List slotValues = mentionUtil.getSlotMentionValues( slotMention );
+
+         for ( int sv = 0; sv < slotValues.size(); sv++ ) {
+
+            //if(mentionUtil.isComplexSlotMention(slotMention)) {
+            //	Slot slot = mentionUtil.getSlotMentionSlot(slotMention);
+            //
+            //}
+            Slot slot = mentionUtil.getSlotMentionSlot( slotMention );
+            String slotName = slot.getName();
+            Object slotValue = slotValues.get( sv );
+            if ( whichSlot.equals( slotName ) ) {
+               returnValue = (SimpleInstance)slotValue;
+            }
+            if ( countDebugMsgs < 0 ) { // TODO
+               countDebugMsgs++;
+
+               if ( sv == 0 ) {
+                  System.out.println( "\t\tSlot:," + slotName + "   Value:" + slotValue );
+               } else {
+                  System.out.println( "\t\t      " + slotName + "   Value:" + slotValue );
+               }
+
+            }
+         }
+      }
+      if ( returnValue == null ) {
+         return returnValue;
+      }
+      returnValue = mentionUtil.getMentionAnnotation( returnValue );
+      return returnValue;
+   }
+
+   protected static boolean getBooleanSlotValue( SimpleInstance annoWithSlots,
+                                                 String whichSlot,
+                                                 boolean defaultValue,
+                                                 AnnotationUtil annotationUtil,
+                                                 MentionUtil mentionUtil ) {
+      Object o = getSlotValue( annoWithSlots, whichSlot, annotationUtil, mentionUtil );
+      if ( o == null ) {
+         return defaultValue;
+      }
+      String s = (String)o;
+      return s.equals( "true" );
+   }
+
+   protected static String getSlotFillerStringSlotValue( SimpleInstance annoWithSlots,
+                                                         String whichSlot,
+                                                         String slotFillersSlot,
+                                                         AnnotationUtil annotationUtil,
+                                                         MentionUtil mentionUtil ) {
+      String coveredText = annoWithSlots.getBrowserText(); // DEBUG
+      List spans = annotationUtil.getSpans( annoWithSlots ); // DEBUG
+      SimpleInstance slotFiller = (SimpleInstance)getSlotValue( annoWithSlots,
+            whichSlot,
+            annotationUtil,
+            mentionUtil );
+      String s = getStringSlotValue( slotFiller, slotFillersSlot, annotationUtil, mentionUtil );
+      return s;
+   }
+
+
+   protected static String getStringSlotValue( SimpleInstance annoWithSlots,
+                                               String whichSlot,
+                                               AnnotationUtil annotationUtil,
+                                               MentionUtil mentionUtil ) {
+      Object o = getSlotValue( annoWithSlots, whichSlot, annotationUtil, mentionUtil );
+      if ( o == null ) {
+         return null;
+      }
+      return (String)o;
+   }
+
+   private static boolean outputWarningAboutAnnoVsMention = false;
+
+   protected static Object getSlotValue( SimpleInstance annoWithSlots,
+                                         String whichSlot,
+                                         AnnotationUtil annotationUtil,
+                                         MentionUtil mentionUtil ) {
+      if ( annoWithSlots == null ) {
+         return null;
+      }
+
+      //SimpleInstance mentionUnknown = mentionUtil.getMentionInstance(umlsRelationAnnotation);
+      SimpleInstance mention = annotationUtil
+            .getMention( annoWithSlots ); // use this when annoWithSlots is a "knowtator annotation" rather than a "knowtator class mention"
+      if ( mention == null ) {
+         if ( !outputWarningAboutAnnoVsMention ) {
+            System.out.println(
+                  "WARNING: mention==null (from annotationUtil.getMention) for SimpleInstance " + annoWithSlots );
+            System.out.println( "         You probably passed a mention rather than an annotation" );
+            System.out.println( "         Going to try using " + annoWithSlots + " itself rather than getMention()" );
+            outputWarningAboutAnnoVsMention = true;
+         }
+         mention = annoWithSlots;
+      }
+      List slotMentions = mentionUtil.getSlotMentions( mention );
+      for ( int i = 0; i < slotMentions.size(); i++ ) {
+
+         SimpleInstance slotMention = (SimpleInstance)slotMentions.get( i );
+
+         List slotValues = mentionUtil.getSlotMentionValues( slotMention );
+
+         for ( int sv = 0; sv < slotValues.size(); sv++ ) {
+
+            Slot slot = mentionUtil.getSlotMentionSlot( slotMention );
+            String slotName = slot.getName();
+            Object slotValue = slotValues.get( sv );
+            if ( whichSlot.equals( slotName ) ) {
+               return slotValue;
+            }
+            if ( 0 < 0 ) { // TODO
+               //countDebugMsgs++;
+
+               if ( sv == 0 ) {
+                  System.out.println( "\t\tSlot:," + slotName + "   Value:" + slotValue );
+               } else {
+                  System.out.println( "\t\t      " + slotName + "   Value:" + slotValue );
+               }
+
+            }
+         }
+      }
+
+      return null;
+   }
+
+
+   //-- protected data members ------
+   protected List errors;
+   protected Project protegeProject;
+   protected TextSourceCollection tsc;
+   protected TextSourceIterator tscItr;
+   protected TextSource textDoc;
+   protected KnowledgeBase kb;
+   protected KnowtatorProjectUtil kpu;
+   protected AnnotationUtil annotationUtil;
+   protected MentionUtil mentionUtil;
+   protected SimpleInstance annotator;
+   protected TextSourceUtil tsu;
+   protected File textSourceDirectory;
+   protected String[] textSourceIds;
+
+
+   KnowtatorManager km;
+
+   public void addActiveFilter( SimpleInstance filter ) {
+      km.addActiveFilter( filter );
+   }
+
+   public boolean addToConfig( SimpleInstance value, String slotName ) {
+
+      if ( value == null ) {
+         System.err.println( "ERROR: value = null in addToConfig(value, slotName)    slotName = " + slotName );
+         System.err.println( "       not able to add to config" );
+         return false;
+      }
+      SimpleInstance config = ProjectSettings.getActiveConfiguration( kb.getProject() );
+      if ( slotName.equals( ACTIVE_FILTERS_SLOT_NAME ) ) {
+         config.addOwnSlotValue( kpu.getActiveFiltersSlot(), value );
+         return true;
+      } else if ( slotName.equals( COLOR_ASSIGNMENTS_SLOT_NAME ) ) {
+         config.addOwnSlotValue( kpu.getColorAssignmentsSlot(), value );
+         return true;
+      } else {
+         System.err.println( "ERROR: slotName " + slotName + " is UNSUPPORTED BY THIS KnowtatorProject class" );
+         return false;
+      }
+
+   }
+
+   //([Anwen_annotationSchemaApril13plusApr14cTAKES_2_merged_w_UMLS_rel_Instance_30000] of  knowtator+filter
+   //
+   //	(knowtator_filter_name "no Relations")
+   //	(knowtator_filter_type
+   //		Document
+   //		Entity
+   //		Event
+   //		Predicate_Argument_Structure
+   //		QuestionAnswer
+   //		Aux_attributes
+   //		QuestionType))
+   public SimpleInstance createFilter( String filterName ) {
+
+      //  SimpleInstance si = getInstanceWithSlotValue(FILTER_CLS_NAME, FILTER_TYPE_SLOT_NAME, knowtatorClsName);
+      //  Collection<Instance> filters = kb.getDirectInstances(kb.getCls(FILTER_CLS_NAME));
+      Cls filterCls = kb.getCls( FILTER_CLS_NAME );
+      SimpleInstance newFilter = (SimpleInstance)kb.createInstance( filterName, filterCls );
+
+      return newFilter;
+
+   }
+
+   public SimpleInstance getDisplayColorSi( String colorName ) {
+      //    DisplayColors dc = km.getDisplayColors();
+      //    dc.getColor()
+
+      SimpleInstance ktDisplayColorSi = getSimpleInstanceWithSlotValue( DISPLAY_COLOR_CLS_NAME,
+            DISPLAY_COLOR_NAME_SLOT_NAME,
+            colorName );
+      //    List<SimpleInstance> colorAssignments = km.getColorAssignments();
+      //    for (SimpleInstance colorAssignment: colorAssignments) {
+      //
+      // 	  	return displayColorSi;
+      //
+      if ( ktDisplayColorSi == null ) {
+         throw new UnsupportedOperationException( "Could not find SimpleInstance for color " + colorName );
+      }
+      return ktDisplayColorSi;
+   }
+
+
+   //Consider if it makes sense to use this instead of
+   //getAnnotatorContainingName or getAnnotatorStartsWithArg1ContainsArg2
+   //Might use with a clsName of KnowtatorProjectUtil.HUMAN_ANNOTATOR_CLS_NAME
+   public SimpleInstance getSimpleInstanceWithValue( String clsName, String value ) {
+      //KnowledgeBase kb = this.getProtegeProject().getKnowledgeBase();
+      Collection<Instance> c = kb.getDirectInstances( kb.getCls( clsName ) );
+      for ( Instance instance : c ) {
+         if ( instance instanceof SimpleInstance ) {
+            SimpleInstance si = (SimpleInstance)instance;
+            String name = si.getBrowserText();
+            if ( name.trim().equals( value.trim() ) ) {
+               return si;
+            }
+         }
+      }
+      return null; // not found one that matches input criteria
+   }
+
+   //Collection<Instance> c = kb.getDirectInstances(kb.getCls(clsName));
+   // FILTER_CLS_NAME
+   //public Collection<Instance> getInstancesOfType(String clsName) {
+   //
+   // Collection<Instance> c = kb.getDirectInstances(kb.getCls(clsName));
+   // for (Instance instance : c) {
+   //     if (instance instanceof SimpleInstance) {
+   //         SimpleInstance si = (SimpleInstance) instance;
+   //         String name = si.getBrowserText();
+   //         if (name.trim().equals(value.trim())) {
+   //     	return si;
+   //         }
+   //     }
+   // }
+   // return null; // not found one that matches input criteria
+   //}
+
+
+   public SimpleInstance getSimpleInstanceWithSlotValue( String clsName, String slotName, String value ) {
+      // get all instances of cls className
+      //KnowledgeBase kb = this.getProtegeProject().getKnowledgeBase();
+      Collection<Instance> c = kb.getDirectInstances( kb.getCls( clsName ) );
+      // loop through until find one with slot containing value
+      // optionally throw exception or something if more than one found
+      for ( Instance instance : c ) {
+         if ( instance instanceof SimpleInstance ) {
+            SimpleInstance si = (SimpleInstance)instance;
+            Slot slot = kb.getSlot( slotName );
+            List values = si.getDirectOwnSlotValues( slot );
+            for ( Object o : values ) {
+               // System.out.println(o.getClass() + " for " + o);
+               if ( o instanceof Cls && value.equals( ((Cls)o).getBrowserText() ) ) {
+                  return si;
+               }
+               if ( o instanceof String && value.equals( o.toString() ) ) {
+                  return si;
+               }
+            }
+         }
+      }
+      // return null if none found
+      return null; // not found one that matches input criteria
+
+   }
+
+   //	([Relations_Sept21_Schema_Set02_Instance_3] of  knowtator+color+assignment
+   //
+   //		(knowtator_color_class ENTITY_candidate)
+   //		(knowtator_display_color [knowtator_Instance_30113]))
+   public SimpleInstance setOrCreateColorAssignment( String knowtatorClsName, SimpleInstance displayColor ) {
+
+      if ( knowtatorClsName == null ) {
+         System.out.println( "WARNING: knowtatorClsName is null" );
+         return null;
+      }
+
+      SimpleInstance si = getSimpleInstanceWithSlotValue( COLOR_ASSIGNMENT_CLS_NAME,
+            COLOR_CLASS_SLOT_NAME,
+            knowtatorClsName );
+      if ( si == null ) {
+         DisplayColors dc = km.getDisplayColors();
+         dc.addAssignment( kb.getCls( knowtatorClsName ), displayColor ); // creates one and adds it
+         DisplayColors dc2 = km.getDisplayColors();
+
+         si = getSimpleInstanceWithSlotValue( COLOR_ASSIGNMENT_CLS_NAME, COLOR_CLASS_SLOT_NAME, knowtatorClsName );
+         if ( si == null ) {
+            System.err.println(
+                  "ERROR: null from getSimpleInstanceWithSlotValue(COLOR_ASSIGNMENT_CLS_NAME, COLOR_CLASS_SLOT_NAME, knowtatorClassName);" );
+            System.err.println( "       COLOR_ASSIGNMENT_CLS_NAME = " + COLOR_ASSIGNMENT_CLS_NAME );
+            System.err.println( "       COLOR_CLASS_SLOT_NAME = " + COLOR_CLASS_SLOT_NAME );
+            System.err.println( "       knowtatorClassName = " + knowtatorClsName );
+         }
+         return si;
+      } else {
+         si.setDirectOwnSlotValue( kpu.getColorClassSlot(), knowtatorClsName );
+         si.setDirectOwnSlotValue( kpu.getDisplayColorSlot(), displayColor );
+         return si;
+      }
+   }
+
+
+   public void addTypeToFilter( String typeClsName, SimpleInstance filter ) {
+
+      Cls cls = kb.getCls( typeClsName );
+      addTypeToFilter( cls, filter );
+   }
+
+   public void addTypeToFilter( Cls cls, SimpleInstance filter ) {
+
+      //FilterUtil fu = km.getFilterUtil();
+      Collection<Cls> types = FilterUtil.getTypes( filter );
+      //Cls cls = kb.getCls(typeClsName);
+      types.add( cls );
+      Slot slot = kb.getSlot( KnowtatorProjectUtil.FILTER_TYPE_SLOT_NAME );
+      filter.setDirectOwnSlotValues( slot, types );   //
+
+   }
+
+   public boolean removeTypeFromFilter( String clsName, SimpleInstance filter ) {
+
+      Collection<Cls> types = FilterUtil.getTypes( filter );
+      Cls cls = kb.getCls( clsName );
+      boolean returnValue = types.remove( cls );
+      Slot slot = kb.getSlot( KnowtatorProjectUtil.FILTER_TYPE_SLOT_NAME );
+      filter.setDirectOwnSlotValues( slot, types );
+      return returnValue;
+
+   }
+
+   public void addMostTypesToFilter( SimpleInstance filter ) {
+
+      boolean DEBUG_THIS_METHOD = false;
+      // get all types/classes defined in this knowtator project
+      Collection<Cls> types = kb.getClses(); // TODO
+      if ( DEBUG_THIS_METHOD ) {
+         for ( Cls c : types ) {
+            System.out.println(
+                  "INFO: getClses returns: " + c.toString() + " " + c.getBrowserText() + " " + c.getName() );
+         }
+      }
+
+      //  Collection<Instance> c = kb.getDirectInstances(kb.getCls(clsName));
+      //  FILTER_CLS_NAME
+
+      // add each one to this filter
+      for ( Cls cls : types ) {
+         if ( cls.getName().startsWith( ":" ) ) {
+            System.out.println( "INFO: not adding class " + cls.getName() + " to filter." );
+         } else if ( cls.getName().startsWith( "knowtator " ) ) {
+            System.out.println( "INFO: not adding class " + cls.getName() + " to filter." );
+         } else if ( cls.getName().startsWith( "file " ) && cls.getName().endsWith( " source" ) ) {
+            System.out.println( "INFO: not adding class " + cls.getName() + " to filter." );
+         } else {
+            addTypeToFilter( cls, filter );
+         }
+      }
+   }
+
+
+}
+

Added: ctakes/sandbox/timelanes/edu/mayo/bmi/annotation/knowtator/LocalSpan.java
URL: http://svn.apache.org/viewvc/ctakes/sandbox/timelanes/edu/mayo/bmi/annotation/knowtator/LocalSpan.java?rev=1660963&view=auto
==============================================================================
--- ctakes/sandbox/timelanes/edu/mayo/bmi/annotation/knowtator/LocalSpan.java (added)
+++ ctakes/sandbox/timelanes/edu/mayo/bmi/annotation/knowtator/LocalSpan.java Thu Feb 19 18:06:13 2015
@@ -0,0 +1,18 @@
+package edu.mayo.bmi.annotation.knowtator;
+
+/**
+ * Author: SPF
+ * Affiliation: CHIP-NLP
+ * Date: 6/19/12
+ */
+public class LocalSpan {
+   // TODO replace with spf Span
+   int begin;
+   int end;
+
+   public LocalSpan( int begin, int end ) {
+      this.begin = begin;
+      this.end = end;
+   }
+
+}

Added: ctakes/sandbox/timelanes/org/chboston/cnlp/anafora/annotation/parser/AnaforaEntitySegregator.java
URL: http://svn.apache.org/viewvc/ctakes/sandbox/timelanes/org/chboston/cnlp/anafora/annotation/parser/AnaforaEntitySegregator.java?rev=1660963&view=auto
==============================================================================
--- ctakes/sandbox/timelanes/org/chboston/cnlp/anafora/annotation/parser/AnaforaEntitySegregator.java (added)
+++ ctakes/sandbox/timelanes/org/chboston/cnlp/anafora/annotation/parser/AnaforaEntitySegregator.java Thu Feb 19 18:06:13 2015
@@ -0,0 +1,68 @@
+package org.chboston.cnlp.anafora.annotation.parser;
+
+import org.chboston.cnlp.nlp.annotation.classtype.ClassType;
+import org.chboston.cnlp.nlp.annotation.classtype.TemporalClassType;
+import org.chboston.cnlp.nlp.annotation.entity.Entity;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Author: SPF
+ * Affiliation: CHIP-NLP
+ * Date: 3/28/13
+ */
+final public class AnaforaEntitySegregator {
+
+   private AnaforaEntitySegregator() {
+   }
+
+   /**
+    * @param entities collection of entities
+    * @return all named entities with the given collection of entities
+    */
+   static List<Entity> getNamedEntities( final Collection<Entity> entities ) {
+      final List<Entity> namedEntityList = new ArrayList<>();
+      for ( Entity entity : entities ) {
+         final ClassType type = entity.getClassType();
+         if ( type != TemporalClassType.EVENT && type != TemporalClassType.TIMEX ) {
+            namedEntityList.add( entity );
+         }
+      }
+      return Collections.unmodifiableList( namedEntityList );
+   }
+
+   /**
+    * @param entities collection of entities
+    * @return all events with the given collection of entities
+    */
+   static List<Entity> getEvents( final Collection<Entity> entities ) {
+      final List<Entity> eventList = new ArrayList<>();
+      for ( Entity entity : entities ) {
+         final ClassType type = entity.getClassType();
+         if ( type == TemporalClassType.EVENT ) {
+            eventList.add( entity );
+         }
+      }
+      return Collections.unmodifiableList( eventList );
+   }
+
+   /**
+    * @param entities collection of entities
+    * @return all timex3 times with the given collection of entities
+    */
+   static List<Entity> getTimes( final Collection<Entity> entities ) {
+      final List<Entity> timexList = new ArrayList<>();
+      for ( Entity entity : entities ) {
+         final ClassType type = entity.getClassType();
+         if ( type == TemporalClassType.TIMEX ) {
+            timexList.add( entity );
+         }
+      }
+      return Collections.unmodifiableList( timexList );
+   }
+
+
+}

Added: ctakes/sandbox/timelanes/org/chboston/cnlp/anafora/annotation/parser/AnaforaRelationSegregator.java
URL: http://svn.apache.org/viewvc/ctakes/sandbox/timelanes/org/chboston/cnlp/anafora/annotation/parser/AnaforaRelationSegregator.java?rev=1660963&view=auto
==============================================================================
--- ctakes/sandbox/timelanes/org/chboston/cnlp/anafora/annotation/parser/AnaforaRelationSegregator.java (added)
+++ ctakes/sandbox/timelanes/org/chboston/cnlp/anafora/annotation/parser/AnaforaRelationSegregator.java Thu Feb 19 18:06:13 2015
@@ -0,0 +1,131 @@
+package org.chboston.cnlp.anafora.annotation.parser;
+
+import org.chboston.cnlp.nlp.annotation.attribute.AttributeUtil;
+import org.chboston.cnlp.nlp.annotation.attribute.TlinkAttributeValue;
+import org.chboston.cnlp.nlp.annotation.classtype.ClassType;
+import org.chboston.cnlp.nlp.annotation.classtype.TemporalClassType;
+import org.chboston.cnlp.nlp.annotation.relation.Relation;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Author: SPF
+ * Affiliation: CHIP-NLP
+ * Date: 3/29/13
+ */
+final public class AnaforaRelationSegregator {
+
+   private AnaforaRelationSegregator() {
+   }
+
+   /**
+    * @param relations collection of relations
+    * @return all umls relations with the given collection of relations
+    */
+   static public List<Relation> getUmlsRelations( final Iterable<Relation> relations ) {
+      final List<Relation> umlsRelationList = new ArrayList<>();
+      for ( Relation relation : relations ) {
+         final ClassType type = relation.getClassType();
+         if ( type != TemporalClassType.TLINK && type != TemporalClassType.ALINK ) {
+            umlsRelationList.add( relation );
+         }
+      }
+      return Collections.unmodifiableList( umlsRelationList );
+   }
+
+   /**
+    * @param relations collection of relations
+    * @return all umls relations with the given collection of relations
+    */
+   static public List<Relation> getTemporalRelations( final Iterable<Relation> relations ) {
+      final List<Relation> timeRelationList = new ArrayList<>();
+      for ( Relation relation : relations ) {
+         final ClassType type = relation.getClassType();
+         if ( type == TemporalClassType.TLINK || type == TemporalClassType.ALINK ) {
+            timeRelationList.add( relation );
+         }
+      }
+      return Collections.unmodifiableList( timeRelationList );
+   }
+
+
+   static private boolean isTimeTimeLink( final Relation relation ) {
+      return relation.getFirstEntity().getClassType() == TemporalClassType.TIMEX
+             && relation.getSecondEntity().getClassType() == TemporalClassType.TIMEX;
+   }
+
+   static private boolean isEventEventLink( final Relation relation ) {
+      return relation.getFirstEntity().getClassType() == TemporalClassType.EVENT
+             && relation.getSecondEntity().getClassType() == TemporalClassType.EVENT;
+   }
+
+   static private boolean isEventTimeLink( final Relation relation ) {
+      return !isTimeTimeLink( relation ) && !isEventEventLink( relation );
+   }
+
+   static private final boolean IGNORE_EVENT_EVENT = false;
+   static private final boolean IGNORE_EVENT_TIME = false;
+   static private final boolean IGNORE_TIME_TIME = false;
+
+   static private final boolean WANT_ALL_TLINK_TYPES = true;
+   static private final TlinkAttributeValue WANT_TLINK_TYPE = TlinkAttributeValue.CONTAINS;
+
+   static private boolean isWantedLinkType( final Relation relation ) {
+      return WANT_ALL_TLINK_TYPES || AttributeUtil.getTlinkType( relation ) == WANT_TLINK_TYPE;
+   }
+
+   static private final boolean WANT_ALINKS = false;
+
+   /**
+    * @param relations collection of relations
+    * @return all Tlink relations with the given collection of relations
+    */
+   static List<Relation> getTlinkRelations( final Collection<Relation> relations ) {
+      final List<Relation> tlinkRelationList = new ArrayList<>();
+      for ( Relation relation : relations ) {
+         final ClassType type = relation.getClassType();
+         if ( type == TemporalClassType.TLINK ) {
+            if ( IGNORE_EVENT_EVENT && isEventEventLink( relation ) ) {
+               // don't want event:event
+               continue;
+            }
+            if ( IGNORE_TIME_TIME && isTimeTimeLink( relation ) ) {
+               // don't want time:time
+               continue;
+            }
+            if ( IGNORE_EVENT_TIME && isEventTimeLink( relation ) ) {
+               // don't want event:time or time:event links
+               continue;
+            }
+            if ( !isWantedLinkType( relation ) ) {
+               continue;
+            }
+            tlinkRelationList.add( relation );
+         }
+      }
+      if ( WANT_ALINKS ) {
+         tlinkRelationList.addAll( AnaforaRelationSegregator.getAlinkRelations( relations ) );
+      }
+      return Collections.unmodifiableList( tlinkRelationList );
+   }
+
+   /**
+    * @param relations collection of relations
+    * @return all Alink relations with the given collection of relations
+    */
+   static List<Relation> getAlinkRelations( final Collection<Relation> relations ) {
+      final List<Relation> alinkRelationList = new ArrayList<>();
+      for ( Relation relation : relations ) {
+         final ClassType type = relation.getClassType();
+         if ( type == TemporalClassType.ALINK ) {
+            alinkRelationList.add( relation );
+         }
+      }
+      return Collections.unmodifiableList( alinkRelationList );
+   }
+
+
+}

Added: ctakes/sandbox/timelanes/org/chboston/cnlp/anafora/annotation/parser/AnaforaTag.java
URL: http://svn.apache.org/viewvc/ctakes/sandbox/timelanes/org/chboston/cnlp/anafora/annotation/parser/AnaforaTag.java?rev=1660963&view=auto
==============================================================================
--- ctakes/sandbox/timelanes/org/chboston/cnlp/anafora/annotation/parser/AnaforaTag.java (added)
+++ ctakes/sandbox/timelanes/org/chboston/cnlp/anafora/annotation/parser/AnaforaTag.java Thu Feb 19 18:06:13 2015
@@ -0,0 +1,42 @@
+package org.chboston.cnlp.anafora.annotation.parser;
+
+/**
+ * Author: SPF
+ * Affiliation: CHIP-NLP
+ * Date: 6/17/14
+ */
+public enum AnaforaTag {
+   ROOT_ELEMENT( "data" ),
+   ANNOTATIONS_GROUP( "annotations" ),
+   ENTITY_ELEMENT( "entity" ),
+   RELATION_ELEMENT( "relation" ),
+   ANNOTATION_ID( "id" ),
+   ANNOTATION_TEXT_SPAN( "span" ),
+   ANNOTATION_TYPE( "type" ),
+   ANNOTATION_PARENT_TYPE( "parentsType" ),
+   ANNOTATION_PROPERTIES( "properties" ),
+   RELATION_SOURCE( "source" ),
+   RELATION_TARGET( "target" ),
+   FIRST_COREF_INSTANCE( "FirstInstance" ),
+   OTHER_COREF_INSTANCE( "Coreferring_String" ),
+
+   // TODO Move following Values elsewhere
+   PARENT_TEMPORAL( "TemporalEntities" ),
+   PARENT_UMLS( "UMLSEntities" ),
+   PARENT_COREFERENCES( "Coreference" ),
+   PARENT_COREFERENCE( "CorefChains" ),
+   COREF_IDENTICAL( "Identical" )
+   // TODO Coref Whole/Part, Set/Subset, Appositive
+   ;
+
+   private final String _name;
+
+   private AnaforaTag( final String name ) {
+      _name = name;
+   }
+
+   public String getName() {
+      return _name;
+   }
+
+}

Added: ctakes/sandbox/timelanes/org/chboston/cnlp/anafora/annotation/parser/AnaforaXmlParser.java
URL: http://svn.apache.org/viewvc/ctakes/sandbox/timelanes/org/chboston/cnlp/anafora/annotation/parser/AnaforaXmlParser.java?rev=1660963&view=auto
==============================================================================
--- ctakes/sandbox/timelanes/org/chboston/cnlp/anafora/annotation/parser/AnaforaXmlParser.java (added)
+++ ctakes/sandbox/timelanes/org/chboston/cnlp/anafora/annotation/parser/AnaforaXmlParser.java Thu Feb 19 18:06:13 2015
@@ -0,0 +1,632 @@
+package org.chboston.cnlp.anafora.annotation.parser;
+
+
+import org.chboston.cnlp.nlp.annotation.annotation.store.ImmutableAnnotationStore;
+import org.chboston.cnlp.nlp.annotation.attribute.Attribute;
+import org.chboston.cnlp.nlp.annotation.attribute.DefaultAttribute;
+import org.chboston.cnlp.nlp.annotation.attribute.DefinedAttributeType;
+import org.chboston.cnlp.nlp.annotation.classtype.ClassType;
+import org.chboston.cnlp.nlp.annotation.classtype.ClassTypeFactory;
+import org.chboston.cnlp.nlp.annotation.coreference.CoreferenceChain;
+import org.chboston.cnlp.nlp.annotation.coreference.CoreferenceChainSpanComparator;
+import org.chboston.cnlp.nlp.annotation.coreference.CoreferenceFactory;
+import org.chboston.cnlp.nlp.annotation.entity.DefaultEntity;
+import org.chboston.cnlp.nlp.annotation.entity.Entity;
+import org.chboston.cnlp.nlp.annotation.parser.AbstractAnnotationXmlParser;
+import org.chboston.cnlp.nlp.annotation.relation.DefaultRelation;
+import org.chboston.cnlp.nlp.annotation.relation.Relation;
+import org.chboston.cnlp.nlp.annotation.textspan.DefaultDiscontiguousTextSpan;
+import org.chboston.cnlp.nlp.annotation.textspan.DefaultTextSpan;
+import org.chboston.cnlp.nlp.annotation.textspan.EntityTextSpan;
+import org.chboston.cnlp.nlp.annotation.textspan.TextSpan;
+import org.jdom.Document;
+import org.jdom.Element;
+import org.jdom.JDOMException;
+import org.jdom.input.SAXBuilder;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.*;
+import java.util.logging.Logger;
+
+/**
+ * Author: SPF
+ * Affiliation: CHIP-NLP
+ * Date: 3/27/13
+ */
+final public class AnaforaXmlParser extends AbstractAnnotationXmlParser {
+
+   static private final Logger LOGGER = Logger.getLogger( "AnaforaXmlParser" );
+
+   // TODO Refactor to use AnaforaTag
+   static private final String ROOT_ELEMENT_NAME = "data";
+   static private final String ANNOTATION_ELEMENT_NAME = "annotations";
+   static private final String ENTITY_ELEMENT_NAME = "entity";
+   static private final String RELATION_ELEMENT_NAME = "relation";
+   static private final String ANNOTATION_ID_ELEMENT_NAME = "id";
+   static private final String ANNOTATION_SPAN_ELEMENT_NAME = "span";
+   static private final String ANNOTATION_TYPE_ELEMENT_NAME = "type";
+   static private final String ANNOTATION_PARENTS_TYPE_ELEMENT_NAME = "parentsType";
+   static private final String ANNOTATION_PROPERTIES_ELEMENT_NAME = "properties";
+   static private final String RELATION_SOURCE_PROPERTY_NAME = "source";
+   static private final String RELATION_TARGET_PROPERTY_NAME = "target";
+   static private final String PARENTS_TYPE_COREF = "Coreference";
+   static private final String PARENTS_TYPE_COREF_CHAIN = "CorefChains";
+
+
+   /**
+    * @param filePath path to file with annotation information
+    * @return true if this AnnotationsParser can properly handle the given file
+    */
+   static public boolean canParse( final String filePath ) {
+      final SAXBuilder saxBuilder = new SAXBuilder();
+      try {
+         final Document document = saxBuilder.build( filePath );
+         final Element rootElement = document.getRootElement();
+         // Anafora has a primary element named "data"
+         return rootElement != null && rootElement.getName().equals( ROOT_ELEMENT_NAME );
+      } catch ( JDOMException jdomE ) {
+         LOGGER.severe( jdomE.getMessage() );
+         return false;
+      } catch ( IOException ioE ) {
+         LOGGER.severe( ioE.getMessage() );
+         return false;
+      }
+   }
+
+//   private String _documentText = "";
+//
+//
+//   public void setDocumentTextFile( final String filePath ) {
+//      if ( filePath != null && !filePath.isEmpty() ) {
+//         setDocumentTextFile( new File( filePath ) );
+//      } else {
+//         _documentText = "";
+//      }
+//   }
+//
+//   public void setDocumentTextFile( final File file ) {
+//      if ( file != null ) {
+//         try {
+//            final BufferedReader reader = new BufferedReader( new FileReader( file ) );
+//            final char[] buffer = new char[8192];
+//            int length = reader.read( buffer );
+//            if ( length == 0 ) {
+//               LOGGER.severe( "Empty File " + file.getPath() );
+//               return;
+//            }
+//            final StringBuilder sb = new StringBuilder();
+//            while ( length > 0 ) {
+//               sb.append( buffer, 0, length );
+//               length = reader.read( buffer );
+//            }
+//            _documentText = sb.toString();
+//            reader.close();
+//         } catch ( FileNotFoundException fnfE ) {
+//            // thrown by new FileReader
+//            LOGGER.severe( "Document File " + file.getPath() + " not found" );
+//         } catch ( IOException ioE ) {
+//            // thrown by read(..) and close()
+//            LOGGER.severe( ioE.getMessage() );
+//         } catch ( SecurityException sE ) {
+//            // thrown by any file io
+//            LOGGER.severe( "Could not read file " + file.getPath() );
+//         }
+//      } else {
+//         _documentText = "";
+//      }
+//   }
+//
+//   public void setDocumentText( final String text ) {
+//      _documentText = text;
+//   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public boolean preParseFile( final String xmlFilePath ) {
+      reset();
+      if ( xmlFilePath == null || xmlFilePath.length() == 0 ) {
+         return false;
+      }
+      final File xmlFile = new File( xmlFilePath );
+      if ( !xmlFile.canRead() ) {
+         return false;
+      }
+      final SAXBuilder saxBuilder = new SAXBuilder();
+      try {
+         final Document document = saxBuilder.build( xmlFile );
+         final Element rootElement = document.getRootElement();
+         final Map<String, Entity> entityMap = getEntityMap( rootElement );
+         for ( Entity entity : entityMap.values() ) {
+            getMutableClassTypes().add( entity.getClassType().getName() );
+            getMutableAttributeTypes().addAll( entity.getAttributeNames() );
+         }
+         final List<Relation> relationList = getRelations( rootElement, entityMap );
+         for ( Relation relation : relationList ) {
+            getMutableRelationTypes().add( relation.getClassType().getName() );
+            getMutableAttributeTypes().addAll( relation.getAttributeNames() );
+         }
+         return true;
+      } catch ( JDOMException jdomE ) {
+         LOGGER.severe( jdomE.getMessage() );
+         return false;
+      } catch ( IOException ioE ) {
+         LOGGER.severe( ioE.getMessage() );
+         return false;
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public boolean parseFile( final String xmlFilePath ) {
+      reset();
+      if ( xmlFilePath == null || xmlFilePath.isEmpty() ) {
+         return false;
+      }
+      final File xmlFile = new File( xmlFilePath );
+      if ( !xmlFile.canRead() ) {
+         return false;
+      }
+      final SAXBuilder saxBuilder = new SAXBuilder();
+      try {
+         final Document document = saxBuilder.build( xmlFile );
+         final Element rootElement = document.getRootElement();
+         final Map<String, Entity> entityMap = getEntityMap( rootElement );
+         final List<Relation> relationList = getRelations( rootElement, entityMap );
+         final List<Entity> entityList = AnaforaEntitySegregator.getNamedEntities( entityMap.values() );
+         final List<Entity> eventList = AnaforaEntitySegregator.getEvents( entityMap.values() );
+         final List<Entity> timexList = AnaforaEntitySegregator.getTimes( entityMap.values() );
+         final List<Relation> umlsRelationList = AnaforaRelationSegregator.getUmlsRelations( relationList );
+         final List<Relation> tlinkRelationList = AnaforaRelationSegregator.getTlinkRelations( relationList );
+         final List<Collection<TextSpan>> coreferenceTextSpans = getCoreferenceTextSpans( rootElement );
+         Collections.sort( coreferenceTextSpans, CoreferenceChainSpanComparator.getInstance() );
+         List<CoreferenceChain> coreferenceChainList = Collections.emptyList();
+         if ( !entityList.isEmpty()
+//              || !eventList.isEmpty()
+              || !timexList.isEmpty() ) {
+            coreferenceChainList = CoreferenceFactory.createCoreferenceChains( coreferenceTextSpans, entityList,
+                  eventList, timexList );
+         }
+         int wordCount = -1;
+         final String documentText = getDocumentText();
+         if ( documentText != null && !documentText.isEmpty() ) {
+            wordCount = documentText.split( "\\s+" ).length;
+         }
+         final ImmutableAnnotationStore.AnnoteCollectBuilder builder
+               = new ImmutableAnnotationStore.AnnoteCollectBuilder();
+         builder.entities( entityList ).events( eventList ).times( timexList );
+         builder.relations( umlsRelationList ).timeRelations( tlinkRelationList );
+//         builder.coreferenceTextSpans( coreferenceChains );
+         builder.coreferenceChains( coreferenceChainList ).wordCount( wordCount );
+         if ( documentText != null && !documentText.isEmpty() ) {
+            builder.documentText( documentText );
+         }
+         _annotationStore = builder.build();
+         return true;
+      } catch ( JDOMException jdomE ) {
+         LOGGER.severe( jdomE.getMessage() );
+         return false;
+      } catch ( IOException ioE ) {
+         LOGGER.severe( ioE.getMessage() );
+         return false;
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public List<Collection<TextSpan>> parseCoreferenceTextSpans( final String xmlFilePath ) {
+      if ( xmlFilePath == null || xmlFilePath.isEmpty() ) {
+         return Collections.emptyList();
+      }
+      final File xmlFile = new File( xmlFilePath );
+      if ( !xmlFile.canRead() ) {
+         return Collections.emptyList();
+      }
+      final SAXBuilder saxBuilder = new SAXBuilder();
+      try {
+         final Document document = saxBuilder.build( xmlFile );
+         final Element rootElement = document.getRootElement();
+         return getCoreferenceTextSpans( rootElement );
+      } catch ( JDOMException jdomE ) {
+         LOGGER.severe( jdomE.getMessage() );
+         return Collections.emptyList();
+      } catch ( IOException ioE ) {
+         LOGGER.severe( ioE.getMessage() );
+         return Collections.emptyList();
+      }
+   }
+
+
+   /**
+    * @param rootElement the root xml element in an annotation xml file
+    * @return map of entityIDs and Knowtator Entities
+    */
+   private Map<String, Entity> getEntityMap( final Element rootElement ) {
+//      <entity>
+//         <id>37@e@ID001_path_002@ahoward</id>
+//         <span>118,137</span>
+//         <type>EVENT</type>
+//         <parentsType>TemporalEntities</parentsType>
+//         <properties>
+//            <DocTimeRel>BEFORE</DocTimeRel>
+//            <Type>N/A</Type>
+//            <Degree>N/A</Degree>
+//            <Polarity>POS</Polarity>
+//            <ContextualModality>ACTUAL</ContextualModality>
+//            <ContextualAspect>N/A</ContextualAspect>
+//            <Permanence>UNDETERMINED</Permanence>
+//         </properties>
+//      </entity>
+      final List<Element> annotationElementList = rootElement.getChildren( ANNOTATION_ELEMENT_NAME );
+      final Map<String, Entity> entityMap = new HashMap<>();
+      final String documentText = getDocumentText();
+      final List<Attribute> attributeList = new ArrayList<>();
+      for ( Element annotationElement : annotationElementList ) {
+         final List<Element> entityElementList = annotationElement.getChildren( ENTITY_ELEMENT_NAME );
+         for ( Element entityElement : entityElementList ) {
+            final String parentsTypeText = entityElement.getChildText( ANNOTATION_PARENTS_TYPE_ELEMENT_NAME );
+            if ( parentsTypeText != null && parentsTypeText.equals( PARENTS_TYPE_COREF ) ) {
+               continue;
+            }
+            final String entityId = entityElement.getChildText( ANNOTATION_ID_ELEMENT_NAME );
+            final List<Element> spanElementList = entityElement.getChildren( ANNOTATION_SPAN_ELEMENT_NAME );
+            final TextSpan span = createTextSpan( spanElementList );
+            if ( span.equals( BAD_TEXT_SPAN ) ) {
+               continue;
+            }
+            final String spannedText = getSpannedText( span, documentText );
+            final String classTypeName = entityElement.getChildText( ANNOTATION_TYPE_ELEMENT_NAME );
+            final ClassType classType = ClassTypeFactory.getClassType( classTypeName );
+//            final List<Attribute> attributeList = new ArrayList<>();
+            final Element propertiesElement = entityElement.getChild( ANNOTATION_PROPERTIES_ELEMENT_NAME );
+            if ( propertiesElement != null ) {
+               final List<Element> attributeElementList = propertiesElement.getChildren();
+               for ( Element attributeElement : attributeElementList ) {
+                  final String attributeName = attributeElement.getName();
+                  final String attributeValue = attributeElement.getText();
+                  attributeList.add( new DefaultAttribute( attributeName, attributeValue ) );
+               }
+            }
+            attributeList.add( new DefaultAttribute( DefinedAttributeType.UNIQUE_ID, entityId ) );
+            final Entity entity = new DefaultEntity( span, spannedText, classType,
+                  attributeList.toArray( new Attribute[ attributeList.size() ] ) );
+            entityMap.put( entityId, entity );
+            attributeList.clear();
+         }
+      }
+      return entityMap;
+   }
+
+   /**
+    * @param rootElement the root xml element in an annotation xml file
+    * @return map of entityIDs and Knowtator Entities
+    */
+   private Map<String, Entity> getMarkableMap( final Element rootElement ) {
+      //      <entity>
+      //         <id>37@e@ID001_path_002@ahoward</id>
+      //         <span>118,137</span>
+      //         <type>EVENT</type>
+      //         <parentsType>TemporalEntities</parentsType>
+      //         <properties>
+      //            <DocTimeRel>BEFORE</DocTimeRel>
+      //            <Type>N/A</Type>
+      //            <Degree>N/A</Degree>
+      //            <Polarity>POS</Polarity>
+      //            <ContextualModality>ACTUAL</ContextualModality>
+      //            <ContextualAspect>N/A</ContextualAspect>
+      //            <Permanence>UNDETERMINED</Permanence>
+      //         </properties>
+      //      </entity>
+      final List<Element> annotationElementList = rootElement.getChildren( ANNOTATION_ELEMENT_NAME );
+      final Map<String, Entity> entityMap = new HashMap<>();
+      final String documentText = getDocumentText();
+      for ( Element annotationElement : annotationElementList ) {
+         final List<Element> entityElementList = annotationElement.getChildren( ENTITY_ELEMENT_NAME );
+         for ( Element entityElement : entityElementList ) {
+            final String parentsTypeText = entityElement.getChildText( ANNOTATION_PARENTS_TYPE_ELEMENT_NAME );
+            if ( parentsTypeText == null || !parentsTypeText.equals( PARENTS_TYPE_COREF ) ) {
+               continue;
+            }
+            final String entityId = entityElement.getChildText( ANNOTATION_ID_ELEMENT_NAME );
+            final List<Element> spanElementList = entityElement.getChildren( ANNOTATION_SPAN_ELEMENT_NAME );
+            final TextSpan span = createTextSpan( spanElementList );
+            if ( span.equals( BAD_TEXT_SPAN ) ) {
+               continue;
+            }
+            final String spannedText = getSpannedText( span, documentText );
+            final String classTypeName = entityElement.getChildText( ANNOTATION_TYPE_ELEMENT_NAME );
+            final ClassType classType = ClassTypeFactory.getClassType( classTypeName );
+            final List<Attribute> attributeList = new ArrayList<>();
+            final Element propertiesElement = entityElement.getChild( ANNOTATION_PROPERTIES_ELEMENT_NAME );
+            if ( propertiesElement != null ) {
+               final List<Element> attributeElementList = propertiesElement.getChildren();
+               for ( Element attributeElement : attributeElementList ) {
+                  final String attributeName = attributeElement.getName();
+                  final String attributeValue = attributeElement.getText();
+                  attributeList.add( new DefaultAttribute( attributeName, attributeValue ) );
+               }
+            }
+            attributeList.add( new DefaultAttribute( DefinedAttributeType.UNIQUE_ID, entityId ) );
+            final Entity entity = new DefaultEntity( span, spannedText, classType,
+                  attributeList.toArray( new Attribute[] { } ) );
+            entityMap.put( entityId, entity );
+         }
+      }
+      return entityMap;
+   }
+
+
+   /**
+    * @param rootElement the root xml element in an annotation xml file
+    * @return map of entityIDs and Anafora Entities
+    */
+   private List<Collection<TextSpan>> getCoreferenceTextSpans( final Element rootElement ) {
+//      <annotations>
+//          <entity>
+//             <id>113@e@ID000_clinic_demo@gold</id>
+//             <span>509,526</span>
+//             <type>Markable</type>
+//             <parentsType>Coreference</parentsType>
+//             <properties>
+//             </properties>
+//             <addition>
+//                <adjudication>gold</adjudication>
+//             </addition>
+//          </entity>
+//
+//          <relation>
+//             <id>36@r@ID000_clinic_demo@gold</id>
+//             <type>Identical</type>
+//             <parentsType>CorefChains</parentsType>
+//             <properties>
+//                <FirstInstance>113@e@ID000_clinic_demo@gold</FirstInstance>
+//                <Coreferring_String>115@e@ID000_clinic_demo@gold</Coreferring_String>
+//                <Coreferring_String>196@e@ID000_clinic_demo@gold</Coreferring_String>
+//                <Coreferring_String>136@e@ID000_clinic_demo@gold</Coreferring_String>
+//                <Coreferring_String>197@e@ID000_clinic_demo@gold</Coreferring_String>
+//                <Coreferring_String>198@e@ID000_clinic_demo@gold</Coreferring_String>
+//             </properties>
+//             <addition>
+//                <adjudication>gold</adjudication>
+//             </addition>
+//          </relation>
+//
+//          <relation>
+//             <id>40@r@ID000_clinic_demo@gold</id>
+//             <type>Set/Subset</type>
+//             <parentsType>CorefChains</parentsType>
+//             <properties>
+//                <Set>124@e@ID000_clinic_demo@gold</Set>
+//                <Subset>118@e@ID000_clinic_demo@gold</Subset>
+//                <Subset>207@e@ID000_clinic_demo@gold</Subset>
+//             </properties>
+//          </relation>
+//
+//          <relation>
+//             <id>43@r@ID000_clinic_demo@gold</id>
+//             <type>Whole/Part</type>
+//             <parentsType>CorefChains</parentsType>
+//             <properties>
+//                <Whole>134@e@ID000_clinic_demo@gold</Whole>
+//                <Part>132@e@ID000_clinic_demo@gold</Part>
+//                <Part>133@e@ID000_clinic_demo@gold</Part>
+//             </properties>
+//          </relation>
+//
+//          <relation>
+//             <id>84@r@ID000_clinic_demo@gold</id>
+//             <type>Appositive</type>
+//             <parentsType>CorefChains</parentsType>
+//             <properties>
+//                <Head>235@e@ID000_clinic_demo@gold</Head>
+//                <Attributes>236@e@ID000_clinic_demo@gold</Attributes>
+//             </properties>
+//             <addition>
+//                <adjudication>gold</adjudication>
+//             </addition>
+//          </relation>
+      final Map<String, Entity> corefEntities = getMarkableMap( rootElement );
+      if ( corefEntities.isEmpty() ) {
+         return Collections.emptyList();
+      }
+      final List<Element> annotationElementList = rootElement.getChildren( ANNOTATION_ELEMENT_NAME );
+      final java.util.List<Collection<TextSpan>> corefSpanChains = new ArrayList<>();
+      for ( Element annotationElement : annotationElementList ) {
+         final List<Element> relationElementList = annotationElement.getChildren( RELATION_ELEMENT_NAME );
+         for ( Element relationElement : relationElementList ) {
+            final String parentsTypeText = relationElement.getChildText( ANNOTATION_PARENTS_TYPE_ELEMENT_NAME );
+            if ( parentsTypeText == null || !parentsTypeText.equals( PARENTS_TYPE_COREF_CHAIN ) ) {
+               continue;
+            }
+            //            final String relationId = relationElement.getChildText( ANNOTATION_ID_ELEMENT_NAME );
+            final String classTypeName = relationElement.getChildText( ANNOTATION_TYPE_ELEMENT_NAME );
+            if ( !classTypeName.equals( "Identical" ) ) {
+               continue;
+            }
+//            final ClassType classType = ((classTypeName == null || classTypeName.isEmpty())
+//                                         ? UnknownClassType.getInstance()
+//                                         : new CustomClassType( classTypeName ));
+            final Collection<TextSpan> corefSpans = new HashSet<>();
+            final Element propertiesElement = relationElement.getChild( ANNOTATION_PROPERTIES_ELEMENT_NAME );
+            if ( propertiesElement != null ) {
+               final List<Element> propertyElementList = propertiesElement.getChildren();
+               for ( Element propertyElement : propertyElementList ) {
+                  final String corefPlace = propertyElement.getName();
+                  if ( corefPlace.equals( "FirstInstance" ) || corefPlace.equals( "Coreferring_String" ) ) {
+                     final String entityId = propertyElement.getText();
+                     final Entity entity = corefEntities.get( entityId );
+                     if ( entity != null ) {
+                        corefSpans.add( entity.getTextSpan() );
+                     }
+                  }
+               }
+            }
+            if ( !corefSpans.isEmpty() || corefSpans.size() < 2 ) {
+               corefSpanChains.add( corefSpans );
+            }
+         }
+      }
+//      return Collections.unmodifiableList( corefSpanChains );
+      return corefSpanChains;
+   }
+
+
+   /**
+    * @param rootElement xml root element
+    * @param entityMap   map of elementIDs and Entities
+    * @return list of Relations created with all the given information
+    */
+   static private List<Relation> getRelations( final Element rootElement, final Map<String, Entity> entityMap ) {
+//      <relation>
+//         <id>1@r@ID001_path_002@ahoward</id>
+//         <type>TLINK</type>
+//         <parentsType>TemporalRelations</parentsType>
+//         <properties>
+//            <Source>14@e@ID001_path_002@ahoward</Source>
+//            <Target>12@e@ID001_path_002@ahoward</Target>
+//            <Type>AFTER</Type>
+//         </properties>
+//      </relation>
+      if ( entityMap.isEmpty() ) {
+         return Collections.emptyList();
+      }
+      final List<Element> annotationElementList = rootElement.getChildren( ANNOTATION_ELEMENT_NAME );
+      final List<Relation> relationList = new ArrayList<>();
+      for ( Element annotationElement : annotationElementList ) {
+         final List<Element> relationElementList = annotationElement.getChildren( RELATION_ELEMENT_NAME );
+         for ( Element relationElement : relationElementList ) {
+            final String parentsTypeText = relationElement.getChildText( ANNOTATION_PARENTS_TYPE_ELEMENT_NAME );
+            if ( parentsTypeText != null && parentsTypeText.equals( PARENTS_TYPE_COREF_CHAIN ) ) {
+               continue;
+            }
+            final String relationId = relationElement.getChildText( ANNOTATION_ID_ELEMENT_NAME );
+            final String classTypeName = relationElement.getChildText( ANNOTATION_TYPE_ELEMENT_NAME );
+            final ClassType classType = ClassTypeFactory.getClassType( classTypeName );
+            String sourceEntityId = "";
+            String targetEntityId = "";
+            final List<Attribute> attributeList = new ArrayList<>();
+            final Element propertiesElement = relationElement.getChild( ANNOTATION_PROPERTIES_ELEMENT_NAME );
+            if ( propertiesElement != null ) {
+               final List<Element> attributeElementList = propertiesElement.getChildren();
+               for ( Element attributeElement : attributeElementList ) {
+                  final String attributeName = attributeElement.getName();
+                  final String attributeValue = attributeElement.getText();
+                  if ( attributeName.equalsIgnoreCase( RELATION_SOURCE_PROPERTY_NAME ) ) {
+                     sourceEntityId = attributeValue;
+                  } else if ( attributeName.equalsIgnoreCase( RELATION_TARGET_PROPERTY_NAME ) ) {
+                     targetEntityId = attributeValue;
+                  } else if ( attributeName.equalsIgnoreCase( ANNOTATION_TYPE_ELEMENT_NAME ) ) {
+                     attributeList
+                           .add( new DefaultAttribute( DefinedAttributeType.RELATION_TYPE.getName(), attributeValue ) );
+                  } else {
+                     attributeList.add( new DefaultAttribute( attributeName, attributeValue ) );
+                  }
+               }
+            }
+            if ( sourceEntityId.isEmpty() || targetEntityId.isEmpty() ) {
+               Logger.getAnonymousLogger().severe( "Relation " + relationId
+                                                   + " has no Source " + sourceEntityId
+                                                   + " and/or no Target " + targetEntityId );
+               continue;
+            }
+            final Entity entity1 = entityMap.get( sourceEntityId );
+            final Entity entity2 = entityMap.get( targetEntityId );
+            if ( entity1 == null || entity2 == null ) {
+               Logger.getAnonymousLogger().severe( "Relation " + relationId
+                                                   + " Source " + sourceEntityId
+                                                   + " and/or Target " + targetEntityId + " does not exist" );
+               continue;
+            }
+            attributeList.add( new DefaultAttribute( DefinedAttributeType.UNIQUE_ID, relationId ) );
+            final Relation relation = new DefaultRelation( entity1, entity2, classType,
+                  attributeList.toArray( new Attribute[ attributeList.size() ] ) );
+            relationList.add( relation );
+         }
+      }
+      return Collections.unmodifiableList( relationList );
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected TextSpan createEntityTextSpan( final Element spanElement ) {
+      final String text = spanElement.getText();
+      if ( text == null || text.isEmpty() ) {
+         return BAD_TEXT_SPAN;
+      }
+      final String[] splits = text.split( ";" );
+      if ( splits.length == 1 ) {
+         return createEntityTextSpan( splits[ 0 ].trim() );
+      }
+
+      final List<TextSpan> spanList = new ArrayList<>( splits.length );
+      for ( String split : splits ) {
+         if ( !split.trim().isEmpty() ) {
+            spanList.add( createEntityTextSpan( split.trim() ) );
+         }
+      }
+      return new DefaultDiscontiguousTextSpan( spanList.toArray( new TextSpan[ spanList.size() ] ) );
+   }
+
+   protected TextSpan createEntityTextSpan( final String spanIndices ) {
+      final String[] numbers = spanIndices.split( "," );
+      if ( numbers.length != 2 ) {
+         return BAD_TEXT_SPAN;
+      }
+      try {
+         final int startIndex = Integer.parseInt( numbers[ 0 ] );
+         final int endIndex = Integer.parseInt( numbers[ 1 ] );
+         return new EntityTextSpan( startIndex, endIndex );
+      } catch ( NumberFormatException nfE ) {
+         LOGGER.severe( nfE.getMessage() );
+         return BAD_TEXT_SPAN;
+      }
+   }
+
+
+   /**
+    * Anafora XML does not provide actual text, but the document text may be known.
+    * If the document text is known then this simply returns a substring, otherwise a string of 'A'
+    *
+    * @param textSpan -
+    * @return The spanned text within provided document text, or a String filled with character 'A'
+    */
+   static private String getSpannedText( final TextSpan textSpan, final String documentText ) {
+      if ( documentText == null || documentText.isEmpty() ) {
+         return fakeSomeText( textSpan );
+      }
+      final int startIndex = textSpan.getStartIndex();
+      final int endIndex = textSpan.getEndIndex();
+      if ( startIndex >= 0 && endIndex < documentText.length() ) {
+         return documentText.substring( startIndex, endIndex );
+      }
+      return fakeSomeText( textSpan );
+   }
+
+   /**
+    * Anafora XML does not provide actual text, so we need to fake it.
+    * This will knock some of the IAA capabilities, such as Alpha computations based upon word count,
+    * marked comparison by word count, etc.
+    *
+    * @param textSpan -
+    * @return A String the length of the textSpan filled with the character 'A'
+    */
+   static private String fakeSomeText( final TextSpan textSpan ) {
+      if ( textSpan instanceof DefaultDiscontiguousTextSpan ) {
+         final TextSpan jointTextSpan = new DefaultTextSpan( textSpan.getStartIndex(), textSpan.getEndIndex() );
+         return fakeSomeText( jointTextSpan );
+      }
+      final char[] chars = new char[ textSpan.getLength() ];
+      Arrays.fill( chars, 'A' );
+      return String.valueOf( chars );
+   }
+
+
+}

Added: ctakes/sandbox/timelanes/org/chboston/cnlp/anafora/annotation/parser/AnaforaXmlWriter.java
URL: http://svn.apache.org/viewvc/ctakes/sandbox/timelanes/org/chboston/cnlp/anafora/annotation/parser/AnaforaXmlWriter.java?rev=1660963&view=auto
==============================================================================
--- ctakes/sandbox/timelanes/org/chboston/cnlp/anafora/annotation/parser/AnaforaXmlWriter.java (added)
+++ ctakes/sandbox/timelanes/org/chboston/cnlp/anafora/annotation/parser/AnaforaXmlWriter.java Thu Feb 19 18:06:13 2015
@@ -0,0 +1,9 @@
+package org.chboston.cnlp.anafora.annotation.parser;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 10/13/2014
+ */
+public class AnaforaXmlWriter {
+}

Added: ctakes/sandbox/timelanes/org/chboston/cnlp/gui/FileSelectionPanel.java
URL: http://svn.apache.org/viewvc/ctakes/sandbox/timelanes/org/chboston/cnlp/gui/FileSelectionPanel.java?rev=1660963&view=auto
==============================================================================
--- ctakes/sandbox/timelanes/org/chboston/cnlp/gui/FileSelectionPanel.java (added)
+++ ctakes/sandbox/timelanes/org/chboston/cnlp/gui/FileSelectionPanel.java Thu Feb 19 18:06:13 2015
@@ -0,0 +1,159 @@
+package org.chboston.cnlp.gui;
+
+import javax.swing.*;
+import javax.swing.border.EmptyBorder;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.Document;
+import javax.swing.text.PlainDocument;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.File;
+import java.util.Collection;
+import java.util.HashSet;
+
+/**
+ * Widget that contains a file/dir selection label, a textbox that displays the currently selected file path,
+ * and an "Open" button to open a JFileChooser to select a new file/directory
+ * Author: SPF
+ * Affiliation: CHIP-NLP
+ * Date: 5/30/12
+ */
+public class FileSelectionPanel extends JPanel {
+
+   static public final String FILE_SELECTED = "FILE_SELECTED";
+
+   private Collection<ActionListener> _actionListeners;
+   private final Document _textAreaDoc = new PlainDocument();
+
+   /**
+    * @param labelText        text for the label, something like "Selected File:"
+    * @param selectionMode    a selection mode for the JFileChooser - dir only, file only, dir & file
+    * @param defaultDirectory starting directory
+    */
+   public FileSelectionPanel( final String labelText, final int selectionMode, final String defaultDirectory ) {
+      super( new BorderLayout( 10, 10 ) );
+      setBorder( new EmptyBorder( 5, 5, 5, 5 ) );
+      final JLabel label = new JLabel( labelText );
+      final JTextField field = new JTextField();
+      field.setEditable( false );  // Can remove this and add "turn font red" file exist checking
+      field.setDocument( _textAreaDoc );
+      final JButton openChooserButton = new JButton( new OpenFileAction( _textAreaDoc,
+            selectionMode,
+            defaultDirectory ) );
+      add( label, BorderLayout.WEST );
+      add( field, BorderLayout.CENTER );
+      add( openChooserButton, BorderLayout.EAST );
+      if ( defaultDirectory != null ) {
+         setFilePath( defaultDirectory );
+      }
+   }
+
+   /**
+    * @return the currently selected file or directory path
+    */
+   public String getFilePath() {
+      return getText( _textAreaDoc );
+   }
+
+   /**
+    * reset the file path
+    */
+   public void clearFilePath() {
+      clearText( _textAreaDoc );
+   }
+
+   /**
+    * @param filePath the file path that this widget should care about
+    */
+   public void setFilePath( final String filePath ) {
+      clearText( _textAreaDoc );
+      appendText( _textAreaDoc, filePath );
+   }
+
+   public void addActionListener( final ActionListener listener ) {
+      if ( _actionListeners == null ) {
+         _actionListeners = new HashSet<>( 1 );
+      }
+      _actionListeners.add( listener );
+   }
+
+   private void fireFileSelected() {
+      if ( _actionListeners == null ) {
+         return;
+      }
+      final ActionEvent event = new ActionEvent( this, ActionEvent.ACTION_PERFORMED, FILE_SELECTED );
+      for ( ActionListener listener : _actionListeners ) {
+         listener.actionPerformed( event );
+      }
+   }
+
+   /**
+    * @param doc the document of the text gui
+    * @return all text in the gui
+    */
+   static private String getText( final Document doc ) {
+      try {
+         return doc.getText( 0, doc.getLength() );
+      } catch ( BadLocationException blE ) {
+         return "";
+      }
+   }
+
+   /**
+    * clears all text
+    *
+    * @param doc the document of the text gui
+    */
+   static private void clearText( final Document doc ) {
+      try {
+         doc.remove( 0, doc.getLength() );
+      } catch ( BadLocationException blE ) {
+         //
+      }
+   }
+
+   /**
+    * @param doc  the document of the text gui
+    * @param text new text for the gui
+    */
+   static private void appendText( final Document doc, final String text ) {
+      try {
+         doc.insertString( doc.getLength(), text, null );
+      } catch ( BadLocationException blE ) {
+         //
+      }
+   }
+
+   /**
+    * Opens the JFileChooser
+    */
+   private class OpenFileAction extends AbstractAction {
+      private final JFileChooser __chooser;
+      private final Document __filePathDoc;
+
+      private OpenFileAction( final Document filePathDoc, final int selectionMode, final String defaultDirectory ) {
+         super( "Open" );
+         __filePathDoc = filePathDoc;
+         __chooser = new JFileChooser();
+         if ( defaultDirectory != null ) {
+            final File startingDir = new File( defaultDirectory );
+            if ( startingDir.exists() ) {
+               __chooser.setCurrentDirectory( startingDir );
+            }
+         }
+         __chooser.setFileSelectionMode( selectionMode );
+      }
+
+      public void actionPerformed( final ActionEvent event ) {
+         final int option = __chooser.showOpenDialog( null );
+         if ( option != JFileChooser.APPROVE_OPTION ) {
+            return;
+         }
+         clearText( __filePathDoc );
+         appendText( __filePathDoc, __chooser.getSelectedFile().getPath() );
+         fireFileSelected();
+      }
+   }
+
+}

Added: ctakes/sandbox/timelanes/org/chboston/cnlp/gui/FontResizeSlider.java
URL: http://svn.apache.org/viewvc/ctakes/sandbox/timelanes/org/chboston/cnlp/gui/FontResizeSlider.java?rev=1660963&view=auto
==============================================================================
--- ctakes/sandbox/timelanes/org/chboston/cnlp/gui/FontResizeSlider.java (added)
+++ ctakes/sandbox/timelanes/org/chboston/cnlp/gui/FontResizeSlider.java Thu Feb 19 18:06:13 2015
@@ -0,0 +1,87 @@
+package org.chboston.cnlp.gui;
+
+import javax.swing.*;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import java.awt.*;
+
+/**
+ * Author: SPF
+ * Affiliation: CHIP-NLP
+ * Date: 10/15/13
+ */
+final public class FontResizeSlider {
+
+
+   static public JMenu createFontResizeMenu( final Container mainContainer ) {
+      final JMenu fontSizeMenu = new JMenu( "Font Size" );
+      final JSlider fontSizer = new JSlider( 1, 10, 3 );
+      final BoundedRangeModel sizerModel = fontSizer.getModel();
+      sizerModel.addChangeListener( new FontSizerListener( mainContainer ) );
+      fontSizeMenu.add( fontSizer );
+      return fontSizeMenu;
+   }
+
+
+   static private class FontSizerListener implements ChangeListener {
+      final private Container __mainContainer;
+
+      private int __oldValue = 3;
+      private boolean __changing = false;
+      private final Object LOCK = new Object();
+
+      private FontSizerListener( final Container mainContainer ) {
+         __mainContainer = mainContainer;
+      }
+
+      public void stateChanged( final ChangeEvent event ) {
+         if ( event.getSource() instanceof BoundedRangeModel ) {
+            final int value = ((BoundedRangeModel)event.getSource()).getValue();
+            if ( value == __oldValue || __changing ) {
+               return;
+            }
+            synchronized ( LOCK ) {
+               if ( __changing ) {
+                  return;
+               }
+               __changing = true;
+               final int delta = value - __oldValue;
+               resizeFont( __mainContainer, delta );
+               __oldValue = value;
+               __changing = false;
+            }
+         }
+      }
+
+      private void resizeFont( final Component comp, final int delta ) {
+         if ( comp == null ) {
+            return;
+         }
+         final Font font = comp.getFont();
+         if ( font == null ) {
+            return;
+         }
+         final int oldSize = font.getSize();
+         final float newSize = oldSize + delta;
+         final Font newFont = font.deriveFont( newSize );
+         comp.setFont( newFont );
+         if ( comp instanceof Container ) {
+            resizeChildFonts( (Container)comp, delta );
+            if ( comp instanceof JTable ) {
+               final int rowHeightDelta = delta > 0 ? (int)Math.floor( delta * 1.5 ) : (int)Math.ceil( delta * 1.5 );
+               ((JTable)comp).setRowHeight( ((JTable)comp).getRowHeight() + rowHeightDelta );
+            }
+         }
+      }
+
+      private void resizeChildFonts( final Container container, final int delta ) {
+         final int childCount = container.getComponentCount();
+         for ( int i = 0; i < childCount; i++ ) {
+            final Component child = container.getComponent( i );
+            resizeFont( child, delta );
+         }
+      }
+
+   }
+
+}

Added: ctakes/sandbox/timelanes/org/chboston/cnlp/gui/GlobalHotkeyManager.java
URL: http://svn.apache.org/viewvc/ctakes/sandbox/timelanes/org/chboston/cnlp/gui/GlobalHotkeyManager.java?rev=1660963&view=auto
==============================================================================
--- ctakes/sandbox/timelanes/org/chboston/cnlp/gui/GlobalHotkeyManager.java (added)
+++ ctakes/sandbox/timelanes/org/chboston/cnlp/gui/GlobalHotkeyManager.java Thu Feb 19 18:06:13 2015
@@ -0,0 +1,63 @@
+package org.chboston.cnlp.gui;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.KeyEvent;
+
+/**
+ * Author: SPF
+ * Affiliation: CHIP-NLP
+ * Date: 2/19/14
+ */
+final public class GlobalHotkeyManager extends EventQueue {
+   private static final GlobalHotkeyManager INSTANCE = new GlobalHotkeyManager();
+   private final InputMap _keyStrokes = new InputMap();
+   private final ActionMap _actions = new ActionMap();
+
+   static {
+      // here we register ourselves as a new link in the chain of
+      // responsibility
+      Toolkit.getDefaultToolkit().getSystemEventQueue().push( INSTANCE );
+   }
+
+   private GlobalHotkeyManager() {
+   } // One is enough - singleton
+
+   public static GlobalHotkeyManager getInstance() {
+      return INSTANCE;
+   }
+
+   //   public InputMap getInputMap() {
+//      return _keyStrokes;
+//   }
+//   public ActionMap getActionMap() {
+//      return _actions;
+//   }
+   public void addHotKey( final String name, final KeyStroke keyStroke, final Action action ) {
+      _keyStrokes.put( keyStroke, name );
+      _actions.put( name, action );
+   }
+
+   protected void dispatchEvent( final AWTEvent event ) {
+      if ( event instanceof KeyEvent ) {
+         // KeyStroke.getKeyStrokeForEvent converts an ordinary KeyEvent
+         // to a keystroke, as stored in the InputMap.  Keep in mind that
+         // Numpad keystrokes are different to ordinary keys, i.e. if you
+         // are listening to
+         final KeyStroke ks = KeyStroke.getKeyStrokeForEvent( (KeyEvent)event );
+         String actionKey = (String)_keyStrokes.get( ks );
+         if ( actionKey != null ) {
+            final Action action = _actions.get( actionKey );
+            if ( action != null && action.isEnabled() ) {
+               // I'm not sure about the parameters
+               action.actionPerformed(
+                     new ActionEvent( event.getSource(), event.getID(),
+                           actionKey, ((KeyEvent)event).getModifiers() ) );
+               return; // consume event
+            }
+         }
+      }
+      super.dispatchEvent( event ); // let the next in chain handle event
+   }
+}

Added: ctakes/sandbox/timelanes/org/chboston/cnlp/gui/LinkedScrollBarHandler.java
URL: http://svn.apache.org/viewvc/ctakes/sandbox/timelanes/org/chboston/cnlp/gui/LinkedScrollBarHandler.java?rev=1660963&view=auto
==============================================================================
--- ctakes/sandbox/timelanes/org/chboston/cnlp/gui/LinkedScrollBarHandler.java (added)
+++ ctakes/sandbox/timelanes/org/chboston/cnlp/gui/LinkedScrollBarHandler.java Thu Feb 19 18:06:13 2015
@@ -0,0 +1,88 @@
+package org.chboston.cnlp.gui;
+
+import javax.swing.*;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Author: SPF
+ * Affiliation: CHIP-NLP
+ * Date: 9/14/12
+ */
+public class LinkedScrollBarHandler {
+
+   final CommonChangeListener _commonChangeListener = new CommonChangeListener();
+   final private Set<BoundedRangeModel> _rangeModelSet = new HashSet<>();
+   private boolean _valueIsAdjusting;
+
+
+   public void addScrollBar( final JScrollBar scrollBar, final boolean isController ) {
+      if ( scrollBar != null ) {
+         final BoundedRangeModel rangeModel = scrollBar.getModel();
+         if ( rangeModel == null ) {
+            return;
+         }
+         final boolean added = _rangeModelSet.add( rangeModel );
+         if ( added && isController ) {
+            rangeModel.addChangeListener( _commonChangeListener );
+         }
+      }
+   }
+
+   public void removeScrollBar( final JScrollBar scrollBar, final boolean isController ) {
+      if ( scrollBar != null ) {
+         final BoundedRangeModel rangeModel = scrollBar.getModel();
+         if ( rangeModel == null ) {
+            return;
+         }
+         final boolean removed = _rangeModelSet.remove( rangeModel );
+         if ( removed && isController ) {
+            rangeModel.removeChangeListener( _commonChangeListener );
+         }
+      }
+   }
+
+   private class CommonChangeListener implements ChangeListener {
+      synchronized public void stateChanged( final ChangeEvent event ) {
+         if ( _valueIsAdjusting ) {
+            return;
+         }
+         final Object source = event.getSource();
+         if ( !(source instanceof BoundedRangeModel) ) {
+            return;
+         }
+         final BoundedRangeModel changedRangeModel = (BoundedRangeModel)source;
+         if ( changedRangeModel.getValueIsAdjusting() && _rangeModelSet.size() > 10 ) {
+            // if there are many scrollpanes with slow paints then we may want to adjust their viewport only after
+            // change is done, rather than update all panes with real-time scrolling
+            return;
+         }
+         _valueIsAdjusting = true;
+         final int min = changedRangeModel.getMinimum();
+         final int max = changedRangeModel.getMaximum();
+         final int extent = changedRangeModel.getExtent();
+         final int maxEx = max - extent;
+         if ( maxEx <= min ) {
+            _valueIsAdjusting = false;
+            return;
+         }
+         final int value = changedRangeModel.getValue();
+         final double change = value / (double)(maxEx - min);
+         for ( BoundedRangeModel rangeModel : _rangeModelSet ) {
+            final int total = rangeModel.getMaximum() - rangeModel.getExtent() - rangeModel.getMinimum();
+            if ( total < 1 ) {
+               continue;
+            }
+            final int adjust = (int)(change * total);
+            if ( rangeModel.getValue() != adjust ) {
+               // don't trust the rangeModel to handle old vs new value checks as it may be a custom implementation
+               rangeModel.setValue( rangeModel.getMinimum() + adjust );
+            }
+         }
+         _valueIsAdjusting = false;
+      }
+   }
+
+}



Mime
View raw message