ctakes-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From seanfi...@apache.org
Subject svn commit: r1660963 [7/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/org/chboston/cnlp/nlp/annotation/entity/DefaultEntity.java
URL: http://svn.apache.org/viewvc/ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/entity/DefaultEntity.java?rev=1660963&view=auto
==============================================================================
--- ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/entity/DefaultEntity.java (added)
+++ ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/entity/DefaultEntity.java Thu Feb 19 18:06:13 2015
@@ -0,0 +1,196 @@
+package org.chboston.cnlp.nlp.annotation.entity;
+
+import org.chboston.cnlp.nlp.annotation.annotation.Annotation;
+import org.chboston.cnlp.nlp.annotation.annotation.DefaultAnnotation;
+import org.chboston.cnlp.nlp.annotation.attribute.Attribute;
+import org.chboston.cnlp.nlp.annotation.attribute.AttributeType;
+import org.chboston.cnlp.nlp.annotation.classtype.ClassType;
+import org.chboston.cnlp.nlp.annotation.textspan.EntityTextSpan;
+import org.chboston.cnlp.nlp.annotation.textspan.TextSpan;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.logging.Logger;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 12/1/2014
+ */
+public class DefaultEntity implements Entity {
+
+   static private final Logger LOGGER = Logger.getLogger( "DefaultEntity" );
+
+   static private final int HASH_OFFSET = 3;
+
+   final private Annotation _annotation;
+   final private int _hashCode;
+
+   public DefaultEntity( final int startIndex, final int endIndex,
+                         final String spannedText, final ClassType classType,
+                         final Attribute... attributes ) {
+      this( new EntityTextSpan( startIndex, endIndex ), spannedText, classType, attributes );
+   }
+
+   public DefaultEntity( final TextSpan span, final String spannedText, final ClassType classType,
+                         final Attribute... attributes ) {
+      _annotation = new DefaultAnnotation( span, spannedText, classType, attributes );
+      _hashCode = HASH_OFFSET + _annotation.hashCode();
+   }
+
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public TextSpan getTextSpan() {
+      return _annotation.getTextSpan();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public String getSpannedText() {
+      return _annotation.getSpannedText();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public String getSpannedTextRepresentation() {
+      return _annotation.getSpannedTextRepresentation();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public ClassType getClassType() {
+      return _annotation.getClassType();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public boolean isClassType( final ClassType classType ) {
+      return _annotation.isClassType( classType );
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public List<String> getAttributeNames() {
+      return _annotation.getAttributeNames();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public Attribute getAttribute( final String key ) {
+      return _annotation.getAttribute( key );
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public Attribute getAttribute( final AttributeType attributeType ) {
+      return _annotation.getAttribute( attributeType );
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public Collection<AttributeType> getAttributeTypes() {
+      return _annotation.getAttributeTypes();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public Collection<Attribute> getAttributes() {
+      return _annotation.getAttributes();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public boolean hasAttribute( final String key ) {
+      return _annotation.hasAttribute( key );
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public boolean hasAttribute( final AttributeType attributeType ) {
+      return _annotation.hasAttribute( attributeType );
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public String getAttributeValue( final String key ) {
+      return _annotation.getAttributeValue( key );
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public String getAttributeValue( final AttributeType attributeType ) {
+      return _annotation.getAttributeValue( attributeType );
+   }
+
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public String getAnnotatorName() {
+      return _annotation.getAnnotatorName();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public boolean areValuesEqual( final Annotation annotation ) {
+      return _annotation.areValuesEqual( annotation );
+   }
+
+
+   /**
+    * @return "Entity: {@link org.chboston.cnlp.nlp.annotation.annotation.DefaultAnnotation#toString()}"
+    */
+   @Override
+   public String toString() {
+      return "Entity: " + _annotation.toString();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public int hashCode() {
+      return _hashCode;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public boolean equals( final Object object ) {
+      return object instanceof Entity && _annotation.equals( object );
+   }
+
+}

Added: ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/entity/Entity.java
URL: http://svn.apache.org/viewvc/ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/entity/Entity.java?rev=1660963&view=auto
==============================================================================
--- ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/entity/Entity.java (added)
+++ ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/entity/Entity.java Thu Feb 19 18:06:13 2015
@@ -0,0 +1,12 @@
+package org.chboston.cnlp.nlp.annotation.entity;
+
+import org.chboston.cnlp.nlp.annotation.annotation.Annotation;
+
+/**
+ * Author: SPF
+ * Affiliation: CHIP-NLP
+ * Date: 5/8/12
+ */
+public interface Entity extends Annotation {
+
+}

Added: ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/event/DocTimeRel.java
URL: http://svn.apache.org/viewvc/ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/event/DocTimeRel.java?rev=1660963&view=auto
==============================================================================
--- ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/event/DocTimeRel.java (added)
+++ ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/event/DocTimeRel.java Thu Feb 19 18:06:13 2015
@@ -0,0 +1,47 @@
+package org.chboston.cnlp.nlp.annotation.event;
+
+import org.chboston.cnlp.nlp.annotation.annotation.Annotation;
+import org.chboston.cnlp.nlp.annotation.attribute.Attribute;
+import org.chboston.cnlp.nlp.annotation.attribute.DefinedAttributeType;
+
+/**
+ * Author: SPF
+ * Affiliation: CHIP-NLP
+ * Date: 7/16/13
+ */
+public enum DocTimeRel {
+   BEFORE( "BEFORE" ), AFTER( "AFTER" ), BEFORE_OVERLAP( "BEFORE/OVERLAP" ), OVERLAP( "OVERLAP" );
+   final private String __name;
+
+   DocTimeRel( final String name ) {
+      __name = name;
+   }
+
+   public String toString() {
+      return __name;
+   }
+
+   static public DocTimeRel getDocTimeRel( final Annotation entity ) {
+      final String docTimeRelText = getDocTimeRelText( entity );
+      return getDocTimeRel( docTimeRelText );
+   }
+
+   static public DocTimeRel getDocTimeRel( final String name ) {
+      for ( DocTimeRel docTimeRel : values() ) {
+         if ( docTimeRel.toString().equalsIgnoreCase( name ) ) {
+            return docTimeRel;
+         }
+      }
+      return null;
+   }
+
+   static public String getDocTimeRelText( final Annotation entity ) {
+      final Attribute docTimeRel = entity.getAttribute( DefinedAttributeType.DOC_TIME_REL.getName() );
+      if ( docTimeRel != null ) {
+         return docTimeRel.getValue();
+      }
+      return "";
+   }
+
+
+}

Added: ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/gui/EntityCollectionTableModel.java
URL: http://svn.apache.org/viewvc/ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/gui/EntityCollectionTableModel.java?rev=1660963&view=auto
==============================================================================
--- ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/gui/EntityCollectionTableModel.java (added)
+++ ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/gui/EntityCollectionTableModel.java Thu Feb 19 18:06:13 2015
@@ -0,0 +1,150 @@
+package org.chboston.cnlp.nlp.annotation.gui;
+
+import org.chboston.cnlp.nlp.annotation.annotation.AnnotationTextComparator;
+import org.chboston.cnlp.nlp.annotation.attribute.Attribute;
+import org.chboston.cnlp.nlp.annotation.attribute.DefinedAttributeType;
+import org.chboston.cnlp.nlp.annotation.entity.Entity;
+
+import javax.swing.table.AbstractTableModel;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Author: SPF
+ * Affiliation: CHIP-NLP
+ * Date: 7/9/13
+ */
+public class EntityCollectionTableModel extends AbstractTableModel {
+
+   static private enum COLUMN_NAME {
+      CUI( "Cui" ), TERM( "Term" ), CLASS_TYPE( "Class Type" ), SENTENCE( "Sentence" );
+      final private String __name;
+
+      private COLUMN_NAME( final String name ) {
+         __name = name;
+      }
+
+      public String toString() {
+         return __name;
+      }
+
+      static private COLUMN_NAME getColumnName( final int columnIndex ) {
+         return values()[ columnIndex ];
+      }
+   }
+
+   private List<Entity> _entityList;
+
+   /**
+    * @return entityList
+    */
+   public List<Entity> getEntityList() {
+      return _entityList;
+   }
+
+   public Entity getEntity( final int rowIndex ) {
+      if ( rowIndex >= getRowCount() ) {
+         return null;
+      }
+      return _entityList.get( rowIndex );
+   }
+
+   /**
+    * @param entityList entityList
+    */
+   public void setEntityList( final List<Entity> entityList ) {
+      final int oldRowCount = getRowCount();
+      if ( entityList != null ) {
+         _entityList = entityList;
+         Collections.sort( entityList, AnnotationTextComparator.getInstance() );
+      } else {
+         _entityList = Collections.emptyList();
+      }
+      fireTableRowsDeleted( 0, oldRowCount );
+      fireTableRowsInserted( 0, getRowCount() );
+   }
+
+   public String getValueAt( final Entity entity, final COLUMN_NAME columnName ) {
+      switch ( columnName ) {
+         case CUI:
+            return getAttributeValue( entity, DefinedAttributeType.CUI );
+         case TERM:
+            return entity.getSpannedText();
+         case CLASS_TYPE:
+            return entity.getClassType().getName();
+         case SENTENCE:
+            return getAttributeValue( entity, DefinedAttributeType.SENTENCE );
+      }
+      return "Unknown";
+   }
+
+   static private String getAttributeValue( final Entity entity, final DefinedAttributeType attributeType ) {
+      final Attribute attribute = entity.getAttribute( attributeType.getName() );
+      return attribute == null ? "-" : attribute.getValue();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public int getRowCount() {
+      if ( _entityList == null ) {
+         return 0;
+      }
+      return _entityList.size();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public int getColumnCount() {
+      return COLUMN_NAME.values().length;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public String getColumnName( final int columnIndex ) {
+      return COLUMN_NAME.values()[ columnIndex ].toString();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public Class<?> getColumnClass( final int columnIndex ) {
+      return String.class;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public boolean isCellEditable( final int rowIndex, final int columnIndex ) {
+      return false;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public Object getValueAt( final int rowIndex, final int columnIndex ) {
+      if ( _entityList == null || _entityList.isEmpty()
+           || rowIndex >= getRowCount() || columnIndex >= getColumnCount() ) {
+         return "";
+      }
+      final Entity entity = _entityList.get( rowIndex );
+      return getValueAt( entity, COLUMN_NAME.getColumnName( columnIndex ) );
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public void setValueAt( Object aValue, int rowIndex, int columnIndex ) {
+      // do nothing
+   }
+
+}

Added: ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/gui/EventDetailsTableModel.java
URL: http://svn.apache.org/viewvc/ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/gui/EventDetailsTableModel.java?rev=1660963&view=auto
==============================================================================
--- ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/gui/EventDetailsTableModel.java (added)
+++ ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/gui/EventDetailsTableModel.java Thu Feb 19 18:06:13 2015
@@ -0,0 +1,180 @@
+package org.chboston.cnlp.nlp.annotation.gui;
+
+import org.chboston.cnlp.nlp.annotation.attribute.Attribute;
+import org.chboston.cnlp.nlp.annotation.attribute.DefinedAttributeType;
+import org.chboston.cnlp.nlp.annotation.coreference.CoreferenceChain;
+import org.chboston.cnlp.nlp.annotation.entity.Entity;
+
+import javax.swing.table.AbstractTableModel;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Author: SPF
+ * Affiliation: CHIP-NLP
+ * Date: 7/9/13
+ */
+public class EventDetailsTableModel extends AbstractTableModel {
+
+   static private enum COLUMN_NAME {
+      CUI( "Cui" ), TERM( "Term" ), CLASS_TYPE( "Class Type" ), // SUBJECT("Subject"),
+      TEXTSPAN( "TextSpan" ),
+      ASPECT( "Aspect" ), PERMANENCE( "Permanence" ), MODALITY( "Modality" ),
+      // SEVERITY("Severity"),
+      DEGREE( "Degree" ), // CERTAINTY("Certainty"),
+      DOC_TIME_REL( "Occurrence" ); //, SENTENCE("Sentence");
+      final private String __name;
+
+      private COLUMN_NAME( final String name ) {
+         __name = name;
+      }
+
+      public String toString() {
+         return __name;
+      }
+
+      static private COLUMN_NAME getColumnName( final int columnIndex ) {
+         return values()[ columnIndex ];
+      }
+   }
+
+   private List<Entity> _entityList;
+
+   /**
+    * @return entityList
+    */
+   public List<Entity> getEntityList() {
+      return _entityList;
+   }
+
+   /**
+    * @param entity -
+    */
+   public void setEntity( final Entity entity ) {
+      final int oldRowCount = getRowCount();
+      if ( entity != null ) {
+         if ( entity instanceof CoreferenceChain ) {
+            _entityList = new ArrayList<>();
+            for ( Entity reference : (CoreferenceChain)entity ) {
+               boolean store = true;
+               for ( Entity storedEntity : _entityList ) {
+                  if ( storedEntity.areValuesEqual( reference ) ) {
+                     store = false;
+                     break;
+                  }
+               }
+               if ( store ) {
+                  _entityList.add( reference );
+               }
+            }
+         } else {
+            _entityList = Arrays.asList( entity );
+         }
+      } else {
+         _entityList = Collections.emptyList();
+      }
+      fireTableRowsDeleted( 0, oldRowCount );
+      fireTableRowsInserted( 0, getRowCount() );
+   }
+
+   public String getValueAt( final Entity entity, final COLUMN_NAME columnName ) {
+      switch ( columnName ) {
+         case CUI:
+            return getAttributeValue( entity, DefinedAttributeType.CUI );
+         case TERM:
+            return entity.getSpannedText();
+         case CLASS_TYPE:
+            return entity.getClassType().getName();
+//         case SUBJECT: return getAttributeValue( entity, DefinedAttributeType.SUBJECT );
+         case TEXTSPAN:
+            return entity.getTextSpan().getStartIndex() + "-" + entity.getTextSpan().getEndIndex();
+         case ASPECT:
+            return getAttributeValue( entity, DefinedAttributeType.CONTEXT_ASPECT );
+         case PERMANENCE:
+            return getAttributeValue( entity, DefinedAttributeType.PERMANENCE );
+         case MODALITY:
+            return getAttributeValue( entity, DefinedAttributeType.CONTEXT_MODALITY );
+//         case SEVERITY: return getAttributeValue( entity, DefinedAttributeType.SEVERITY );
+         case DEGREE:
+            return getAttributeValue( entity, DefinedAttributeType.DEGREE );
+//         case CERTAINTY: return getAttributeValue( entity, DefinedAttributeType.UNCERTAINTY );
+         case DOC_TIME_REL:
+            return getAttributeValue( entity, DefinedAttributeType.DOC_TIME_REL );
+//         case SENTENCE: return getAttributeValue( entity, DefinedAttributeType.SENTENCE );
+      }
+      return "Unknown";
+   }
+
+   static private String getAttributeValue( final Entity entity, final DefinedAttributeType attributeType ) {
+      final Attribute attribute = entity.getAttribute( attributeType.getName() );
+      return attribute == null ? "-" : attribute.getValue();
+   }
+
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public int getRowCount() {
+      if ( _entityList == null ) {
+         return 0;
+      }
+      return _entityList.size();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public int getColumnCount() {
+      return COLUMN_NAME.values().length;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public String getColumnName( final int columnIndex ) {
+      return COLUMN_NAME.values()[ columnIndex ].toString();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public Class<?> getColumnClass( final int columnIndex ) {
+      return String.class;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public boolean isCellEditable( final int rowIndex, final int columnIndex ) {
+      return false;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public Object getValueAt( final int rowIndex, final int columnIndex ) {
+      if ( _entityList == null || _entityList.isEmpty()
+           || rowIndex >= getRowCount() || columnIndex >= getColumnCount() ) {
+         return "";
+      }
+      final Entity entity = _entityList.get( rowIndex );
+      return getValueAt( entity, COLUMN_NAME.getColumnName( columnIndex ) );
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public void setValueAt( Object aValue, int rowIndex, int columnIndex ) {
+      // do nothing
+   }
+
+}

Added: ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/parser/AbstractAnnotationXmlParser.java
URL: http://svn.apache.org/viewvc/ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/parser/AbstractAnnotationXmlParser.java?rev=1660963&view=auto
==============================================================================
--- ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/parser/AbstractAnnotationXmlParser.java (added)
+++ ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/parser/AbstractAnnotationXmlParser.java Thu Feb 19 18:06:13 2015
@@ -0,0 +1,88 @@
+package org.chboston.cnlp.nlp.annotation.parser;
+
+import org.chboston.cnlp.nlp.annotation.annotation.store.AnnotationStore;
+import org.chboston.cnlp.nlp.annotation.textspan.DefaultDiscontiguousTextSpan;
+import org.chboston.cnlp.nlp.annotation.textspan.TextSpan;
+import org.jdom.Element;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.logging.Logger;
+
+/**
+ * Author: SPF
+ * Affiliation: CHIP-NLP
+ * Date: 3/27/13
+ */
+abstract public class AbstractAnnotationXmlParser extends AbstractAnnotationsParser {
+
+   static private final Logger LOGGER = Logger.getLogger( "AbstractAnnotationXmlParser" );
+
+   protected AnnotationStore _annotationStore;
+
+   /**
+    * @param spanElement xml element with information on an annotation's span
+    * @return a TextSpan
+    */
+   // TODO move this to another project - spiffy xml or something.  Shouldn't need jdom for annotations
+   abstract protected TextSpan createEntityTextSpan( Element spanElement );
+
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public AnnotationStore getAnnotationStore() {
+      return _annotationStore;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   // TODO CollectionMap
+   public List<Collection<TextSpan>> parseCoreferenceTextSpans( final String xmlFilePath ) {
+      return Collections.emptyList();
+   }
+
+
+   //               ---   OTHER METHODS   ---
+
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public void close() {
+      reset();
+   }
+
+   /**
+    * reset the internally stored information
+    */
+   protected void reset() {
+      super.reset();
+      _annotationStore = null;
+   }
+
+
+   /**
+    * @param spanElementList List of xml elements with span information
+    * @return a TextSpan created from the given list
+    */
+   // TODO move this to another project - spiffy xml or something.  Shouldn't need jdom for annotations
+   protected TextSpan createTextSpan( final List<Element> spanElementList ) {
+      final int spanCount = spanElementList.size();
+      if ( spanCount == 1 ) {
+         return createEntityTextSpan( spanElementList.get( 0 ) );
+      }
+      final TextSpan[] spans = new TextSpan[ spanCount ];
+      for ( int i = 0; i < spanCount; i++ ) {
+         spans[ i ] = createEntityTextSpan( spanElementList.get( i ) );
+      }
+      return new DefaultDiscontiguousTextSpan( spans );
+   }
+
+
+}

Added: ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/parser/AbstractAnnotationsParser.java
URL: http://svn.apache.org/viewvc/ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/parser/AbstractAnnotationsParser.java?rev=1660963&view=auto
==============================================================================
--- ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/parser/AbstractAnnotationsParser.java (added)
+++ ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/parser/AbstractAnnotationsParser.java Thu Feb 19 18:06:13 2015
@@ -0,0 +1,132 @@
+package org.chboston.cnlp.nlp.annotation.parser;
+
+import java.io.*;
+import java.util.*;
+import java.util.logging.Logger;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 12/1/2014
+ */
+abstract public class AbstractAnnotationsParser implements AnnotationsParser {
+
+   static private final Logger LOGGER = Logger.getLogger( "AbstractAnnotationsParser" );
+
+   private String _documentText = "";
+   private Collection<String> _entityTypeNames = new HashSet<>();
+   private Collection<String> _relationTypes = new HashSet<>();
+   private Collection<String> _attributeNames = new HashSet<>();
+
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public void setDocumentTextFile( final String filePath ) {
+      if ( filePath != null && !filePath.isEmpty() ) {
+         setDocumentTextFile( new File( filePath ) );
+      } else {
+         _documentText = "";
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public void setDocumentTextFile( final File file ) {
+      if ( file != null ) {
+         try ( BufferedReader reader = new BufferedReader( new FileReader( file ) ) ) {
+            final char[] buffer = new char[ 8192 ];
+            int length = reader.read( buffer );
+            if ( length == 0 ) {
+               LOGGER.warning( "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 = "";
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public void setDocumentText( final String text ) {
+      _documentText = text;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public String getDocumentText() {
+      return _documentText;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public List<String> getClassTypes() {
+      return Collections.unmodifiableList( new ArrayList<>( _entityTypeNames ) );
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public List<String> getRelationTypes() {
+      return Collections.unmodifiableList( new ArrayList<>( _relationTypes ) );
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public List<String> getAttributeNames() {
+      return Collections.unmodifiableList( new ArrayList<>( _attributeNames ) );
+   }
+
+   /**
+    * reset the internally stored information
+    */
+   protected void reset() {
+//      _annotationStore = null;
+      _entityTypeNames.clear();
+      _relationTypes.clear();
+      _attributeNames.clear();
+   }
+
+   protected Collection<String> getMutableClassTypes() {
+      return _entityTypeNames;
+   }
+
+   protected Collection<String> getMutableRelationTypes() {
+      return _relationTypes;
+   }
+
+   protected Collection<String> getMutableAttributeTypes() {
+      return _attributeNames;
+   }
+
+
+}

Added: ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/parser/AnnotationsParser.java
URL: http://svn.apache.org/viewvc/ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/parser/AnnotationsParser.java?rev=1660963&view=auto
==============================================================================
--- ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/parser/AnnotationsParser.java (added)
+++ ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/parser/AnnotationsParser.java Thu Feb 19 18:06:13 2015
@@ -0,0 +1,77 @@
+package org.chboston.cnlp.nlp.annotation.parser;
+
+import org.chboston.cnlp.nlp.annotation.annotation.store.AnnotationStore;
+import org.chboston.cnlp.nlp.annotation.textspan.EntityTextSpan;
+import org.chboston.cnlp.nlp.annotation.textspan.TextSpan;
+
+import java.io.File;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * Author: SPF
+ * Affiliation: CHIP-NLP
+ * Date: 5/8/12
+ */
+public interface AnnotationsParser {
+
+   static final TextSpan BAD_TEXT_SPAN = new EntityTextSpan( -1, -1 );
+   static final String BAD_SPANNED_TEXT = "BAD_SPANNED_TEXT";
+
+
+   // TODO Place this in an AbstractAnnotationsParser
+   public void setDocumentTextFile( String filePath );
+
+   public void setDocumentTextFile( File file );
+
+   public void setDocumentText( String text );
+
+   public String getDocumentText();
+
+   /**
+    * @return collection of annotations gained by the reader
+    */
+   public AnnotationStore getAnnotationStore();
+
+   /**
+    * @return all the discovered classtype type names: location_of, disease_disorder, etc.
+    */
+   public List<String> getClassTypes();
+
+   /**
+    * @return all the discovered relation names: argument, event, etc.
+    */
+   public List<String> getRelationTypes();
+
+   /**
+    * @return all the discovered trait names: cui, relationtype, etc.
+    */
+   public List<String> getAttributeNames();
+
+   /**
+    * Simple preParse to collect class types and attribute types used for annotations
+    *
+    * @param filePath path to file with annotation information
+    * @return true if the annotations were parsed successfully
+    */
+   // TODO move to AnnotationsFileParser, add preParse(), create AnnotationsDbParser .preParseTable(..)
+   public boolean preParseFile( String filePath );
+
+   /**
+    * Fully parse annotations, populating the AnnotationCollection stored in the parser
+    *
+    * @param filePath path to file with annotation information
+    * @return true if the annotations were parsed successfully
+    */
+   // TODO move to AnnotationsFileParser, add parse(), create AnnotationsDbParser .parseTable(..)
+   public boolean parseFile( String filePath );
+
+
+   public List<Collection<TextSpan>> parseCoreferenceTextSpans( String filePath );
+
+   /**
+    * Had to put this in for Protege, since it NEVER cleans up its cache by itself
+    */
+   public void close();
+
+}

Added: ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/relation/DefaultRelation.java
URL: http://svn.apache.org/viewvc/ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/relation/DefaultRelation.java?rev=1660963&view=auto
==============================================================================
--- ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/relation/DefaultRelation.java (added)
+++ ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/relation/DefaultRelation.java Thu Feb 19 18:06:13 2015
@@ -0,0 +1,274 @@
+package org.chboston.cnlp.nlp.annotation.relation;
+
+import net.jcip.annotations.Immutable;
+import org.chboston.cnlp.nlp.annotation.annotation.Annotation;
+import org.chboston.cnlp.nlp.annotation.annotation.DefaultAnnotation;
+import org.chboston.cnlp.nlp.annotation.attribute.Attribute;
+import org.chboston.cnlp.nlp.annotation.attribute.AttributeType;
+import org.chboston.cnlp.nlp.annotation.classtype.ClassType;
+import org.chboston.cnlp.nlp.annotation.entity.Entity;
+import org.chboston.cnlp.nlp.annotation.textspan.RelationTextSpan;
+import org.chboston.cnlp.nlp.annotation.textspan.TextSpan;
+import org.chboston.cnlp.nlp.annotation.textspan.TextSpanComparator;
+
+import java.util.Collection;
+import java.util.List;
+
+
+/**
+ * Author: SPF
+ * Affiliation: CHIP-NLP
+ * Date: 5/8/12
+ */
+@Immutable
+final public class DefaultRelation implements Relation {
+
+
+   static private String createSpannedTextRepresentation( final Annotation entity1, final Annotation entity2 ) {
+      final int spanComparison = TextSpanComparator.getInstance()
+            .compare( entity1.getTextSpan(), entity2.getTextSpan() );
+      if ( spanComparison <= 0 ) {
+         return entity1.getSpannedTextRepresentation() + " " + entity2.getSpannedTextRepresentation();
+      }
+      return entity2.getSpannedTextRepresentation() + " " + entity1.getSpannedTextRepresentation();
+   }
+
+
+   final private Annotation _annotation;
+   private final String _textRepresentation;
+
+   private final Entity _entity1;
+   private final Entity _entity2;
+   private final Direction _direction;
+
+   final private int _hashcode;
+
+
+   public DefaultRelation( final Entity entity1, final Entity entity2, final ClassType classType,
+                           final Attribute... attributes ) {
+      final int spanComparison = TextSpanComparator.getInstance()
+            .compare( entity1.getTextSpan(), entity2.getTextSpan() );
+      _entity1 = entity1;
+      _entity2 = entity2;
+      _direction = spanComparison <= 0 ? Direction.FORWARD : Direction.BACKWARD;
+
+      // Annotation requirements
+      final TextSpan textSpan = new RelationTextSpan( _entity1.getTextSpan(), _entity2.getTextSpan() );
+      // Create the spanned text - true text of the entities with whitespace between
+      final String spannedText = DefaultAnnotation.expandText( _entity1.getTextSpan(), _entity2.getTextSpan(),
+            _entity1.getSpannedText(), _entity2.getSpannedText() );
+
+      _annotation = new DefaultAnnotation( textSpan, spannedText, classType, attributes );
+      _textRepresentation = createSpannedTextRepresentation( entity1, entity2 );
+      int bits = _annotation.hashCode();
+      // Don't need direction as it is handled by entities
+      bits += 3 * _entity1.hashCode();
+      bits += 5 * _entity2.hashCode();
+      _hashcode = bits;
+   }
+
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public Entity getFirstEntity() {
+      return _entity1;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public Entity getSecondEntity() {
+      return _entity2;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public Direction getTextSpanDirection() {
+      return _direction;
+   }
+
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public TextSpan getTextSpan() {
+      return _annotation.getTextSpan();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public String getSpannedText() {
+      return _annotation.getSpannedText();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public String getSpannedTextRepresentation() {
+      return _textRepresentation;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public ClassType getClassType() {
+      return _annotation.getClassType();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public boolean isClassType( final ClassType classType ) {
+      return _annotation.isClassType( classType );
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public List<String> getAttributeNames() {
+      return _annotation.getAttributeNames();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public Attribute getAttribute( final String key ) {
+      return _annotation.getAttribute( key );
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public Attribute getAttribute( final AttributeType attributeType ) {
+      return _annotation.getAttribute( attributeType );
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public Collection<AttributeType> getAttributeTypes() {
+      return _annotation.getAttributeTypes();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public Collection<Attribute> getAttributes() {
+      return _annotation.getAttributes();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public boolean hasAttribute( final String key ) {
+      return _annotation.hasAttribute( key );
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public boolean hasAttribute( final AttributeType attributeType ) {
+      return _annotation.hasAttribute( attributeType );
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public String getAttributeValue( final String key ) {
+      return _annotation.getAttributeValue( key );
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public String getAttributeValue( final AttributeType attributeType ) {
+      return _annotation.getAttributeValue( attributeType );
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public String getAnnotatorName() {
+      return _annotation.getAnnotatorName();
+   }
+
+   /**
+    * Does NOT check entities to make sure that their values are equal
+    * {@inheritDoc}
+    */
+   @Override
+   public boolean areValuesEqual( final Annotation annotation ) {
+      if ( !annotation.getTextSpan().equals( getTextSpan() )
+           || !annotation.getSpannedTextRepresentation().equals( getSpannedTextRepresentation() )
+           || !annotation.getClassType().equals( getClassType() ) ) {
+         return false;
+      }
+      final Collection<String> annotationAttributeNames = annotation.getAttributeNames();
+      final Collection<String> attributeNames = getAttributeNames();
+      if ( annotationAttributeNames.size() != attributeNames.size() ) {
+         return false;
+      }
+      for ( String key : attributeNames ) {
+         if ( !getAttribute( key ).equals( annotation.getAttribute( key ) ) ) {
+            return false;
+         }
+      }
+      return true;
+   }
+
+   /**
+    * @return "Relation: {@link org.chboston.cnlp.nlp.annotation.annotation.DefaultAnnotation#toString()}"
+    */
+   @Override
+   public String toString() {
+      return "Relation: " + _annotation.toString();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public boolean equals( final Object object ) {
+      if ( !(object instanceof Relation) ) {
+         return false;
+      }
+      if ( !areValuesEqual( (Relation)object ) ) {
+         return false;
+      }
+      // Don't need textspan or direction, they are handled by entities
+      final Relation annotation = (Relation)object;
+      return annotation.getFirstEntity().equals( _entity1 ) && annotation.getSecondEntity().equals( _entity2 )
+             && annotation.getClassType().equals( getClassType() );
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public int hashCode() {
+      return _hashcode;
+   }
+
+
+}

Added: ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/relation/Relation.java
URL: http://svn.apache.org/viewvc/ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/relation/Relation.java?rev=1660963&view=auto
==============================================================================
--- ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/relation/Relation.java (added)
+++ ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/relation/Relation.java Thu Feb 19 18:06:13 2015
@@ -0,0 +1,39 @@
+package org.chboston.cnlp.nlp.annotation.relation;
+
+
+import org.chboston.cnlp.nlp.annotation.annotation.Annotation;
+import org.chboston.cnlp.nlp.annotation.entity.Entity;
+
+/**
+ * Author: SPF
+ * Affiliation: CHIP-NLP
+ * Date: 5/8/12
+ */
+public interface Relation extends Annotation {
+
+   static public enum Direction {
+      FORWARD,
+      BACKWARD
+   }
+
+   /**
+    * @return first of two entities in a relation
+    */
+   public Entity getFirstEntity();
+
+   /**
+    * @return second of two entities in a relation
+    */
+   public Entity getSecondEntity();
+
+   /**
+    * Argument Directionality is basically the idea that one entity comes before another in the text for a relationship.
+    * The Boy has a Ball    ( Boy --> Ball = forward)
+    * The Ball is the Boy's ( Ball <-- Boy = backward)
+    * Not really, but that is the general idea.
+    *
+    * @return {@link Direction}
+    */
+   public Direction getTextSpanDirection();
+
+}

Added: ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/textspan/AbstractTextSpan.java
URL: http://svn.apache.org/viewvc/ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/textspan/AbstractTextSpan.java?rev=1660963&view=auto
==============================================================================
--- ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/textspan/AbstractTextSpan.java (added)
+++ ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/textspan/AbstractTextSpan.java Thu Feb 19 18:06:13 2015
@@ -0,0 +1,97 @@
+package org.chboston.cnlp.nlp.annotation.textspan;
+
+import net.jcip.annotations.NotThreadSafe;
+
+/**
+ * Author: SPF
+ * Affiliation: CHIP-NLP
+ * Date: 5/17/12
+ */
+@NotThreadSafe
+abstract public class AbstractTextSpan implements TextSpan {
+
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   final public int getLength() {
+      return getEndIndex() - getStartIndex();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public TextSpan getIntersectionSpan( final TextSpan textSpan ) {
+      if ( textSpan == null || getStartIndex() > textSpan.getEndIndex() || getEndIndex() < textSpan.getStartIndex() ) {
+         // No overlap
+         return NULL_TEXT_SPAN.INSTANCE;
+      }
+      if ( textSpan instanceof DiscontiguousTextSpan ) {
+         // MultipleTextSpan takes care of multiple spans whereas this does not
+         return textSpan.getIntersectionSpan( this );
+      }
+      final int overlapStart = Math.max( getStartIndex(), textSpan.getStartIndex() );
+      final int overlapEnd = Math.min( getEndIndex(), textSpan.getEndIndex() );
+      return new DefaultTextSpan( overlapStart, overlapEnd );
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public TextSpan getPossibleUnionSpan( final TextSpan textSpan ) {
+      if ( textSpan == null || getStartIndex() > textSpan.getEndIndex() || getEndIndex() < textSpan.getStartIndex() ) {
+         // No overlap
+         return NULL_TEXT_SPAN.INSTANCE;
+      }
+      if ( textSpan instanceof DiscontiguousTextSpan ) {
+         // MultipleTextSpan takes care of multiple spans whereas this does not
+         return textSpan.getPossibleUnionSpan( this );
+      }
+      final int unionStart = Math.min( getStartIndex(), textSpan.getStartIndex() );
+      final int unionEnd = Math.max( getEndIndex(), textSpan.getEndIndex() );
+      return new DefaultTextSpan( unionStart, unionEnd );
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   final public boolean intersects( final TextSpan textSpan ) {
+      return getIntersectionSpan( textSpan ).getLength() > 0;
+   }
+
+   /**
+    * @return "Entity Span: [startIndex]-[endIndex]"
+    */
+   @Override
+   public String toString() {
+      return "TextSpan: " + getStartIndex() + "-" + getEndIndex();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public boolean equals( final Object object ) {
+      if ( !(object instanceof TextSpan) ) {
+         return false;
+      }
+      final TextSpan textSpan = (TextSpan)object;
+      return textSpan.getStartIndex() == getStartIndex() && textSpan.getEndIndex() == getEndIndex();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public int hashCode() {
+      long bits = getStartIndex();
+      bits ^= getEndIndex() * 31;
+      return (((int)bits) ^ ((int)(bits >> 32)));
+   }
+
+
+}

Added: ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/textspan/DefaultDiscontiguousTextSpan.java
URL: http://svn.apache.org/viewvc/ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/textspan/DefaultDiscontiguousTextSpan.java?rev=1660963&view=auto
==============================================================================
--- ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/textspan/DefaultDiscontiguousTextSpan.java (added)
+++ ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/textspan/DefaultDiscontiguousTextSpan.java Thu Feb 19 18:06:13 2015
@@ -0,0 +1,274 @@
+package org.chboston.cnlp.nlp.annotation.textspan;
+
+import net.jcip.annotations.NotThreadSafe;
+
+import java.util.*;
+
+/**
+ * Span that represents non-contiguous regions of text (multiple sub-spans)
+ * <p/>
+ * Author: SPF
+ * Affiliation: CHIP-NLP
+ * Date: 5/18/12
+ */
+@NotThreadSafe
+public class DefaultDiscontiguousTextSpan extends AbstractTextSpan implements DiscontiguousTextSpan {
+
+   /**
+    * Make sure that any attempts at creating span 5-10 , 5-15 just become a single span 5-15
+    *
+    * @param textSpans -
+    * @param textSpan  -
+    * @return -
+    */
+   static private Collection<TextSpan> mergeTextSpans( final Iterable<TextSpan> textSpans, final TextSpan textSpan ) {
+      final Collection<TextSpan> spanSet = new HashSet<>();
+      boolean consumed = false;
+      for ( TextSpan textSpan1 : textSpans ) {
+         if ( textSpan.equals( textSpan1 ) ) {
+            continue;
+         }
+         final TextSpan unionSpan = textSpan.getPossibleUnionSpan( textSpan1 );
+         if ( unionSpan != null && unionSpan.getLength() > 0 && unionSpan.equals( textSpan ) ) {
+            spanSet.add( unionSpan );
+            consumed = true;
+         } else {
+            spanSet.add( textSpan1 );
+         }
+      }
+      if ( !consumed ) {
+         spanSet.add( textSpan );
+      }
+      return spanSet;
+   }
+
+
+   private final List<TextSpan> _textSpanList;
+   private final int _startIndex;
+   private final int _endIndex;
+
+
+   /**
+    * @param textSpans sub-textSpans contained within this multiple textspan
+    */
+   public DefaultDiscontiguousTextSpan( final TextSpan... textSpans ) {
+      Collection<TextSpan> spanSet = new HashSet<>( Arrays.asList( textSpans ) );
+      for ( TextSpan textSpan : textSpans ) {
+         spanSet = mergeTextSpans( spanSet, textSpan );
+      }
+      _textSpanList = new ArrayList<>( spanSet );
+      Collections.sort( _textSpanList, TextSpanComparator.getInstance() );
+      int startIndex = Integer.MAX_VALUE;
+      int endIndex = 0;
+      for ( TextSpan textSpan : textSpans ) {
+         startIndex = Math.min( startIndex, textSpan.getStartIndex() );
+         endIndex = Math.max( endIndex, textSpan.getEndIndex() );
+      }
+      _startIndex = startIndex;
+      _endIndex = endIndex;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public int getTextSpanCount() {
+      return _textSpanList.size();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public TextSpan getTextSpan( final int index ) {
+      if ( index < 0 || index >= _textSpanList.size() ) {
+         return NULL_TEXT_SPAN.INSTANCE;
+      }
+      return _textSpanList.get( index );
+   }
+
+
+   /**
+    * @return the index of the first character of the first entity for the relation within the entire text
+    */
+   @Override
+   public int getStartIndex() {
+      return _startIndex;
+   }
+
+   /**
+    * @return the index of the character after the last character of the second entity for the relation
+    * within the entire text
+    */
+   @Override
+   public int getEndIndex() {
+      return _endIndex;
+   }
+
+   /**
+    * Overlap only truly occurs when individual spans overlap each other
+    * {@inheritDoc}
+    */
+   @Override
+   public TextSpan getIntersectionSpan( final TextSpan textSpan ) {
+      if ( textSpan == null || getStartIndex() > textSpan.getEndIndex() || getEndIndex() < textSpan.getStartIndex() ) {
+         // No overlap
+         return NULL_TEXT_SPAN.INSTANCE;
+      }
+      final Collection<TextSpan> otherTextSpans = new ArrayList<>();
+      if ( textSpan instanceof DiscontiguousTextSpan ) {
+         for ( TextSpan otherSpan : (DiscontiguousTextSpan)textSpan ) {
+            otherTextSpans.add( otherSpan );
+         }
+      } else {
+         otherTextSpans.add( textSpan );
+      }
+      final Collection<TextSpan> overlapTextSpans = new HashSet<>();
+      for ( TextSpan myTextSpan : _textSpanList ) {
+         for ( TextSpan otherTextSpan : otherTextSpans ) {
+            final TextSpan overlapTextSpan = myTextSpan.getIntersectionSpan( otherTextSpan );
+            if ( overlapTextSpan != null && overlapTextSpan.getLength() > 0 ) {
+               overlapTextSpans.add( overlapTextSpan );
+            }
+         }
+      }
+      if ( overlapTextSpans.size() == 0 ) {
+         return NULL_TEXT_SPAN.INSTANCE;
+      } else if ( overlapTextSpans.size() == 1 ) {
+         // Kludgy
+//         return overlapTextSpans.toArray( new TextSpan[]{} )[0];
+         return overlapTextSpans.iterator().next();
+      }
+      return new DefaultDiscontiguousTextSpan( overlapTextSpans.toArray( new TextSpan[ overlapTextSpans.size() ] ) );
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public TextSpan getPossibleUnionSpan( final TextSpan textSpan ) {
+      if ( textSpan == null || getStartIndex() > textSpan.getEndIndex() || getEndIndex() < textSpan.getStartIndex() ) {
+         // No overlap
+         return NULL_TEXT_SPAN.INSTANCE;
+      }
+      final Collection<TextSpan> otherTextSpans = new ArrayList<>();
+      if ( textSpan instanceof DiscontiguousTextSpan ) {
+         for ( TextSpan otherSpan : (DiscontiguousTextSpan)textSpan ) {
+            otherTextSpans.add( otherSpan );
+         }
+      } else {
+         otherTextSpans.add( textSpan );
+      }
+      final Collection<TextSpan> unionTextSpans = new HashSet<>();
+      for ( TextSpan myTextSpan : _textSpanList ) {
+         for ( TextSpan otherTextSpan : otherTextSpans ) {
+            final TextSpan unionTextSpan = myTextSpan.getPossibleUnionSpan( otherTextSpan );
+            if ( unionTextSpan != null && unionTextSpan.getLength() > 0 ) {
+               unionTextSpans.add( unionTextSpan );
+            }
+         }
+      }
+      if ( unionTextSpans.size() == 0 ) {
+         return NULL_TEXT_SPAN.INSTANCE;
+      } else if ( unionTextSpans.size() == 1 ) {
+         // Kludgy
+         return unionTextSpans.iterator().next();
+//         return unionTextSpans.toArray( new TextSpan[]{} )[0];
+      }
+      return new DefaultDiscontiguousTextSpan( unionTextSpans.toArray( new TextSpan[ unionTextSpans.size() ] ) );
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public Iterator<TextSpan> iterator() {
+      return new SpanIterator( cloneMultipleSpan() );
+   }
+
+   /**
+    * Creates a clone
+    */
+   private DiscontiguousTextSpan cloneMultipleSpan() {
+      return new DefaultDiscontiguousTextSpan( _textSpanList.toArray( new TextSpan[ getTextSpanCount() ] ) );
+   }
+
+   /**
+    * @return "First Entity Span: [startIndex]-[endIndex] : Second Entity Span: [startIndex]-[endIndex]"
+    */
+   @Override
+   public String toString() {
+      final StringBuilder stringBuilder = new StringBuilder( "Multiple Spans: " );
+      for ( TextSpan textSpan : _textSpanList ) {
+         stringBuilder.append( textSpan.toString() );
+         stringBuilder.append( ", " );
+      }
+      return stringBuilder.toString();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public boolean equals( final Object object ) {
+      if ( !(object instanceof DiscontiguousTextSpan) ) {
+         return false;
+      }
+      final DiscontiguousTextSpan span = (DiscontiguousTextSpan)object;
+      if ( span.getTextSpanCount() != getTextSpanCount() ) {
+         return false;
+      }
+      for ( int i = 0; i < getTextSpanCount(); i++ ) {
+         if ( !span.getTextSpan( i ).equals( _textSpanList.get( i ) ) ) {
+            return false;
+         }
+      }
+      return true;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public int hashCode() {
+      int hash = 1;
+      for ( TextSpan textSpan : _textSpanList ) {
+         hash += 7 * hash + textSpan.hashCode();
+      }
+      return hash;
+   }
+
+   static private class SpanIterator implements Iterator<TextSpan> {
+      final private DiscontiguousTextSpan __multipleSpan;
+      private int __currentIndex = -1;
+
+      private SpanIterator( final DiscontiguousTextSpan multipleSpan ) {
+         __multipleSpan = multipleSpan;
+      }
+
+      /**
+       * {@inheritDoc}
+       */
+      @Override
+      public boolean hasNext() {
+         return __currentIndex < __multipleSpan.getTextSpanCount() - 1;
+      }
+
+      /**
+       * {@inheritDoc}
+       */
+      @Override
+      public TextSpan next() {
+         __currentIndex++;
+         return __multipleSpan.getTextSpan( __currentIndex );
+      }
+
+      /**
+       * Not implemented.  Cannot remove a Span from the MultipleTextSpan
+       */
+      @Override
+      public void remove() {
+      }
+   }
+
+}

Added: ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/textspan/DefaultTextSpan.java
URL: http://svn.apache.org/viewvc/ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/textspan/DefaultTextSpan.java?rev=1660963&view=auto
==============================================================================
--- ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/textspan/DefaultTextSpan.java (added)
+++ ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/textspan/DefaultTextSpan.java Thu Feb 19 18:06:13 2015
@@ -0,0 +1,56 @@
+package org.chboston.cnlp.nlp.annotation.textspan;
+
+import net.jcip.annotations.Immutable;
+
+/**
+ * Immutable contiguous textspan with a start index and end index
+ * Author: SPF
+ * Affiliation: CHIP-NLP
+ * Date: 5/17/12
+ */
+@Immutable
+public class DefaultTextSpan extends AbstractTextSpan {
+
+   private final int _startIndex;
+   private final int _endIndex;
+
+   public DefaultTextSpan( final int startIndex, final int endIndex ) {
+      _startIndex = startIndex;
+      _endIndex = endIndex;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public int getStartIndex() {
+      return _startIndex;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public int getEndIndex() {
+      return _endIndex;
+   }
+
+   //   /**
+   //    * {@inheritDoc}
+   //    */
+   //   @Override
+   //   public boolean equals( final Object object ) {
+   //      // don't need to reference super, but it is a good reminder that super handles specially
+   //      return super.equals( object );
+   //   }
+   //
+   //   /**
+   //    * {@inheritDoc}
+   //    */
+   //   @Override
+   //   public int hashCode() {
+   //      // don't need to reference super, but it is a good reminder that super handles specially
+   //      return super.hashCode();
+   //   }
+
+}

Added: ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/textspan/DiscontiguousTextSpan.java
URL: http://svn.apache.org/viewvc/ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/textspan/DiscontiguousTextSpan.java?rev=1660963&view=auto
==============================================================================
--- ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/textspan/DiscontiguousTextSpan.java (added)
+++ ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/textspan/DiscontiguousTextSpan.java Thu Feb 19 18:06:13 2015
@@ -0,0 +1,20 @@
+package org.chboston.cnlp.nlp.annotation.textspan;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 12/1/2014
+ */
+public interface DiscontiguousTextSpan extends TextSpan, Iterable<TextSpan> {
+   /**
+    * @return total number of sub-spans
+    */
+   int getTextSpanCount();
+
+   /**
+    * @param index index of sub-textspan
+    * @return sub-textspan at that index or a Null Span
+    */
+   TextSpan getTextSpan( int index );
+
+}

Added: ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/textspan/EntityTextSpan.java
URL: http://svn.apache.org/viewvc/ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/textspan/EntityTextSpan.java?rev=1660963&view=auto
==============================================================================
--- ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/textspan/EntityTextSpan.java (added)
+++ ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/textspan/EntityTextSpan.java Thu Feb 19 18:06:13 2015
@@ -0,0 +1,43 @@
+package org.chboston.cnlp.nlp.annotation.textspan;
+
+import net.jcip.annotations.Immutable;
+
+/**
+ * Author: SPF
+ * Affiliation: CHIP-NLP
+ * Date: 5/8/12
+ */
+@Immutable
+final public class EntityTextSpan extends DefaultTextSpan {
+
+   public EntityTextSpan( final int startIndex, final int endIndex ) {
+      super( startIndex, endIndex );
+   }
+
+   /**
+    * @return "Entity Span: [startIndex]-[endIndex]"
+    */
+   @Override
+   public String toString() {
+      return "Entity " + super.toString();
+   }
+
+   //   /**
+   //    * {@inheritDoc}
+   //    */
+   //   @Override
+   //   public boolean equals( final Object object ) {
+   //      // don't need to reference super, but it is a good reminder that super handles specially
+   //      return super.equals( object );
+   //   }
+   //
+   //   /**
+   //    * {@inheritDoc}
+   //    */
+   //   @Override
+   //   public int hashCode() {
+   //      // don't need to reference super, but it is a good reminder that super handles specially
+   //      return super.hashCode();
+   //   }
+
+}

Added: ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/textspan/RelationTextSpan.java
URL: http://svn.apache.org/viewvc/ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/textspan/RelationTextSpan.java?rev=1660963&view=auto
==============================================================================
--- ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/textspan/RelationTextSpan.java (added)
+++ ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/textspan/RelationTextSpan.java Thu Feb 19 18:06:13 2015
@@ -0,0 +1,69 @@
+package org.chboston.cnlp.nlp.annotation.textspan;
+
+import net.jcip.annotations.Immutable;
+
+/**
+ * For Convenience.  Mention "Span" and "Relation" in the same sentence and ten people will jump you with sporks drawn.
+ * <p/>
+ * A Relation is between Entities, and Entities have spans.  So if we need to know that document text associated with a
+ * Relation then we could certainly make calls to getEntity1().getTextSpan() and getEntity2().getTextSpan() and pump the returns
+ * through some kind of normalizer to fit the need at hand...
+ * <p/>
+ * But that would be a case where the developer adheres the code design to the outside world - needlessly.
+ * <p/>
+ * Author: SPF
+ * Affiliation: CHIP-NLP
+ * Date: 5/8/12
+ */
+@Immutable
+final public class RelationTextSpan extends DefaultDiscontiguousTextSpan {
+
+   public RelationTextSpan( final int firstEntityStartIndex, final int firstEntityEndIndex,
+                            final int secondEntityStartIndex, final int secondEntityEndIndex ) {
+      this( new EntityTextSpan( firstEntityStartIndex, firstEntityEndIndex ),
+            new EntityTextSpan( secondEntityStartIndex, secondEntityEndIndex ) );
+   }
+
+   public RelationTextSpan( final TextSpan firstEntityTextSpan, final TextSpan secondEntityTextSpan ) {
+      super( firstEntityTextSpan, secondEntityTextSpan );
+   }
+
+   /**
+    * @return the textspan of the relation that appears first in the full text
+    */
+   public TextSpan getFirstEntitySpan() {
+      return getTextSpan( 0 );
+   }
+
+   /**
+    * @return the textspan of the relation that appears second in the full text
+    */
+   public TextSpan getSecondEntitySpan() {
+      return getTextSpan( 1 );
+   }
+
+   /**
+    * @return "First Entity Span: [startIndex]-[endIndex] : Second Entity Span: [startIndex]-[endIndex]"
+    */
+   @Override
+   public String toString() {
+      return "First " + getFirstEntitySpan().toString() + " , Second " + getSecondEntitySpan().toString();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public boolean equals( final Object object ) {
+      return object instanceof RelationTextSpan && super.equals( object );
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public int hashCode() {
+      return 23 * super.hashCode();
+   }
+
+}

Added: ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/textspan/TextSpan.java
URL: http://svn.apache.org/viewvc/ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/textspan/TextSpan.java?rev=1660963&view=auto
==============================================================================
--- ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/textspan/TextSpan.java (added)
+++ ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/textspan/TextSpan.java Thu Feb 19 18:06:13 2015
@@ -0,0 +1,75 @@
+package org.chboston.cnlp.nlp.annotation.textspan;
+
+/**
+ * Author: SPF
+ * Affiliation: CHIP-NLP
+ * Date: 5/8/12
+ */
+public interface TextSpan {
+
+   public enum NULL_TEXT_SPAN implements TextSpan {
+      INSTANCE;
+
+      static public TextSpan getInstance() {
+         return INSTANCE;
+      }
+
+      public int getStartIndex() {
+         return 0;
+      }
+
+      public int getEndIndex() {
+         return 0;
+      }
+
+      public int getLength() {
+         return 0;
+      }
+
+      public TextSpan getIntersectionSpan( final TextSpan textSpan ) {
+         return this;
+      }
+
+      public TextSpan getPossibleUnionSpan( final TextSpan textSpan ) {
+         return this;
+      }
+
+      public boolean intersects( final TextSpan textSpan ) {
+         return false;
+      }
+   }
+
+   /**
+    * @return the index of the first character of a textspan within the entire text
+    */
+   public int getStartIndex();
+
+   /**
+    * @return the index of the character after the last character of a textspan within the entire text
+    */
+   public int getEndIndex();
+
+   /**
+    * @return number of characters in the textspan : [end index] - [start index]
+    */
+   public int getLength();
+
+   /**
+    * @param textSpan -
+    * @return a textSpan for the intersection of two spans IFF they intersect, else NULL_TEXT_SPAN
+    */
+   public TextSpan getIntersectionSpan( TextSpan textSpan );
+
+   /**
+    * @param textSpan -
+    * @return a textSpan for the union of two spans IFF they intersect, else NULL_TEXT_SPAN
+    */
+   public TextSpan getPossibleUnionSpan( final TextSpan textSpan );
+
+   /**
+    * @param textSpan some text span
+    * @return true if this TextSpan intersects the given TextSpan
+    */
+   public boolean intersects( TextSpan textSpan );
+
+}

Added: ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/textspan/TextSpanComparator.java
URL: http://svn.apache.org/viewvc/ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/textspan/TextSpanComparator.java?rev=1660963&view=auto
==============================================================================
--- ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/textspan/TextSpanComparator.java (added)
+++ ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/annotation/textspan/TextSpanComparator.java Thu Feb 19 18:06:13 2015
@@ -0,0 +1,31 @@
+package org.chboston.cnlp.nlp.annotation.textspan;
+
+import java.util.Comparator;
+
+/**
+ * Author: SPF
+ * Affiliation: CHIP-NLP
+ * Date: 5/8/12
+ */
+public enum TextSpanComparator implements Comparator<TextSpan> {
+   INSTANCE;
+
+   static public TextSpanComparator getInstance() {
+      return INSTANCE;
+   }
+
+   /**
+    * {@inheritDoc}
+    *
+    * @param textSpan1 -
+    * @param textSpan2 -
+    * @return the difference between startIndices, or the difference between the ends if the starts are equal
+    */
+   public int compare( final TextSpan textSpan1, final TextSpan textSpan2 ) {
+      if ( textSpan1.getStartIndex() != textSpan2.getStartIndex() ) {
+         return textSpan1.getStartIndex() - textSpan2.getStartIndex();
+      }
+      return textSpan1.getEndIndex() - textSpan2.getEndIndex();
+   }
+
+}

Added: ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/corpus/AnnotatedNote.java
URL: http://svn.apache.org/viewvc/ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/corpus/AnnotatedNote.java?rev=1660963&view=auto
==============================================================================
--- ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/corpus/AnnotatedNote.java (added)
+++ ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/corpus/AnnotatedNote.java Thu Feb 19 18:06:13 2015
@@ -0,0 +1,40 @@
+package org.chboston.cnlp.nlp.corpus;
+
+import org.chboston.cnlp.nlp.annotation.annotation.store.AnnotationStore;
+
+/**
+ * Author: SPF
+ * Affiliation: CHIP-NLP
+ * Date: 3/25/14
+ */
+public class AnnotatedNote extends DefaultNote {
+
+   final private AnnotationStore _annotationStore;
+
+   public AnnotatedNote( final String filePath, final AnnotationStore annotationStore ) {
+      this( null, filePath, annotationStore );
+   }
+
+   public AnnotatedNote( final String name, final String filePath, final AnnotationStore annotationStore ) {
+      this( name, -1, filePath, annotationStore );
+   }
+
+   public AnnotatedNote( final String name, final long timestampMillis, final String filePath,
+                         final AnnotationStore annotationStore ) {
+      super( name, timestampMillis, filePath );
+      _annotationStore = annotationStore;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public String getText() {
+      return _annotationStore.getDocumentText();
+   }
+
+   public AnnotationStore getAnnotationStore() {
+      return _annotationStore;
+   }
+
+}

Added: ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/corpus/DefaultNote.java
URL: http://svn.apache.org/viewvc/ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/corpus/DefaultNote.java?rev=1660963&view=auto
==============================================================================
--- ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/corpus/DefaultNote.java (added)
+++ ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/corpus/DefaultNote.java Thu Feb 19 18:06:13 2015
@@ -0,0 +1,97 @@
+package org.chboston.cnlp.nlp.corpus;
+
+import java.io.File;
+
+/**
+ * Author: SPF
+ * Affiliation: CHIP-NLP
+ * Date: 3/25/14
+ */
+public class DefaultNote implements Note {
+
+   private String _name;
+   private String _path;
+   private long _timestampMillis;
+   private String _text;
+
+   public DefaultNote( final String filePath ) {
+      this( null, filePath );
+   }
+
+   public DefaultNote( final String name, final String filePath ) {
+      this( name, -1, filePath );
+   }
+
+   public DefaultNote( final String name, final long timestampMillis, final String filePath ) {
+      if ( filePath != null ) {
+         final File file = new File( filePath );
+         if ( name == null ) {
+            _name = file.getName();
+         }
+         if ( timestampMillis < 0 ) {
+            _timestampMillis = file.lastModified();
+         }
+      }
+      if ( name != null ) {
+         _name = name;
+      }
+      if ( timestampMillis > 0 ) {
+         _timestampMillis = timestampMillis;
+      }
+      _path = filePath;
+   }
+
+   @Override
+   public String getTitle() {
+      String title = getPath();
+      if ( title.endsWith( ".old" ) ) {
+         title = title.substring( 0, title.length() - 4 );
+      }
+      if ( title.endsWith( ".xmi" ) ) {
+         title = title.substring( 0, title.length() - 4 );
+      }
+      if ( title.endsWith( ".txt" ) ) {
+         title = title.substring( 0, title.length() - 4 );
+      }
+      if ( title.endsWith( ".xml" ) ) {
+         title = title.substring( 0, title.length() - 4 );
+      }
+      if ( title.endsWith( ".knowtator" ) ) {
+         title = title.substring( 0, title.length() - 10 );
+      }
+      return title;
+   }
+
+   /**
+    * @return name
+    */
+   @Override
+   public String getName() {
+      return _name;
+   }
+
+   /**
+    * @return path
+    */
+   @Override
+   public String getPath() {
+      return _path;
+   }
+
+   /**
+    * @return timestamp for note
+    */
+   @Override
+   public long getTimestampMillis() {
+      return _timestampMillis;
+   }
+
+   /**
+    * @return text in note
+    */
+   @Override
+   public String getText() {
+      return _text;
+   }
+
+}

Added: ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/corpus/Note.java
URL: http://svn.apache.org/viewvc/ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/corpus/Note.java?rev=1660963&view=auto
==============================================================================
--- ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/corpus/Note.java (added)
+++ ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/corpus/Note.java Thu Feb 19 18:06:13 2015
@@ -0,0 +1,19 @@
+package org.chboston.cnlp.nlp.corpus;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 10/13/2014
+ */
+public interface Note {
+
+   String getTitle();
+
+   String getName();
+
+   String getPath();
+
+   long getTimestampMillis();
+
+   String getText();
+}

Added: ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/util/ArrayListMap.java
URL: http://svn.apache.org/viewvc/ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/util/ArrayListMap.java?rev=1660963&view=auto
==============================================================================
--- ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/util/ArrayListMap.java (added)
+++ ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/util/ArrayListMap.java Thu Feb 19 18:06:13 2015
@@ -0,0 +1,71 @@
+package org.chboston.cnlp.nlp.util;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.logging.Logger;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 11/5/2014
+ */
+// TODO copy from ctakes source
+public class ArrayListMap<K, V> extends HashMap<K, List<V>> implements CollectionMap<K, V> {
+
+   static private final Logger LOGGER = Logger.getLogger( "ArrayListMap" );
+
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public void place( final K key, final V value ) {
+      List<V> list = get( key );
+      if ( list == null ) {
+         list = new ArrayList<>();
+         put( key, list );
+      }
+      list.add( value );
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public Collection<V> obtain( final K key ) {
+      List<V> list = get( key );
+      if ( list == null ) {
+         list = new ArrayList<>();
+         put( key, list );
+      }
+      return list;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public void addAll( final K key, final Collection<V> collection ) {
+      List<V> list = get( key );
+      if ( list == null ) {
+         list = new ArrayList<>();
+         put( key, list );
+      }
+      list.addAll( collection );
+   }
+
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public void clear( final K key ) {
+      final List<V> list = get( key );
+      if ( list != null ) {
+         list.clear();
+      }
+   }
+
+}

Added: ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/util/CollectionMap.java
URL: http://svn.apache.org/viewvc/ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/util/CollectionMap.java?rev=1660963&view=auto
==============================================================================
--- ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/util/CollectionMap.java (added)
+++ ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/util/CollectionMap.java Thu Feb 19 18:06:13 2015
@@ -0,0 +1,43 @@
+package org.chboston.cnlp.nlp.util;
+
+import java.util.Collection;
+
+/**
+ * Author: SPF
+ * Affiliation: CHIP-NLP
+ * Date: 6/24/14
+ */
+public interface CollectionMap<K, V> {
+
+   /**
+    * places value into a collection mapped with key
+    *
+    * @param key   key for internal collection
+    * @param value value to place in internal collection
+    */
+   public void place( K key, V value );
+
+   /**
+    * obtains a collection mapped with key
+    *
+    * @param key key for internal collection
+    * @return collection mapped with key
+    */
+   public Collection<V> obtain( K key );
+
+   /**
+    * adds everything from the given collection to the internal collection mapped with key
+    *
+    * @param key        key for internal collection
+    * @param collection collection of values to place in internal collection
+    */
+   public void addAll( K key, Collection<V> collection );
+
+   /**
+    * clear the collection mapped with key
+    *
+    * @param key key for internal collection
+    */
+   public void clear( K key );
+
+}

Added: ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/util/HashSetMap.java
URL: http://svn.apache.org/viewvc/ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/util/HashSetMap.java?rev=1660963&view=auto
==============================================================================
--- ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/util/HashSetMap.java (added)
+++ ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/util/HashSetMap.java Thu Feb 19 18:06:13 2015
@@ -0,0 +1,67 @@
+package org.chboston.cnlp.nlp.util;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Author: SPF
+ * Affiliation: CHIP-NLP
+ * Date: 6/24/14
+ */
+// TODO replace with cTakes CollectionMaps
+final public class HashSetMap<K, V> extends HashMap<K, Set<V>> implements SetMap<K, V> {
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public void place( final K key, final V value ) {
+      Set<V> set = get( key );
+      if ( set == null ) {
+         set = new HashSet<>();
+         put( key, set );
+      }
+      set.add( value );
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public Collection<V> obtain( final K key ) {
+      Set<V> set = get( key );
+      if ( set == null ) {
+         set = new HashSet<>();
+         put( key, set );
+      }
+      return set;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public void addAll( final K key, final Collection<V> collection ) {
+      Set<V> set = get( key );
+      if ( set == null ) {
+         set = new HashSet<>();
+         put( key, set );
+      }
+      set.addAll( collection );
+   }
+
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public void clear( final K key ) {
+      final Set<V> set = get( key );
+      if ( set != null ) {
+         set.clear();
+      }
+   }
+
+}

Added: ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/util/SetMap.java
URL: http://svn.apache.org/viewvc/ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/util/SetMap.java?rev=1660963&view=auto
==============================================================================
--- ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/util/SetMap.java (added)
+++ ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/util/SetMap.java Thu Feb 19 18:06:13 2015
@@ -0,0 +1,12 @@
+package org.chboston.cnlp.nlp.util;
+
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 12/1/2014
+ */
+public interface SetMap<K, V> extends Map<K, Set<V>>, CollectionMap<K, V> {
+}

Added: ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/util/collection/ArrayListMap.java
URL: http://svn.apache.org/viewvc/ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/util/collection/ArrayListMap.java?rev=1660963&view=auto
==============================================================================
--- ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/util/collection/ArrayListMap.java (added)
+++ ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/util/collection/ArrayListMap.java Thu Feb 19 18:06:13 2015
@@ -0,0 +1,225 @@
+package org.chboston.cnlp.nlp.util.collection;
+
+import java.util.*;
+
+/**
+ * Author: SPF
+ * Affiliation: CHIP-NLP
+ * Date: 7/23/14
+ */
+final public class ArrayListMap<K, V> implements CollectionMap<K, V, List<V>> {
+
+   private final CollectionMap<K, V, List<V>> _delegate;
+
+
+   public ArrayListMap() {
+      final Map<K, List<V>> hashMap = new HashMap<>();
+      final CollectionCreator<V, List<V>> creator = CollectionCreatorFactory.createListCreator();
+      _delegate = new DefaultCollectionMap<>( hashMap, creator );
+   }
+
+   /**
+    * @param size initial size of the HashSetMap
+    */
+   public ArrayListMap( final int size ) {
+      final Map<K, List<V>> hashMap = new HashMap<>( size );
+      final CollectionCreator<V, List<V>> creator = CollectionCreatorFactory.createListCreator();
+      _delegate = new DefaultCollectionMap<>( hashMap, creator );
+   }
+
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public Iterator<Map.Entry<K, List<V>>> iterator() {
+      return _delegate.iterator();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public Collection<List<V>> getAllCollections() {
+      return new HashSet<>( _delegate.values() );
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public List<V> getCollection( final K key ) {
+      return _delegate.getCollection( key );
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public List<V> obtainCollection( final K key ) {
+      return _delegate.obtainCollection( key );
+   }
+
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public boolean containsValue( final K key, final V value ) {
+      return _delegate.containsValue( key, value );
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public boolean placeValue( final K key, final V value ) {
+      return _delegate.placeValue( key, value );
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public boolean placeMap( final Map<K, V> map ) {
+      return _delegate.placeMap( map );
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public void removeValue( final K key, final V value ) {
+      _delegate.removeValue( key, value );
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public <C extends Collection<V>> int addAllValues( final K key, final C collection ) {
+      return _delegate.addAllValues( key, collection );
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public void clearCollection( final K key ) {
+      _delegate.clearCollection( key );
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public int size() {
+      return _delegate.size();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public boolean isEmpty() {
+      return _delegate.isEmpty();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public boolean containsKey( final Object key ) {
+      return _delegate.containsKey( key );
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public boolean containsValue( final Object value ) {
+      return _delegate.containsValue( value );
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public List<V> get( final Object key ) {
+      return _delegate.get( key );
+   }
+
+   // Modification Operations
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public List<V> put( final K key, final List<V> value ) {
+      return _delegate.put( key, value );
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public List<V> remove( final Object key ) {
+      return _delegate.remove( key );
+   }
+
+
+   // Bulk Operations
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public void putAll( final Map<? extends K, ? extends List<V>> map ) {
+      _delegate.putAll( map );
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public void clear() {
+      _delegate.clear();
+   }
+
+
+   // Views
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public Set<K> keySet() {
+      return _delegate.keySet();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public Collection<List<V>> values() {
+      return _delegate.values();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public Set<Map.Entry<K, List<V>>> entrySet() {
+      return _delegate.entrySet();
+   }
+
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public Map<K, List<V>> toSimpleMap() {
+      return _delegate;
+   }
+
+}

Added: ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/util/collection/CollectionCreator.java
URL: http://svn.apache.org/viewvc/ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/util/collection/CollectionCreator.java?rev=1660963&view=auto
==============================================================================
--- ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/util/collection/CollectionCreator.java (added)
+++ ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/util/collection/CollectionCreator.java Thu Feb 19 18:06:13 2015
@@ -0,0 +1,17 @@
+package org.chboston.cnlp.nlp.util.collection;
+
+import java.util.Collection;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 9/23/2014
+ */
+public interface CollectionCreator<V, T extends Collection<V>> {
+
+   public T createCollection();
+
+   public T createCollection( int size );
+
+
+}

Added: ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/util/collection/CollectionCreatorFactory.java
URL: http://svn.apache.org/viewvc/ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/util/collection/CollectionCreatorFactory.java?rev=1660963&view=auto
==============================================================================
--- ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/util/collection/CollectionCreatorFactory.java (added)
+++ ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/util/collection/CollectionCreatorFactory.java Thu Feb 19 18:06:13 2015
@@ -0,0 +1,46 @@
+package org.chboston.cnlp.nlp.util.collection;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 9/23/2014
+ */
+final public class CollectionCreatorFactory {
+
+   private CollectionCreatorFactory() {
+   }
+
+   static public <V> CollectionCreator<V, Set<V>> createSetCreator() {
+      return new CollectionCreator<V, Set<V>>() {
+         @Override
+         public Set<V> createCollection() {
+            return new HashSet<>();
+         }
+
+         @Override
+         public Set<V> createCollection( final int size ) {
+            return new HashSet<>( size );
+         }
+      };
+   }
+
+   static public <V> CollectionCreator<V, List<V>> createListCreator() {
+      return new CollectionCreator<V, List<V>>() {
+         @Override
+         public List<V> createCollection() {
+            return new ArrayList<>();
+         }
+
+         @Override
+         public List<V> createCollection( final int size ) {
+            return new ArrayList<>( size );
+         }
+      };
+   }
+
+}

Added: ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/util/collection/CollectionMap.java
URL: http://svn.apache.org/viewvc/ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/util/collection/CollectionMap.java?rev=1660963&view=auto
==============================================================================
--- ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/util/collection/CollectionMap.java (added)
+++ ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/util/collection/CollectionMap.java Thu Feb 19 18:06:13 2015
@@ -0,0 +1,93 @@
+package org.chboston.cnlp.nlp.util.collection;
+
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * Author: SPF
+ * Affiliation: CHIP-NLP
+ * Date: 6/24/14
+ */
+public interface CollectionMap<K, V, T extends Collection<V>> extends Map<K, T>, Iterable<Map.Entry<K, T>> {
+
+   /**
+    * @return all of the collections for all keys
+    */
+   public Collection<T> getAllCollections();
+
+
+   /**
+    * gets a collection mapped with key.  If one does not exist then an empty collection is returned
+    *
+    * @param key key for internal collection
+    * @return collection mapped with key or an empty collection if there is none
+    */
+   public T getCollection( K key );
+
+   /**
+    * obtains a collection mapped with key.  If one does not exist then one is added to this CollectionMap
+    *
+    * @param key key for internal collection
+    * @return (possibly new) collection mapped with key
+    */
+   public T obtainCollection( K key );
+
+   /**
+    * check the collection map for a key and value combination
+    *
+    * @param key   key for internal collection
+    * @param value value to check in internal collection
+    * @return <tt>true</tt> if this CollectionMap contain the value for the given key
+    */
+   public boolean containsValue( K key, V value );
+
+   /**
+    * places value into a collection mapped with key
+    *
+    * @param key   key for internal collection
+    * @param value value to placeValue in internal collection
+    * @return <tt>true</tt> if this set did not already contain the value
+    */
+   public boolean placeValue( K key, V value );
+
+   /**
+    * places each value of a map into a collection mapped with the appropriate key
+    *
+    * @param map map to store
+    * @return <tt>true</tt> if this set did not already contain the value
+    */
+   public boolean placeMap( Map<K, V> map );
+
+   /**
+    * removes value from a collection mapped with key
+    *
+    * @param key   key for internal collection
+    * @param value value to remove from internal collection
+    */
+   public void removeValue( K key, V value );
+
+   /**
+    * adds everything from the given collection to the internal collection mapped with key
+    *
+    * @param key        key for internal collection
+    * @param collection collection of values to place in internal collection
+    * @return the number of new items added
+    */
+   public <C extends Collection<V>> int addAllValues( K key, C collection );
+
+   /**
+    * clearCollection the collection mapped with key
+    *
+    * @param key key for internal collection
+    */
+   public void clearCollection( K key );
+
+   /**
+    * Copy of this object as a simple (java.util.Collection) map of Collection
+    *
+    * @return map of java.util.Collection
+    */
+   public Map<K, T> toSimpleMap();
+
+
+}



Mime
View raw message