You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ctakes.apache.org by se...@apache.org on 2015/02/19 19:06:17 UTC
svn commit: r1660963 [8/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...
Added: ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/util/collection/DefaultCollectionMap.java
URL: http://svn.apache.org/viewvc/ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/util/collection/DefaultCollectionMap.java?rev=1660963&view=auto
==============================================================================
--- ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/util/collection/DefaultCollectionMap.java (added)
+++ ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/util/collection/DefaultCollectionMap.java Thu Feb 19 18:06:13 2015
@@ -0,0 +1,279 @@
+package org.chboston.cnlp.nlp.util.collection;
+
+import java.util.*;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 9/23/2014
+ */
+final public class DefaultCollectionMap<K, V, T extends Collection<V>> implements CollectionMap<K, V, T> {
+
+ private final Map<K, T> _delegate;
+ private final CollectionCreator<V, T> _collectionCreator;
+ private final T EMPTY_COLLECTION;
+
+ public DefaultCollectionMap( final Map<K, T> delegate, final CollectionCreator<V, T> collectionCreator ) {
+ _delegate = delegate;
+ _collectionCreator = collectionCreator;
+ EMPTY_COLLECTION = collectionCreator.createCollection();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Iterator<Entry<K, T>> iterator() {
+ final Iterator<Map.Entry<K, T>> setIterator = _delegate.entrySet().iterator();
+ return new Iterator<Map.Entry<K, T>>() {
+ public boolean hasNext() {
+ return setIterator.hasNext();
+ }
+
+ public Map.Entry<K, T> next() {
+ final Map.Entry<K, T> next = setIterator.next();
+ return new Map.Entry<K, T>() {
+ public K getKey() {
+ return next.getKey();
+ }
+
+ public T getValue() {
+ return next.getValue();
+ }
+
+ public T setValue( final T value ) {
+ return null;
+ }
+ };
+ }
+
+ public void remove() {
+ }
+ };
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Collection<T> getAllCollections() {
+ return new HashSet<>( _delegate.values() );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public T getCollection( final K key ) {
+ final T collection = _delegate.get( key );
+ if ( collection != null ) {
+ return collection;
+ }
+ return EMPTY_COLLECTION;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public T obtainCollection( final K key ) {
+ T collection = _delegate.get( key );
+ if ( collection == null ) {
+ collection = _collectionCreator.createCollection();
+ _delegate.put( key, collection );
+ }
+ return collection;
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean containsValue( final K key, final V value ) {
+ final T collection = _delegate.get( key );
+ return collection != null && collection.contains( value );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean placeValue( final K key, final V value ) {
+ T collection = _delegate.get( key );
+ if ( collection == null ) {
+ collection = _collectionCreator.createCollection();
+ _delegate.put( key, collection );
+ }
+ return collection.add( value );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean placeMap( final Map<K, V> map ) {
+ boolean placedAny = false;
+ for ( Map.Entry<K, V> entry : map.entrySet() ) {
+ final boolean placed = placeValue( entry.getKey(), entry.getValue() );
+ placedAny = placedAny || placed;
+ }
+ return placedAny;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void removeValue( final K key, final V value ) {
+ final T collection = _delegate.get( key );
+ if ( collection == null ) {
+ return;
+ }
+ collection.remove( value );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public <C extends Collection<V>> int addAllValues( final K key, final C values ) {
+ if ( values == null || values.isEmpty() ) {
+ return 0;
+ }
+ T collection = _delegate.get( key );
+ if ( collection == null ) {
+ collection = _collectionCreator.createCollection();
+ _delegate.put( key, collection );
+ }
+ final int oldSize = collection.size();
+ collection.addAll( values );
+ return collection.size() - oldSize;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void clearCollection( final K key ) {
+ final T collection = _delegate.get( key );
+ if ( collection != null ) {
+ collection.clear();
+ }
+ }
+
+ /**
+ * {@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 T get( final Object key ) {
+ return _delegate.get( key );
+ }
+
+ // Modification Operations
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public T put( final K key, final T value ) {
+ return _delegate.put( key, value );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public T remove( final Object key ) {
+ return _delegate.remove( key );
+ }
+
+
+ // Bulk Operations
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void putAll( final Map<? extends K, ? extends T> 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<T> values() {
+ return _delegate.values();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Set<Map.Entry<K, T>> entrySet() {
+ return _delegate.entrySet();
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Map<K, T> toSimpleMap() {
+ return _delegate;
+ }
+
+
+}
Added: ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/util/collection/EnumSetMap.java
URL: http://svn.apache.org/viewvc/ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/util/collection/EnumSetMap.java?rev=1660963&view=auto
==============================================================================
--- ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/util/collection/EnumSetMap.java (added)
+++ ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/util/collection/EnumSetMap.java Thu Feb 19 18:06:13 2015
@@ -0,0 +1,215 @@
+package org.chboston.cnlp.nlp.util.collection;
+
+import java.util.*;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 9/23/2014
+ */
+final public class EnumSetMap<K extends Enum<K>, V> implements CollectionMap<K, V, Set<V>> {
+
+ private final CollectionMap<K, V, Set<V>> _delegate;
+
+
+ public EnumSetMap( final Class<K> enumType ) {
+ final EnumMap<K, Set<V>> enumMap = new EnumMap<>( enumType );
+ final CollectionCreator<V, Set<V>> creator = CollectionCreatorFactory.createSetCreator();
+ _delegate = new DefaultCollectionMap<>( enumMap, creator );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Iterator<Map.Entry<K, Set<V>>> iterator() {
+ return _delegate.iterator();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Collection<Set<V>> getAllCollections() {
+ return new HashSet<>( _delegate.values() );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Set<V> getCollection( final K key ) {
+ return _delegate.getCollection( key );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Set<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 Set<V> get( final Object key ) {
+ return _delegate.get( key );
+ }
+
+ // Modification Operations
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Set<V> put( final K key, final Set<V> value ) {
+ return _delegate.put( key, value );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Set<V> remove( final Object key ) {
+ return _delegate.remove( key );
+ }
+
+
+ // Bulk Operations
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void putAll( final Map<? extends K, ? extends Set<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<Set<V>> values() {
+ return _delegate.values();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Set<Map.Entry<K, Set<V>>> entrySet() {
+ return _delegate.entrySet();
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Map<K, Set<V>> toSimpleMap() {
+ return _delegate;
+ }
+
+}
Added: ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/util/collection/HashSetMap.java
URL: http://svn.apache.org/viewvc/ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/util/collection/HashSetMap.java?rev=1660963&view=auto
==============================================================================
--- ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/util/collection/HashSetMap.java (added)
+++ ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/util/collection/HashSetMap.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: 6/24/14
+ */
+final public class HashSetMap<K, V> implements CollectionMap<K, V, Set<V>> {
+
+ private final CollectionMap<K, V, Set<V>> _delegate;
+
+
+ public HashSetMap() {
+ final Map<K, Set<V>> hashMap = new HashMap<>();
+ final CollectionCreator<V, Set<V>> creator = CollectionCreatorFactory.createSetCreator();
+ _delegate = new DefaultCollectionMap<>( hashMap, creator );
+ }
+
+ /**
+ * @param size initial size of the HashSetMap
+ */
+ public HashSetMap( final int size ) {
+ final Map<K, Set<V>> hashMap = new HashMap<>( size );
+ final CollectionCreator<V, Set<V>> creator = CollectionCreatorFactory.createSetCreator();
+ _delegate = new DefaultCollectionMap<>( hashMap, creator );
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Iterator<Map.Entry<K, Set<V>>> iterator() {
+ return _delegate.iterator();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Collection<Set<V>> getAllCollections() {
+ return new HashSet<>( _delegate.values() );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Set<V> getCollection( final K key ) {
+ return _delegate.getCollection( key );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Set<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 Set<V> get( final Object key ) {
+ return _delegate.get( key );
+ }
+
+ // Modification Operations
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Set<V> put( final K key, final Set<V> value ) {
+ return _delegate.put( key, value );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Set<V> remove( final Object key ) {
+ return _delegate.remove( key );
+ }
+
+
+ // Bulk Operations
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void putAll( final Map<? extends K, ? extends Set<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<Set<V>> values() {
+ return _delegate.values();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Set<Map.Entry<K, Set<V>>> entrySet() {
+ return _delegate.entrySet();
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Map<K, Set<V>> toSimpleMap() {
+ return _delegate;
+ }
+
+}
Added: ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/util/collection/ImmutableCollectionMap.java
URL: http://svn.apache.org/viewvc/ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/util/collection/ImmutableCollectionMap.java?rev=1660963&view=auto
==============================================================================
--- ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/util/collection/ImmutableCollectionMap.java (added)
+++ ctakes/sandbox/timelanes/org/chboston/cnlp/nlp/util/collection/ImmutableCollectionMap.java Thu Feb 19 18:06:13 2015
@@ -0,0 +1,217 @@
+package org.chboston.cnlp.nlp.util.collection;
+
+import net.jcip.annotations.Immutable;
+
+import java.util.*;
+
+/**
+ * Author: SPF
+ * Affiliation: CHIP-NLP
+ * Date: 9/5/2014
+ */
+@Immutable
+final public class ImmutableCollectionMap<K, V, T extends Collection<V>> implements CollectionMap<K, V, T> {
+
+ private final CollectionMap<K, V, T> _protectedMap;
+
+ public ImmutableCollectionMap( final CollectionMap<K, V, T> collectionMap ) {
+ _protectedMap = collectionMap;
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Iterator<Map.Entry<K, T>> iterator() {
+ return _protectedMap.iterator();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Collection<T> getAllCollections() {
+ return Collections.unmodifiableCollection( _protectedMap.values() );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public T getCollection( final K key ) {
+ // unfortunately, we cannot use an unmodifiable from Collections
+ return _protectedMap.getCollection( key );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public T obtainCollection( final K key ) {
+ return getCollection( key );
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean containsValue( final K key, final V value ) {
+ return _protectedMap.containsValue( key, value );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean placeValue( final K key, final V value ) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean placeMap( final Map<K, V> map ) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void removeValue( final K key, final V value ) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public <C extends Collection<V>> int addAllValues( final K key, final C collection ) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void clearCollection( final K key ) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int size() {
+ return _protectedMap.size();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isEmpty() {
+ return _protectedMap.isEmpty();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean containsKey( final Object key ) {
+ return _protectedMap.containsKey( key );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean containsValue( final Object value ) {
+ return _protectedMap.containsValue( value );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public T get( final Object key ) {
+ return _protectedMap.get( key );
+ }
+
+ // Modification Operations
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public T put( final K key, final T value ) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public T remove( final Object key ) {
+ throw new UnsupportedOperationException();
+ }
+
+
+ // Bulk Operations
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void putAll( final Map<? extends K, ? extends T> map ) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void clear() {
+ throw new UnsupportedOperationException();
+ }
+
+
+ // Views
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Set<K> keySet() {
+ return _protectedMap.keySet();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Collection<T> values() {
+ return _protectedMap.values();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Set<Map.Entry<K, T>> entrySet() {
+ return _protectedMap.entrySet();
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Map<K, T> toSimpleMap() {
+ return Collections.unmodifiableMap( _protectedMap );
+ }
+
+}
Added: ctakes/sandbox/timelanes/org/chboston/cnlp/timeline/chronic/parser/AtParser.java
URL: http://svn.apache.org/viewvc/ctakes/sandbox/timelanes/org/chboston/cnlp/timeline/chronic/parser/AtParser.java?rev=1660963&view=auto
==============================================================================
--- ctakes/sandbox/timelanes/org/chboston/cnlp/timeline/chronic/parser/AtParser.java (added)
+++ ctakes/sandbox/timelanes/org/chboston/cnlp/timeline/chronic/parser/AtParser.java Thu Feb 19 18:06:13 2015
@@ -0,0 +1,148 @@
+package org.chboston.cnlp.timeline.chronic.parser;
+
+import com.mdimension.jchronic.Options;
+import com.mdimension.jchronic.utils.Span;
+import org.chboston.cnlp.nlp.annotation.annotation.Annotation;
+import org.chboston.cnlp.nlp.annotation.attribute.Attribute;
+import org.chboston.cnlp.nlp.annotation.classtype.CustomClassType;
+import org.chboston.cnlp.nlp.annotation.classtype.TemporalClassType;
+import org.chboston.cnlp.nlp.annotation.entity.Entity;
+import org.chboston.cnlp.timeline.timespan.DefaultTimeSpan;
+import org.chboston.cnlp.timeline.timespan.TimeSpan;
+
+import java.util.*;
+
+
+/**
+ * Author: SPF
+ * Affiliation: CHIP-NLP
+ * Date: 9/4/12
+ */
+final public class AtParser {
+
+ private AtParser() {
+ }
+
+ /**
+ * A hack to get the docTime. Basically parses all date text using the standard java DateFormat.parse
+ * and returns the last parseable date - which assumes no absolutely specified future dates in the text.
+ *
+ * @param times collection of date entities
+ * @return a timex entity representing "now" as the last java parseable date in the list
+ */
+ // TODO getDocTimex called three times - can be down to two or one from createTimeline3
+// static public Timex getDocTimex( final Collection<Entity> namedEntities, final Collection<Timex> times ) {
+ static public <T extends Entity> Entity getDocTimex( final Collection<T> namedEntities,
+ final Collection<Entity> times ) {
+ for ( Entity entity : namedEntities ) {
+ if ( entity.isClassType( TemporalClassType.DOCTIME ) ) {
+ return entity;
+ }
+ final List<String> attributeNames = entity.getAttributeNames();
+ for ( String name : attributeNames ) {
+ final Attribute attribute = entity.getAttribute( name );
+ if ( attribute.getValue().equalsIgnoreCase( "DOCTIME" ) ) {
+ return entity;
+ }
+ }
+ }
+ for ( Entity timex : times ) {
+ final List<String> attributeNames = timex.getAttributeNames();
+ for ( String name : attributeNames ) {
+ final Attribute attribute = timex.getAttribute( name );
+ if ( attribute.getValue().equalsIgnoreCase( "DOCTIME" ) ) {
+ return timex;
+ }
+ }
+ }
+ Entity docTimex = null;
+ long maxMillis = StringDateParser.IMPROPER_DATE;
+ for ( Entity timex : times ) {
+ final String text = getTimexText( timex );
+ if ( text == null || text.isEmpty() ) {
+ continue;
+ }
+ final long millis = StringDateParser.getJavaDateMillis( text );
+ if ( millis > maxMillis ) {
+ docTimex = timex;
+ maxMillis = millis;
+ }
+ }
+ return docTimex;
+ }
+
+ static public long getTimexMillis( final Entity timex ) {
+ final String text = getTimexText( timex );
+ if ( text == null || text.isEmpty() ) {
+ return Calendar.getInstance().getTimeInMillis();
+ }
+ return StringDateParser.getJavaDateMillis( text );
+ }
+
+ static public Calendar getTimexCalendar( final Entity timex ) {
+ final long timexMillis = getTimexMillis( timex );
+ final Calendar calendar = Calendar.getInstance();
+ calendar.setTimeInMillis( timexMillis );
+ return calendar;
+ }
+
+ static public Collection<Entity> getValidTimes( final Iterable<Entity> times ) {
+ final Collection<Entity> timexSet = new HashSet<>();
+ for ( Entity timex : times ) {
+ final String text = getTimexText( timex );
+ if ( text != null && !text.isEmpty() ) {
+ timexSet.add( timex );
+ }
+ }
+ return timexSet;
+ }
+
+
+ static private String getTimexText( final Annotation timex ) {
+ if ( timex == null ) {
+ return "";
+ }
+ if ( timex.isClassType( TemporalClassType.DOCTIME ) ) {
+ return timex.getSpannedText();
+ }
+ final List<String> attributeNames = timex.getAttributeNames();
+ for ( String name : attributeNames ) {
+ final Attribute attribute = timex.getAttribute( name );
+ final String value = attribute.getValue().toUpperCase();
+ if ( value.equals( "DATE" ) ) {
+ return timex.getSpannedText();
+ } else if ( value.equals( "TIME" ) ) {
+ return timex.getSpannedText();
+ } else if ( value.equals( "DURATION" ) && timex.getSpannedText().contains( "last few" ) ) {
+ // Kludge because annotations often have duration of "last few XXX", which can become a parsed timespan
+ return timex.getSpannedText();
+ } else if ( value.equals( "DURATION" )
+ && (timex.getSpannedText().startsWith( "the last " )
+ || timex.getSpannedText().startsWith( "the next " )) ) {
+ // Kludge because annotations often have duration of "last few XXX", which can become a parsed timespan
+ return timex.getSpannedText();
+// } else if ( attribute.getValue().equalsIgnoreCase( "QUANTIFIER" ) ) {
+// return timex.getSpannedText();
+ } else if ( value.equals( "PREPOSTEXP" ) ) {
+ return timex.getSpannedText();
+// } else if ( attribute.getValue().equalsIgnoreCase( "SET" ) ) {
+// return timex.getSpannedText();
+ }
+ }
+ return "";
+ }
+
+
+ static public TimeSpan createTimeSpan( final String text, final Options chronicOptions ) {
+ if ( text == null || text.isEmpty() ) {
+ return null;
+ }
+ final Span chronicSpan = StringDateParser.getChronicSpan( chronicOptions, text );
+ if ( chronicSpan != null ) {
+ return new DefaultTimeSpan( chronicSpan, StringDateParser.isFuzzy( text ) );
+ }
+ return null;
+ }
+
+
+}
Added: ctakes/sandbox/timelanes/org/chboston/cnlp/timeline/chronic/parser/StringDateParser.java
URL: http://svn.apache.org/viewvc/ctakes/sandbox/timelanes/org/chboston/cnlp/timeline/chronic/parser/StringDateParser.java?rev=1660963&view=auto
==============================================================================
--- ctakes/sandbox/timelanes/org/chboston/cnlp/timeline/chronic/parser/StringDateParser.java (added)
+++ ctakes/sandbox/timelanes/org/chboston/cnlp/timeline/chronic/parser/StringDateParser.java Thu Feb 19 18:06:13 2015
@@ -0,0 +1,742 @@
+package org.chboston.cnlp.timeline.chronic.parser;
+
+import com.mdimension.jchronic.Chronic;
+import com.mdimension.jchronic.Options;
+import com.mdimension.jchronic.utils.Span;
+import org.chboston.cnlp.timeline.timespan.CalendarUtil;
+
+import java.util.Calendar;
+import java.util.Date;
+import org.apache.log4j.Logger;
+
+import static java.util.Calendar.*;
+
+/**
+ * Author: SPF
+ * Affiliation: CHIP-NLP
+ * Date: 8/1/12
+ */
+final public class StringDateParser {
+
+ static private final Logger LOGGER = Logger.getLogger( "StringDateParser" );
+
+ static public final long IMPROPER_DATE = Long.MIN_VALUE;
+
+
+ private StringDateParser() {
+ }
+
+ static public Span getChronicSpan( final Options chronicOptions, final String text ) {
+ final String refinedText = refineTextForChronic( text );
+ try {
+ if ( refinedText.length() == 4 && isInteger( refinedText ) ) {
+ return getYearSpan( refinedText );
+ }
+ Span chronicSpan = Chronic.parse( refinedText, chronicOptions );
+ if ( chronicSpan != null ) {
+ final Span refinedSpan = refineChronicSpan( chronicSpan, chronicOptions, text );
+// LOGGER.info( "Chronic parsed: " + text + " as: " + refinedText + " to: " + refinedSpan );
+ return refinedSpan;
+ } else {
+ LOGGER.warn( "Chronic couldn't parse: -" + text + "- as: -" + refinedText + "-" );
+ System.err.println( "Chronic couldn't parse: -" + text + "- as: -" + refinedText + "-" );
+ }
+ } catch ( RuntimeException rtE ) {
+ LOGGER.error( "Chronic parsing " + refinedText + " : " + rtE.getLocalizedMessage() );
+ }
+ return null;
+ }
+
+ static public long getJavaDateMillis( final String text ) {
+ final String refinedText = refineTextForJavaDate( text );
+ if ( refinedText == null || refinedText.isEmpty() ) {
+ return IMPROPER_DATE;
+ }
+ try {
+ // DateFormat doesn't always parse correctly, so we use the deprecated Date.parse method
+ return Date.parse( refinedText );
+ } catch ( IllegalArgumentException iaE ) {
+ //
+ }
+ return IMPROPER_DATE;
+ }
+
+
+ static public boolean isFuzzy( final String dateText ) {
+ final String lowerText = dateText.toLowerCase();
+ return !lowerText.equals( refineFuzzy1( dateText ) )
+ || !lowerText.equals( refineAtThisTime( dateText ) )
+ || !lowerText.equals( refineDecades( dateText) )
+ || !lowerText.equals( refineInterOperative( dateText ) )
+ || !lowerText.equals( refinePreOperative( dateText ) )
+ || !lowerText.equals( refinePostOperative( dateText ) )
+ || !lowerText.equals( refinePeriOperative( dateText ) )
+ || !lowerText.equals( refineIndeterminate( dateText ) )
+ || !lowerText.equals( refineOr( dateText ) )
+ || !lowerText.equals( refineSeason( dateText ) )
+ || !lowerText.equals( refineBeginEnd( dateText ) );
+ }
+
+ static private String refineTextForJavaDate( final String dateText ) {
+ return getYearJanOneText( dateText );
+ }
+
+ static private String getYearJanOneText( final String text ) {
+ if ( text != null && text.length() == 4 && isInteger( text ) ) {
+ return "01/01/" + text;
+ }
+ return text;
+ }
+
+ static final private String[] MONTH_TRIS = { "jan", "feb", "mar", "apr", "may", "jun",
+ "jul", "aug", "sep", "oct", "nov", "dec" };
+ static final private String[] MONTH_FULLS = { "january", "february", "march", "april", "may", "june",
+ "july", "august", "september", "october", "november", "december" };
+ static final private String[] DAY_NAMES = { "monday", "tuesday", "wednesday", "thursday",
+ "friday", "saturday", "sunday" };
+
+ static private String refineWhiteSpace( final String dateText ) {
+ String lowerText = dateText.toLowerCase();
+ lowerText = lowerText.replace( '\r', ' ' );
+ lowerText = lowerText.replace( '\n', ' ' );
+ lowerText = lowerText.replaceAll( "\\s+", " " );
+ return lowerText.trim();
+ }
+
+
+ static private String refineFuzzy1( final String dateText ) {
+ String lowerText = dateText.toLowerCase();
+ lowerText = lowerText.replaceAll( "\\bwithin\\b", "" );
+ lowerText = lowerText.replaceAll( "\\b(approximately|about|around|at least|some time in)\\b", "" );
+// lowerText = lowerText.replaceAll( "\\bin\\b", "" );
+ lowerText = lowerText.replaceAll( "\\bor so\\b", "" );
+ lowerText = lowerText.replaceAll( "-some\\b", "" );
+ lowerText = lowerText.replaceAll( "^(<|before|prior to)\\b", "" );
+ lowerText = lowerText.replaceAll( "\\bfrom\\b", "" );
+ lowerText = lowerText.replaceAll( "\\b(|the) first week in\\b", "" );
+ lowerText = lowerText.replaceAll( "\\ba little (over|under)\\b", "" );
+ return lowerText;
+ }
+
+ // remove seconds from times like 14:33:51
+ static private String removeSeconds( final String dateText ) {
+ String lowerText = dateText.toLowerCase();
+ if ( lowerText.contains( ":" ) && lowerText.length() > 9
+ && lowerText.charAt( lowerText.length() - 3 ) == ':' && lowerText.charAt( lowerText.length() - 5 ) == ':' ) {
+ return lowerText.substring( 0, lowerText.length() - 9 );
+ }
+ return lowerText;
+ }
+
+ // remove times from expressions like May 25, 1972 at 1:32 pm. 07:13 AM, 08 Mar 2010
+ static private String removeDateHours( final String dateText ) {
+ String lowerText = dateText.toLowerCase();
+ if ( !lowerText.replaceAll( "\\b[0-9]?[0-9], \\d{4} at ", "" ).equals( lowerText ) ) {
+ final int atIndex = lowerText.indexOf( " at " );
+ return lowerText.substring( 0, atIndex );
+ }
+ if ( !lowerText.replaceAll( "\\b[0-9]?[0-9]:\\d{2}(| am| pm), [0-9]?[0-9] [a-z]* \\d{4}\\b", "" ).equals( lowerText ) ) {
+ final int commaIndex = lowerText.indexOf( "," );
+ return lowerText.substring( commaIndex+1 );
+ }
+ return lowerText;
+ }
+
+ // fix undecorated times like 0100 hours
+ static private String refineUndecoratedHours( final String dateText ) {
+ String lowerText = dateText.toLowerCase();
+ if ( !lowerText.replaceAll( "\\b\\d{4} hours", "" ).equals( lowerText ) ) {
+ final int hourIndex = lowerText.indexOf( " hours" );
+ if ( hourIndex > 3 ) {
+ return lowerText.substring( 0, hourIndex-2 ) + ":" + lowerText.substring( hourIndex-2, hourIndex );
+ }
+ }
+ return lowerText;
+ }
+
+ // fix undecorated dates like 20110210 0909
+ static private String refineUndecoratedDate( final String dateText ) {
+ String lowerText = dateText.toLowerCase();
+ if ( !lowerText.replaceAll( "\\b\\d{8} \\d{4}\\b", "" ).equals( lowerText ) ) {
+ return lowerText.substring( 4, 6 ) + "/" + lowerText.substring( 6, 8 ) + "/" + lowerText.substring( 8, 10 )
+ + " " + lowerText.substring( 11, 13 ) + ":" + lowerText.substring( 13 );
+ }
+ if ( !lowerText.replaceAll( "\\b\\d{8}\\b", "" ).equals( lowerText ) ) {
+ return lowerText.substring( 4, 6 ) + "/" + lowerText.substring( 6, 8 ) + "/" + lowerText.substring( 8, 10 )
+ + lowerText.substring( 10 );
+ }
+ return lowerText;
+ }
+
+ // kludge for "DAY, date"
+ static private String reOrderDayDate( final String dateText ) {
+ String lowerText = dateText.toLowerCase();
+ for ( String day : DAY_NAMES ) {
+ if ( lowerText.startsWith( day ) ) {
+ final int spaceIndex = lowerText.indexOf( ' ' );
+ if ( spaceIndex < 0 ) {
+ return lowerText;
+ }
+ final String possibleMonther = lowerText.substring( spaceIndex + 1 );
+ for ( String monthTri : MONTH_TRIS ) {
+ if ( possibleMonther.startsWith( monthTri ) ) {
+ // Friday, Mar 10 1976
+ return possibleMonther;
+ }
+ }
+ for ( String monthFull : MONTH_FULLS ) {
+ if ( possibleMonther.startsWith( monthFull ) ) {
+ // Friday, March 10 1976
+ return possibleMonther;
+ }
+ }
+ break;
+ }
+ }
+ return lowerText;
+ }
+
+ // fix for dates like "9 May, 2010"
+ static private String reOrderDayMonth( final String dateText ) {
+ String lowerText = dateText.toLowerCase();
+ String month = "";
+ for ( String monthTri : MONTH_TRIS ) {
+ if ( !lowerText.equals( lowerText.replaceAll( "\\b[0-9]?[0-9] " + monthTri + ", \\d{4}\\b", "" ) ) ) {
+ month = monthTri;
+ break;
+ }
+ }
+ for ( String monthFull : MONTH_FULLS ) {
+ if ( !lowerText.equals( lowerText.replaceAll( "\\b[0-9]?[0-9] " + monthFull + ", \\d{4}\\b", "" ) ) ) {
+ month = monthFull;
+ break;
+ }
+ }
+ if ( month.isEmpty() ) {
+ return lowerText;
+ }
+ final int monthIndex = lowerText.indexOf( month );
+ final int dayIndex = Math.max( 0, monthIndex-3 );
+ return month + " " + lowerText.substring( dayIndex, monthIndex ) + " "
+ + lowerText.substring( monthIndex + month.length() + 1 );
+ }
+
+ // fix for dates like 02-May-2014, May-02-2014
+ static private String refineDashMonthTri( final String dateText ) {
+ String lowerText = dateText.toLowerCase();
+ int monthNum = 1;
+ for ( String monthTri : MONTH_TRIS ) {
+ if ( lowerText.startsWith( monthTri + "-" ) ) {
+ int nextDash = lowerText.indexOf( '-', 4 );
+ if ( nextDash < 0 ) {
+ nextDash = lowerText.length();
+ }
+ final String day = lowerText.substring( 4, nextDash );
+ if ( nextDash == lowerText.length() ) {
+ return monthNum + " " + day;
+ }
+ final String year = lowerText.substring( nextDash + 1 );
+ return monthNum + "/" + day + "/" + year;
+ }
+ final int dashIndex = lowerText.indexOf( "-" + monthTri + "-" );
+ if ( dashIndex > 0 ) {
+ final String day = lowerText.substring( 0, dashIndex );
+ final String year = lowerText.substring( dashIndex + 5 );
+ return monthNum + "/" + day + "/" + year;
+ }
+ monthNum++;
+ }
+ return lowerText;
+ }
+
+ // 15th of January 15 january 2010
+ static private String refineOfMonth( final String dateText ) {
+ String lowerText = dateText.toLowerCase();
+ for ( String monthFull : MONTH_FULLS ) {
+ lowerText = lowerText.replaceAll( monthFull + ",", monthFull );
+ final String ofMonth = lowerText.replaceAll( " of " + monthFull, "OF_MONTH" );
+ final int ofIndex = ofMonth.indexOf( "OF_MONTH" );
+ if ( ofIndex > 0 ) {
+ if ( ofMonth.indexOf( ' ' ) < 0 ) {
+ return monthFull + " " + ofMonth.substring( 0, ofIndex );
+ }
+
+ return monthFull + " " + ofMonth.substring( 0, ofIndex ) + " " + ofMonth.substring( ofIndex+8 );
+ }
+ }
+ return lowerText;
+ }
+
+ static private String refineDashMonthFull( final String dateText ) {
+ String lowerText = dateText.toLowerCase();
+ int monthNum = 1;
+ for ( String monthFull : MONTH_FULLS ) {
+ if ( lowerText.startsWith( monthFull + "-" ) ) {
+ int nextDash = lowerText.indexOf( '-', monthFull.length() + 1 );
+ if ( nextDash < 0 ) {
+ nextDash = lowerText.length();
+ }
+ final String day = lowerText.substring( monthFull.length(), nextDash );
+ if ( nextDash == lowerText.length() ) {
+ return monthNum + " " + day;
+ }
+ final String year = lowerText.substring( nextDash + 1 );
+ return monthNum + "/" + day + "/" + year;
+ }
+ monthNum++;
+ }
+ return lowerText;
+ }
+
+ static private String refineNumberEnds( final String dateText ) {
+ String lowerText = dateText.toLowerCase();
+ lowerText = lowerText.replaceAll( "1st,?\\b", "1" );
+ lowerText = lowerText.replaceAll( "2nd,?\\b", "2" );
+ lowerText = lowerText.replaceAll( "3rd,?\\b", "3" );
+ lowerText = lowerText.replaceAll( "4th,?\\b", "4" );
+ lowerText = lowerText.replaceAll( "5th,?\\b", "5" );
+ lowerText = lowerText.replaceAll( "6th,?\\b", "6" );
+ lowerText = lowerText.replaceAll( "7th,?\\b", "7" );
+ lowerText = lowerText.replaceAll( "8th,?\\b", "8" );
+ lowerText = lowerText.replaceAll( "9th,?\\b", "9" );
+ lowerText = lowerText.replaceAll( "\\b10th,?\\b", "10" );
+ lowerText = lowerText.replaceAll( "\\b11th,?\\b", "11" );
+ lowerText = lowerText.replaceAll( "\\b12th,?\\b", "12" );
+ lowerText = lowerText.replaceAll( "\\b13th,?\\b", "13" );
+ return lowerText;
+ }
+
+ static private String refineDecades( final String dateText ) {
+ String lowerText = dateText.toLowerCase();
+ String decadeless = lowerText.replaceAll( "\\b\\d{4}'?s\\b", "DECADE" );
+ int decadeIndex = decadeless.indexOf( "DECADE" );
+ if ( decadeIndex >= 0 ) {
+ return lowerText.substring( decadeIndex, decadeIndex+4 );
+ }
+ decadeless = lowerText.replaceAll( "\\b\\d{2}'?s\\b", "DECADE" );
+ decadeIndex = decadeless.indexOf( "DECADE" );
+ if ( decadeIndex >= 0 ) {
+ return "19" + lowerText.substring( decadeIndex, decadeIndex+2 );
+ }
+ lowerText = lowerText.replaceAll( "\\b(a|one) decade\\b", "10 years" );
+ lowerText = lowerText.replaceAll( "\\btwo decades\\b", "20 years" );
+ lowerText = lowerText.replaceAll( "\\three decades\\b", "30 years" );
+ return lowerText;
+ }
+
+
+ static private String refineAtThisTime( final String dateText ) {
+ String lowerText = dateText.toLowerCase();
+ if ( lowerText.equals( "now" ) ) {
+ return "this day";
+ }
+ lowerText = lowerText.replaceAll( "\\b(|at )this (time|point|juncture)(| in time)\\b", "this day" );
+ lowerText = lowerText.replaceAll( "\\b(|at )the current time\\b", "this day" );
+ lowerText = lowerText.replaceAll( "\\bthe time( |-)being\\b", "this day" );
+ lowerText = lowerText.replaceAll( "\\b(|at )(pres|curr|rec)ent(|ly)\\b", "this day" );
+ lowerText = lowerText.replaceAll( "\\b(|most )(recent|late)ly\\b", "this day" );
+ lowerText = lowerText.replaceAll( "\\b(immediately|as soon as possible|at the current time)\\b", "this day" );
+ lowerText = lowerText.replaceAll( "\\btoday'?s\\b", "this day" );
+ lowerText = lowerText.replaceAll( "\\b(|this )mid-?(day| ?afternoon)\\b", "this day" );
+ lowerText = lowerText.replaceAll( "\\byesterday'?s\\b", "yesterday" );
+ lowerText = lowerText.replaceAll( "\\b(|this )mid-? ?morning\\b", "this morning" );
+ lowerText = lowerText.replaceAll( "\\bthis a.m.?\\b", "this morning" );
+ lowerText = lowerText.replaceAll( "\\b(overnight|nighttime|evening)\\b", "night" );
+ lowerText = lowerText.replaceAll( "\\b(tonite|tonight)\\b", "this night" );
+ return lowerText;
+ }
+
+ static private String refineInterOperative( final String dateText ) {
+ String lowerText = dateText.toLowerCase();
+ if ( lowerText.equals( "operative" ) ) {
+ return "this day";
+ }
+ lowerText = lowerText.replaceAll( "\\b(|at )(|the )(|point of |time of )(|hospital )(admission|consultation)\\b", "this day" );
+ lowerText = lowerText.replaceAll( "\\bint(er|ra)-? ?op(|erative|eratively)\\b", "this day" );
+ lowerText = lowerText.replaceAll( "\\b(during|time of) (|the )(operation|surgery)\\b", "this day" );
+ // kludge - discharge is not a great thing to put here
+ lowerText = lowerText.replaceAll( "\\b(|at )(|the )(|point of |time of )(|hospital )(discharge)\\b", "this night" );
+ return lowerText;
+ }
+
+ static private String refinePreOperative( final String dateText ) {
+ String lowerText = dateText.toLowerCase();
+ if ( lowerText.equals( "pre" ) ) {
+ return "this day";
+ }
+ lowerText = lowerText.replaceAll( "\\bpre-? ?op(|eration|erative|eratively)\\b", "this day" );
+ lowerText = lowerText.replaceAll( "\\bpre-? ?surg(ical|ery)\\b", "this day" );
+ lowerText = lowerText.replaceAll( "\\bpre-? ?(treatment|procedure)\\b", "this day" );
+ lowerText = lowerText.replaceAll( "\\b(before|prior to) (|the )(operation|surgery)\\b", "this day" );
+ return lowerText;
+ }
+
+ static private String refinePostOperative( final String dateText ) {
+ String lowerText = dateText.toLowerCase();
+ if ( lowerText.equals( "post" ) ) {
+ return "this day";
+ }
+ lowerText = lowerText.replaceAll( "\\bpost-? ?op(|eration|erative|eratively)\\b", "this day" );
+ lowerText = lowerText.replaceAll( "\\bpost-? ?(treatment|procedure|hospitalization)\\b", "this day" );
+ lowerText = lowerText.replaceAll( "\\bpost-? ?surg(ical|ery)\\b", "this day" );
+ lowerText = lowerText.replaceAll( "\\b(after|following) (|the )(operation|surgery)\\b", "this day" );
+ // kludge for expressions like "3-4 weeks postop"
+ if ( lowerText.endsWith( "this day" ) ) {
+ return "this day";
+ }
+ return lowerText;
+ }
+
+ static private String refinePeriOperative( final String dateText ) {
+ String lowerText = dateText.toLowerCase();
+ if ( lowerText.equals( "peri" ) ) {
+ return "this day";
+ }
+ lowerText = lowerText.replaceAll( "\\bperi?-? ?op(|eration|erative|eratively)\\b", "this day" );
+ lowerText = lowerText.replaceAll( "\\bperi?-? ?procedural\\b", "this day" );
+ return lowerText;
+ }
+
+ static private String refineIndeterminate( final String dateText ) {
+ String lowerText = dateText.toLowerCase();
+ lowerText = lowerText.replaceAll( "\\b(|a )couple(| of)\\b", "two" );
+ lowerText = lowerText.replaceAll( "\\b(|a )few\\b", "three" );
+ lowerText = lowerText.replaceAll( "\\b(several|some)\\b", "three" );
+ lowerText = lowerText.replaceAll( "\\bmany|(, many)\\b", "five" );
+ return lowerText;
+ }
+
+ static private String refineOr( final String dateText ) {
+ String lowerText = dateText.toLowerCase();
+ lowerText = lowerText.replaceAll( "\\b(1|one)-? ?(to|or)-? ?(2|two)\\b", "two" );
+ lowerText = lowerText.replaceAll( "\\b(1|one)-? ?(to|or)-? ?(3|three)\\b", "three" );
+ lowerText = lowerText.replaceAll( "\\b(2|two)-? ?(to|or)-? ?(3|three)\\b", "three" );
+ lowerText = lowerText.replaceAll( "\\b(3|three)-? ?(to|or)-? ?(4|four)\\b", "four" );
+ lowerText = lowerText.replaceAll( "\\b(4|four)-? ?(to|or)-? ?(5|five)\\b", "five" );
+ lowerText = lowerText.replaceAll( "\\b(4|four)-? ?(to|or)-? ?(6|six)\\b", "five" );
+ lowerText = lowerText.replaceAll( "\\b(4|four)-? ?(to|or)-? ?(8|eight)\\b", "six" );
+ lowerText = lowerText.replaceAll( "\\b(5|five)-? ?(to|or)-? ?(6|six)\\b", "six" );
+ lowerText = lowerText.replaceAll( "\\b(6|six)-? ?(to|or)-? ?(7|seven)\\b", "seven" );
+ lowerText = lowerText.replaceAll( "\\b(6|six)-? ?(to|or)-? ?(8|eight)\\b", "seven" );
+ lowerText = lowerText.replaceAll( "\\b(7|seven)-? ?(to|or)-? ?(8|eight)\\b", "eight" );
+ lowerText = lowerText.replaceAll( "\\b(9|nine)-? ?(to|or)-? ?(10|ten)\\b", "ten" );
+ lowerText = lowerText.replaceAll( "\\b(10|ten)-? ?(to|or)-? ?(12|twelve)\\b", "twelve" );
+ lowerText = lowerText.replaceAll( "\\b(1|one)-? ?(to|or)-? ?(12|twelve)\\b", "six" );
+ lowerText = lowerText.replaceAll( "\\b(17|seventeen)-? ?(to|or)-? ?(18|eighteen)\\b", "18" );
+ lowerText = lowerText.replaceAll( "\\b(20|twenty)-? ?some\\b", "20" );
+ final String orYears = lowerText.replaceAll( "\\b\\d{4} or \\d{4}\\b", "YEAR_OR" );
+ final int orIndex = orYears.indexOf( "YEAR_OR" );
+ if ( orIndex >= 0 ) {
+ return lowerText.substring( 0,orIndex+5 );
+ }
+// lowerText = lowerText.replaceAll( "\\b1-\\b", "one" );
+ return lowerText;
+ }
+
+ static private String refineSeason( final String dateText ) {
+ String lowerText = dateText.toLowerCase();
+ lowerText = lowerText.replaceAll( "\\b(|the|this|last) ?(|early-? ?|mid-? ?|late-? ?)winter ?(|of)(| ?this year)\\b", "december 21 " );
+ lowerText = lowerText.replaceAll( "\\b(|the|this|last) ?(|early-? ?|mid-? ?|late-? ?)spring ?(|of)(| ?this year)\\b", "march 20 " );
+ lowerText = lowerText.replaceAll( "\\b(|the|this|last) ?(|early-? ?|mid-? ?|late-? ?)summer ?(|of)(| ?this year)\\b", "june 21 " );
+ lowerText = lowerText.replaceAll( "\\b(|the|this|last) ?(|early-? ?|mid-? ?|late-? ?)fall ?(|of)(| ?this year)\\b", "september 22 " );
+ lowerText = lowerText.replaceAll( "\\b(|the|this|last) ?(|early-? ?|mid-? ?|late-? ?)autumn ?(|of)(| ?this year)\\b", "september 22 " );
+ return lowerText;
+ }
+
+ static private String refineBeginEnd( final String dateText ) {
+ String lowerText = dateText.toLowerCase();
+ lowerText = lowerText.replaceAll( "\\b(|at |in )(|the )beginning of (the|this) year\\b", "january 1" );
+ lowerText = lowerText.replaceAll( "\\b(|at |in )(|the )(end|latter part) of (the|this) year\\b", "september 22" );
+ lowerText = lowerText.replaceAll( "\\b(|at |in )(|the )(beginning|middle|end) of the day\\b", "this day" );
+// lowerText = lowerText.replaceAll( "^(the |in |0 )", "" );
+ lowerText = lowerText.replaceAll( "^(the |0 )", "" );
+ lowerText = lowerText.replaceAll( "^(early |late |later |latter part of )(|the |this |in )", "" );
+ lowerText = lowerText.replaceAll( "\\b(|at |in )(|the )(beginning|middle|end) (|of )", "" );
+ return lowerText;
+ }
+
+ static private String refineTextForChronic( final String dateText ) {
+ String lowerText = dateText.toLowerCase();
+ lowerText = refineWhiteSpace( lowerText );
+ lowerText = refineInterOperative( lowerText );
+ lowerText = refinePreOperative( lowerText );
+ lowerText = refinePostOperative( lowerText );
+ lowerText = refinePeriOperative( lowerText );
+ lowerText = refineFuzzy1( lowerText );
+ if ( lowerText.endsWith( "," ) || lowerText.endsWith( "." ) ) {
+ lowerText = lowerText.substring( 0, lowerText.length() - 1 );
+ }
+ lowerText = removeDateHours( lowerText );
+ lowerText = removeSeconds( lowerText );
+ lowerText = refineUndecoratedHours( lowerText );
+ lowerText = refineUndecoratedDate( lowerText );
+ lowerText = lowerText.trim();
+ lowerText = reOrderDayDate( lowerText );
+ lowerText = reOrderDayMonth( lowerText );
+ lowerText = refineDashMonthTri( lowerText );
+ // 15th of January
+ lowerText = refineOfMonth( lowerText );
+ lowerText = refineDashMonthFull( lowerText );
+ lowerText = refineNumberEnds( lowerText );
+ lowerText = lowerText.replaceAll( "\\b24-? ?hours\\b", "day" );
+ lowerText = lowerText.replaceAll( "s' time\\b", "s" );
+ lowerText = refineDecades( lowerText );
+ lowerText = refineAtThisTime( lowerText );
+ lowerText = lowerText.replaceAll( "^day\\b", "a day" );
+ lowerText = refineIndeterminate( lowerText );
+ lowerText = refineOr( lowerText );
+ lowerText = refineSeason( lowerText );
+ // first/last XX in YY
+ lowerText = lowerText.replaceAll( "^(|the )(first|last) [a-z]* (in|of) ", "" );
+ // of this year
+ lowerText = lowerText.replaceAll( "\\b of this year\\b", "" );
+ // last / next / prior to
+ lowerText = lowerText.replaceAll( "^(over|in|during) the\\b", "this" );
+ lowerText = lowerText.replaceAll( "^(|the )(p|l)ast\\b", "this past" );
+ // kludge for 1-2 days in demo
+ lowerText = lowerText.replaceAll( "\\b(|in )(|the next )(1|one)-? ?(|to )-? ?(2|two) weeks\\b", "in 2 weeks" );
+ lowerText = refineBeginEnd( lowerText );
+ lowerText = lowerText.replaceAll( "^in\\b", "" );
+ lowerText = lowerText.replaceAll( "^at\\b", "" );
+ lowerText = lowerText.replaceAll( "\\byrs\\b", "years" );
+ lowerText = lowerText.replaceAll( "-days\\b", " days" );
+ lowerText = lowerText.replaceAll( "-month\\b", " month" );
+ lowerText = lowerText.replaceAll( "-year\\b", " year" );
+ lowerText = lowerText.replace( '"', ' ' );
+ lowerText = lowerText.replace( '=', ' ' );
+ lowerText = lowerText.replaceAll( "\\s+", " " );
+ return lowerText.trim();
+ }
+
+ static private int getNumber( final String dateText ) {
+ final String[] tokens = dateText.split( " " );
+ for ( String token : tokens ) {
+ if ( !token.isEmpty() ) {
+ try {
+ return Integer.parseInt( token );
+ } catch ( NumberFormatException nfE ) {
+ // continue
+ }
+ }
+ }
+ return Integer.MIN_VALUE;
+ }
+
+ static private boolean isPreSurgery( final String lowerText ) {
+ return !lowerText.equals( refinePreOperative( lowerText ) );
+ }
+
+ static private boolean isPostSurgery( final String lowerText ) {
+ return !lowerText.equals( refinePostOperative( lowerText ) );
+ }
+
+ static private boolean isIntraOperative( final String lowerText ) {
+ return !lowerText.equals( refineInterOperative( lowerText ) );
+ }
+
+ static private boolean isPeriOperative( final String lowerText ) {
+ return !lowerText.equals( refinePeriOperative( lowerText ) );
+ }
+
+
+ static private final String[] EARLY_LATE_KEYS = { "early", "beginning of", "late", "end of", "latter part of",
+ "mid" };
+
+ static private Span createEarlyLateSpan( final Calendar beginCalendar, final Calendar endCalendar,
+ final int unit, final int offset, final String lowerText ) {
+ if ( lowerText.startsWith( "early" ) || lowerText.contains( "beginning of" ) ) {
+ endCalendar.add( unit, -1 * offset );
+ } else if ( lowerText.startsWith( "late" ) || lowerText.startsWith( "the late" )
+ || lowerText.contains( "end of" ) || lowerText.contains( "latter part of" ) ) {
+ beginCalendar.add( unit, offset );
+ } else if ( (lowerText.startsWith( "mid" ) || lowerText.startsWith( "the mid" )) && offset > 1 ) {
+ beginCalendar.add( unit, offset / 2 );
+ endCalendar.add( unit, -1 * offset / 2 );
+ }
+ return new Span( beginCalendar, endCalendar );
+ }
+
+ static private Span refineChronicSpan( final Span chronicSpan,
+ final Options chronicOptions,
+ final String dateText ) {
+ final String lowerText = dateText.toLowerCase();
+ final Calendar beginCalendar = chronicSpan.getBeginCalendar();
+ final Calendar endCalendar = chronicSpan.getEndCalendar();
+ // preop / postop (be careful)
+ if ( isPreSurgery( lowerText ) ) {
+ beginCalendar.add( DAY_OF_YEAR, -7 );
+ return createEarlyLateSpan( beginCalendar, endCalendar, DAY_OF_YEAR, 3, lowerText );
+ } else if ( isPostSurgery( lowerText ) ) {
+ endCalendar.add( DAY_OF_YEAR, 30 );
+ return createEarlyLateSpan( beginCalendar, endCalendar, DAY_OF_YEAR, 15, lowerText );
+ } else if ( isPeriOperative( lowerText ) ) {
+ beginCalendar.add( DAY_OF_YEAR, -7 );
+ endCalendar.add( DAY_OF_YEAR, 30 );
+ return createEarlyLateSpan( beginCalendar, endCalendar, DAY_OF_YEAR, 18, lowerText );
+ }
+ // adjust for season spans
+ else if ( lowerText.contains( "winter" ) ) {
+ endCalendar.set( MONTH, MARCH );
+ endCalendar.set( DAY_OF_MONTH, 20 );
+ endCalendar.add( YEAR, 1 );
+ return createEarlyLateSpan( beginCalendar, endCalendar, DAY_OF_YEAR, 30, lowerText );
+ } else if ( lowerText.contains( "spring" ) ) {
+ endCalendar.set( MONTH, JUNE );
+ endCalendar.set( DAY_OF_MONTH, 21 );
+ return createEarlyLateSpan( beginCalendar, endCalendar, DAY_OF_YEAR, 30, lowerText );
+ } else if ( lowerText.contains( "summer" ) ) {
+ endCalendar.set( MONTH, SEPTEMBER );
+ endCalendar.set( DAY_OF_MONTH, 22 );
+ return createEarlyLateSpan( beginCalendar, endCalendar, DAY_OF_YEAR, 30, lowerText );
+ } else if ( lowerText.contains( "fall" ) || lowerText.contains( "autumn" ) ) {
+ endCalendar.set( MONTH, DECEMBER );
+ endCalendar.set( DAY_OF_MONTH, 21 );
+ return createEarlyLateSpan( beginCalendar, endCalendar, DAY_OF_YEAR, 30, lowerText );
+ // kludge
+ } else if ( lowerText.contains( "end of the year" ) ) {
+ endCalendar.set( MONTH, DECEMBER );
+ endCalendar.set( DAY_OF_MONTH, 21 );
+ return createEarlyLateSpan( beginCalendar, endCalendar, DAY_OF_YEAR, 30, lowerText );
+ }
+ // adjust for "early march", "late april"
+ for ( String month : MONTH_FULLS ) {
+ if ( lowerText.endsWith( month ) ) {
+ for ( String earlyLate : EARLY_LATE_KEYS ) {
+ if ( lowerText.startsWith( earlyLate ) ) {
+ return createEarlyLateSpan( beginCalendar, endCalendar, DAY_OF_YEAR, 14, lowerText );
+ }
+ }
+ }
+ }
+ // adjust for "last few" spans
+ if ( !lowerText.replaceAll( "\\b(|in|during|over )th(e |is )(l|p)ast", "" ).equals( lowerText )
+ || !lowerText.replaceAll( "\\b(last|past) (couple|few|several)", "" ).equals( lowerText ) ) {
+ final Span nowChronicSpan = Chronic.parse( "today", chronicOptions );
+ if ( nowChronicSpan != null ) {
+ return new Span( beginCalendar, nowChronicSpan.getEndCalendar() );
+ }
+ }
+ // adjust for "the last" spans
+ if ( lowerText.startsWith( "the next" ) ) {
+ final Span nowChronicSpan = Chronic.parse( "today", chronicOptions );
+ if ( nowChronicSpan != null ) {
+ return new Span( nowChronicSpan.getBeginCalendar(), endCalendar );
+ }
+ }
+ // adjust for "ago" spans
+ if ( lowerText.contains( "ago" ) || lowerText.contains( "before" ) || lowerText.contains( "prior" )
+ || lowerText.contains( "after" ) || lowerText.contains( "in " ) ) {
+ if ( lowerText.contains( "year" ) ) {
+ beginCalendar.add( Calendar.MONTH, -6 );
+ endCalendar.add( Calendar.MONTH, 6 );
+ } else if ( lowerText.contains( "month" ) ) {
+ beginCalendar.add( Calendar.DAY_OF_YEAR, -15 );
+ endCalendar.add( Calendar.DAY_OF_YEAR, 15 );
+ } else if ( lowerText.contains( "week" ) ) {
+ beginCalendar.add( Calendar.DAY_OF_YEAR, -3 );
+ endCalendar.add( Calendar.DAY_OF_YEAR, 3 );
+ } else if ( lowerText.contains( "day" ) ) {
+ // Day and hour are fine gradation that they shouldn't be adjusted by half
+ endCalendar.add( Calendar.HOUR_OF_DAY, 24 );
+ } else if ( lowerText.contains( "hours" ) ) {
+ // a large number of hours can represent days
+ final int totalHours = getNumber( lowerText );
+ if ( totalHours == Integer.MIN_VALUE || totalHours < 24 ) {
+ endCalendar.add( Calendar.MINUTE, 60 );
+ } else {
+ beginCalendar.add( Calendar.HOUR_OF_DAY, -totalHours % 24 );
+ endCalendar.add( Calendar.HOUR_OF_DAY, 24 );
+ }
+ } else if ( lowerText.contains( "hour" ) ) {
+ endCalendar.add( Calendar.MINUTE, 60 );
+ }
+ return new Span( beginCalendar, endCalendar );
+ }
+ // adjust for "first of" spans
+ if ( lowerText.startsWith( "first" ) && (lowerText.contains( " in " ) || lowerText.contains( " of " )) ) {
+ endCalendar.setTimeInMillis( beginCalendar.getTimeInMillis() );
+ if ( lowerText.contains( "year" ) ) {
+ endCalendar.add( Calendar.YEAR, 1 );
+ } else if ( lowerText.contains( "month" ) ) {
+ endCalendar.add( Calendar.MONTH, 1 );
+ } else if ( lowerText.contains( "week" ) ) {
+ endCalendar.add( Calendar.DAY_OF_YEAR, 7 );
+ } else if ( lowerText.contains( "day" ) ) {
+ // Day and hour are fine gradation that they shouldn't be adjusted by half
+ endCalendar.add( Calendar.DAY_OF_YEAR, 1 );
+ } else if ( lowerText.contains( "hours" ) ) {
+ // a large number of hours can represent days
+ final int totalHours = getNumber( lowerText );
+ endCalendar.add( Calendar.HOUR_OF_DAY, totalHours );
+ } else if ( lowerText.contains( "hour" ) ) {
+ endCalendar.add( Calendar.HOUR_OF_DAY, 1 );
+ }
+ return new Span( beginCalendar, endCalendar );
+ }
+ // adjust for decades
+ if ( !lowerText.equals( refineDecades( lowerText ) ) ) {
+ endCalendar.add( Calendar.YEAR, 10 );
+ return new Span( beginCalendar, endCalendar );
+ }
+ // adjust for "last of" spans
+ if ( lowerText.startsWith( "last" ) && (lowerText.contains( " in " ) || lowerText.contains( " of " )) ) {
+ beginCalendar.setTimeInMillis( endCalendar.getTimeInMillis() );
+ if ( lowerText.contains( "year" ) ) {
+ beginCalendar.add( Calendar.YEAR, -1 );
+ } else if ( lowerText.contains( "month" ) ) {
+ beginCalendar.add( Calendar.MONTH, -1 );
+ } else if ( lowerText.contains( "week" ) ) {
+ beginCalendar.add( Calendar.DAY_OF_YEAR, -7 );
+ } else if ( lowerText.contains( "day" ) ) {
+ // Day and hour are fine gradation that they shouldn't be adjusted by half
+ beginCalendar.add( Calendar.DAY_OF_YEAR, -1 );
+ } else if ( lowerText.contains( "hours" ) ) {
+ // a large number of hours can represent days
+ final int totalHours = getNumber( lowerText );
+ beginCalendar.add( Calendar.HOUR_OF_DAY, -totalHours );
+ } else if ( lowerText.contains( "hour" ) ) {
+ beginCalendar.add( Calendar.HOUR_OF_DAY, -1 );
+ }
+ return new Span( beginCalendar, endCalendar );
+ }
+
+ // Adjust for times set to midnight for a relative date textspan
+ if ( beginCalendar.get( DAY_OF_YEAR ) == endCalendar.get( DAY_OF_YEAR )
+ && beginCalendar.get( YEAR ) == endCalendar.get( YEAR ) ) {
+ if ( CalendarUtil.isMidnight( beginCalendar ) && endCalendar.get( HOUR_OF_DAY ) == 0
+ && endCalendar.get( MINUTE ) == 0 && endCalendar.get( SECOND ) == 1 ) {
+ beginCalendar.set( HOUR_OF_DAY, 12 );
+ // Remember that Chronic spans take seconds, not milliseconds
+ return new Span( beginCalendar.getTimeInMillis() / 1000, beginCalendar.getTimeInMillis() / 1000 );
+ }
+ }
+ return chronicSpan;
+ }
+
+
+ static private Span getYearSpan( final String text ) {
+ try {
+ int year = Integer.decode( text );
+ final Calendar begin = Calendar.getInstance();
+ begin.set( year, JANUARY, 1, 0, 0, 0 );
+ final Calendar end = Calendar.getInstance();
+ end.set( year + 1, JANUARY, 1, 0, 0, 0 );
+ return new Span( begin, end );
+ } catch ( NumberFormatException nfE ) {
+ // do nothing
+ }
+ return null;
+ }
+
+ // Java standard libraries should really have a method for this
+ static private boolean isInteger( final String text ) {
+ try {
+ Integer.decode( text );
+ return true;
+ } catch ( NumberFormatException nfE ) {
+ // do nothing
+ }
+ return false;
+ }
+
+}
Added: ctakes/sandbox/timelanes/org/chboston/cnlp/timeline/debug/InfoPanel.java
URL: http://svn.apache.org/viewvc/ctakes/sandbox/timelanes/org/chboston/cnlp/timeline/debug/InfoPanel.java?rev=1660963&view=auto
==============================================================================
--- ctakes/sandbox/timelanes/org/chboston/cnlp/timeline/debug/InfoPanel.java (added)
+++ ctakes/sandbox/timelanes/org/chboston/cnlp/timeline/debug/InfoPanel.java Thu Feb 19 18:06:13 2015
@@ -0,0 +1,252 @@
+package org.chboston.cnlp.timeline.debug;
+
+import org.chboston.cnlp.gui.PositioningSplitPane;
+import org.chboston.cnlp.nlp.annotation.entity.Entity;
+import org.chboston.cnlp.nlp.annotation.gui.EventDetailsTableModel;
+import org.chboston.cnlp.timeline.eventSelection.EventSelectionEvent;
+import org.chboston.cnlp.timeline.eventSelection.EventSelectionListener;
+import org.chboston.cnlp.timeline.gui.timespan.TimeSpanSelectionEvent;
+import org.chboston.cnlp.timeline.gui.timespan.TimeSpanSelectionListener;
+import org.chboston.cnlp.timeline.timeline.Timeline;
+
+import javax.swing.*;
+import javax.swing.event.TreeSelectionEvent;
+import javax.swing.event.TreeSelectionListener;
+import javax.swing.tree.TreePath;
+import java.awt.*;
+
+/**
+ * Author: SPF
+ * Affiliation: CHIP-NLP
+ * Date: 8/2/13
+ */
+public class InfoPanel extends JPanel {
+
+
+ private final TimeSpanSelectionListener _timeSpanSelectionListener;
+ private final EventSelectionListener _eventSelectionListener;
+
+
+ public InfoPanel() {
+ super( new BorderLayout() );
+
+ _timeSpanSelectionListener = new InfoPanelTimeSpanListener();
+ _eventSelectionListener = new InfoPanelEventListener();
+ }
+
+ public TimeSpanSelectionListener getSelectionListener() {
+ return _timeSpanSelectionListener;
+ }
+
+ public EventSelectionListener getEventSelectionListener() {
+ return _eventSelectionListener;
+ }
+
+
+ public void setTimeline( final Timeline timeline ) {
+ // final EntityCollectionTableModel eventsTableModel = new EntityCollectionTableModel();
+ final EventDetailsTableModel detailsTableModel = new EventDetailsTableModel();
+ // final JTable entityTable = new JTable( eventsTableModel );
+ final JTable eventDetailsTable = new JTable( detailsTableModel );
+ // final ListSelectionListener listSelectionListener = new EntitySelectionHandler( eventsTableModel,
+ // detailsTableModel );
+ // entityTable.getSelectionModel().addListSelectionListener( listSelectionListener );
+ // final PositioningSplitPane tablePanel = new PositioningSplitPane( JSplitPane.VERTICAL_SPLIT,
+ // new JScrollPane( entityTable ),
+ // new JScrollPane( relationTable ) );
+ // tablePanel.setOneTouchExpandable( true );
+ // tablePanel.setDividerLocation( 0.5d );
+ final TimeSpanTreeModel treeModel = new TimeSpanTreeModel( timeline );
+ final JTree tree = new JTree( treeModel );
+ tree.setRootVisible( false );
+ // final TreeSelectionListener treeSelectionListener = new TimeSpanSelectionHandler( eventsTableModel,
+ // detailsTableModel );
+ final TreeSelectionListener treeSelectionListener = new TimeSpanSelectionHandler( detailsTableModel );
+ tree.addTreeSelectionListener( treeSelectionListener );
+ final PositioningSplitPane splitPane = new PositioningSplitPane( JSplitPane.HORIZONTAL_SPLIT,
+ new JScrollPane( tree ),
+ new JScrollPane( eventDetailsTable ) );
+ // tablePanel );
+ splitPane.setOneTouchExpandable( true );
+ splitPane.setDividerLocation( 0.3d );
+ add( splitPane, BorderLayout.CENTER );
+ }
+
+
+ private class TimeSpanSelectionHandler implements TreeSelectionListener {
+ final private EventDetailsTableModel __detailsTableModel;
+
+ private TimeSpanSelectionHandler( final EventDetailsTableModel detailsTableModel ) {
+ __detailsTableModel = detailsTableModel;
+ }
+
+ public void valueChanged( final TreeSelectionEvent event ) {
+ final TreePath selectedPath = event.getNewLeadSelectionPath();
+ if ( selectedPath == null ) {
+ return;
+ }
+ final Object selection = selectedPath.getLastPathComponent();
+ if ( selection instanceof TimeSpanTreeModel.FunkyTimeSpanNode ) {
+ __detailsTableModel.setEntity( null );
+ } else if ( selection instanceof TimeSpanTreeModel.EntityNode ) {
+ final Entity entity = ((TimeSpanTreeModel.EntityNode)selection).getEntity();
+ __detailsTableModel.setEntity( entity );
+ } else {
+ __detailsTableModel.setEntity( null );
+ }
+ }
+ }
+
+
+ // private class TimeSpanSelectionHandler implements TreeSelectionListener {
+ // final private EntityCollectionTableModel __eventsTableModel;
+ // final private EventDetailsTableModel __detailsTableModel;
+ // private TimeSpanSelectionHandler( final EntityCollectionTableModel eventsTableModel,
+ // final EventDetailsTableModel detailsTableModel ) {
+ // __eventsTableModel = eventsTableModel;
+ // __detailsTableModel = detailsTableModel;
+ // }
+ //
+ // public void valueChanged( final TreeSelectionEvent event ) {
+ // final TreePath selectedPath = event.getNewLeadSelectionPath();
+ // if ( selectedPath == null ) {
+ // return;
+ // }
+ // final Object selection = selectedPath.getLastPathComponent();
+ // if ( selection instanceof TimeSpanTreeModel.FunkyTimeSpanNode ) {
+ // final java.util.List<Entity> eventList = ((TimeSpanTreeModel.FunkyTimeSpanNode)selection).getEvents();
+ // __eventsTableModel.setEntityList( eventList );
+ // __detailsTableModel.setEntity( null );
+ // } else if ( selection instanceof TimeSpanTreeModel.EntityNode ) {
+ // final Entity entity = ((TimeSpanTreeModel.EntityNode)selection).getEntity();
+ // final java.util.List<Entity> eventList = Arrays.asList( entity );
+ // __eventsTableModel.setEntityList( eventList );
+ // __detailsTableModel.setEntity( entity );
+ // } else {
+ // __eventsTableModel.setEntityList( null );
+ // __detailsTableModel.setEntity( null );
+ // }
+ // }
+ // }
+
+ // private class EntitySelectionHandler implements ListSelectionListener {
+ // final private EntityCollectionTableModel __eventsTableModel;
+ // final private EventDetailsTableModel __detailsTableModel;
+ // private EntitySelectionHandler( final EntityCollectionTableModel eventsTableModel,
+ // final EventDetailsTableModel detailsTableModel ) {
+ // __eventsTableModel = eventsTableModel;
+ // __detailsTableModel = detailsTableModel;
+ // }
+ // public void valueChanged( final ListSelectionEvent event ) {
+ // if ( event.getValueIsAdjusting() ) {
+ // return;
+ // }
+ // final Object source = event.getSource();
+ // if ( !(source instanceof ListSelectionModel) ) {
+ // return;
+ // }
+ // final int leadIndex = ((ListSelectionModel) source).getLeadSelectionIndex();
+ // if ( leadIndex >= 0 ) {
+ // final Entity entity = __eventsTableModel.getEntity( leadIndex );
+ // __detailsTableModel.setEntity( entity );
+ // } else {
+ // __detailsTableModel.setEntity( null );
+ // }
+ // }
+ // }
+
+
+ private class InfoPanelTimeSpanListener implements TimeSpanSelectionListener {
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void valueChanged( final TimeSpanSelectionEvent event ) {
+ // if ( event == null || event.getValueIsAdjusting() ) {
+ // return;
+ // }
+ // final Object source = event.getSource();
+ // if ( source == null || source.equals( InfoPanel.this ) ) {
+ // return;
+ // }
+ // final Collection<TimeSpan> timeSpans = event.getSelectedTimeSpans();
+ // if ( timeSpans.isEmpty() ) {
+ // setText( "" );
+ // } else {
+ // final Collection<String> texts = event.getSelectionTexts();
+ // final StringBuilder sb = new StringBuilder();
+ // sb.append( HEADER );
+ // for ( TimeSpan timeSpan : timeSpans ) {
+ // if ( timeSpan instanceof TimeSpanPlus ) {
+ // appendFunkyTimeSpan( sb, source, (TimeSpanPlus)timeSpan, texts );
+ // System.out.println("Texts");
+ // for ( String text : texts ) {
+ // System.out.println( " " + text );
+ // }
+ // final JTimelineComponent comp = (JTimelineComponent)source;
+ // final DefaultTimeline timeline = comp.getModel();
+ // final Set<Relation> tlinks = timeline.getTlinks( (TimeSpanPlus)timeSpan );
+ // final List<Relation> tlinkList = new ArrayList<Relation>( tlinks );
+ // Collections.sort( tlinkList, TlinkRefiner.INSTANCE );
+ // final Set<Entity> usedEntities = new HashSet<Entity>();
+ // System.out.println("Tlinks");
+ // for ( Relation tlink : tlinkList ) {
+ // if ( usedEntities.contains( tlink.getFirstEntity() ) ) {
+ // continue;
+ // }
+ // final Attribute tlinkAttribute = tlink.getAttribute( "Relation Type" );
+ // if ( tlinkAttribute == null ) {
+ // System.out.print(" Equal ");
+ // } else {
+ // System.out.print( " " + tlinkAttribute.getValue() );
+ // }
+ // System.out.println( " " + tlink.toString() );
+ //
+ // final Entity entity = tlink.getFirstEntity();
+ // final Set<Relation> eventEvents = timeline.getEntityEntityLinks( entity );
+ // if ( eventEvents != null && !eventEvents.isEmpty() ) {
+ // System.out.println( " EventEvents");
+ // final List<Relation> eventEventList = new ArrayList<Relation>( eventEvents );
+ // Collections.sort( eventEventList, TlinkRefiner.INSTANCE );
+ // final Set<Map.Entry<Entity,Entity>> usedEntityEntities = new HashSet<Map.Entry<Entity, Entity>>();
+ // for ( final Relation eventEvent : eventEventList ) {
+ // final Map.Entry<Entity,Entity> entry = new AbstractMap.SimpleEntry<Entity,Entity>( eventEvent.getFirstEntity(),
+ // eventEvent.getSecondEntity() );
+ // if ( usedEntityEntities.contains( entry ) ) {
+ // continue;
+ // }
+ // final Attribute eeAttribute = eventEvent.getAttribute( "Relation Type" );
+ // if ( eeAttribute == null ) {
+ // System.out.print(" Equal ");
+ // } else {
+ // System.out.print(" " + eeAttribute.getValue() );
+ // }
+ // System.out.println( " " + eventEvent.toString() );
+ // usedEntityEntities.add( entry );
+ // }
+ // }
+ // usedEntities.add( entity );
+ // }
+ // } else {
+ // appendTimeSpan( sb, timeSpan, texts );
+ // }
+ // }
+ // sb.append( FOOTER );
+ // setText( sb.toString() );
+ // }
+ }
+ }
+
+
+ private class InfoPanelEventListener implements EventSelectionListener {
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void valueChanged( final EventSelectionEvent event ) {
+
+ }
+ }
+
+
+}
Added: ctakes/sandbox/timelanes/org/chboston/cnlp/timeline/debug/TimeSpanTreeModel.java
URL: http://svn.apache.org/viewvc/ctakes/sandbox/timelanes/org/chboston/cnlp/timeline/debug/TimeSpanTreeModel.java?rev=1660963&view=auto
==============================================================================
--- ctakes/sandbox/timelanes/org/chboston/cnlp/timeline/debug/TimeSpanTreeModel.java (added)
+++ ctakes/sandbox/timelanes/org/chboston/cnlp/timeline/debug/TimeSpanTreeModel.java Thu Feb 19 18:06:13 2015
@@ -0,0 +1,294 @@
+package org.chboston.cnlp.timeline.debug;
+
+import org.chboston.cnlp.nlp.annotation.annotation.AnnotationTextComparator;
+import org.chboston.cnlp.nlp.annotation.coreference.CoreferenceChain;
+import org.chboston.cnlp.nlp.annotation.entity.Entity;
+import org.chboston.cnlp.timeline.timeline.Timeline;
+import org.chboston.cnlp.timeline.timespan.plus.PointedTimeSpan;
+
+import javax.swing.tree.DefaultTreeModel;
+import javax.swing.tree.TreeNode;
+import java.util.*;
+import java.util.regex.Pattern;
+
+/**
+ * Author: SPF
+ * Affiliation: CHIP-NLP
+ * Date: 8/2/13
+ */
+public class TimeSpanTreeModel extends DefaultTreeModel {
+
+
+ public TimeSpanTreeModel( final Timeline timeline ) {
+ super( new TimelineRootNode( timeline ) );
+ }
+
+
+ static private class TimelineRootNode implements TreeNode {
+ final private String __name;
+ final private List<FunkyTimeSpanNode> __childNodes;
+
+ private TimelineRootNode( final Timeline timeline ) {
+ __name = timeline.getTitle();
+ __childNodes = new ArrayList<>();
+ for ( PointedTimeSpan timeSpanPlus : timeline ) {
+ __childNodes.add( new FunkyTimeSpanNode( timeline, this, timeSpanPlus ) );
+ }
+ }
+
+ public TreeNode getParent() {
+ return null;
+ }
+
+ public FunkyTimeSpanNode getChildAt( final int childIndex ) {
+ return __childNodes.get( childIndex );
+ }
+
+ public int getChildCount() {
+ return __childNodes.size();
+ }
+
+ public int getIndex( final TreeNode node ) {
+ if ( node instanceof FunkyTimeSpanNode ) {
+ return __childNodes.indexOf( node );
+ }
+ return -1;
+ }
+
+ public boolean getAllowsChildren() {
+ return false;
+ }
+
+ public boolean isLeaf() {
+ return false;
+ }
+
+ public Enumeration<FunkyTimeSpanNode> children() {
+ return new Enumeration<FunkyTimeSpanNode>() {
+ private int ___index = -1;
+
+ @Override
+ public boolean hasMoreElements() {
+ return ___index < getChildCount() - 2;
+ }
+
+ @Override
+ public FunkyTimeSpanNode nextElement() {
+ ___index++;
+ return getChildAt( ___index );
+ }
+ };
+ }
+
+ public String toString() {
+ return __name;
+ }
+
+ public Iterator<FunkyTimeSpanNode> iterator() {
+ return __childNodes.iterator();
+ }
+ }
+
+
+ // static public class TimeSpanNode implements TreeNode {
+ // private String __name = "Date?";
+ // final private TimeSpan __timeSpan;
+ // final private TimelineRootNode __parent;
+ // final private List<FunkyTimeSpanNode> __childNodes;
+ // private TimeSpanNode( final DefaultTimeline timeline, final TimelineRootNode timelineRootNode,
+ // final TimeSpan timeSpan, final List<TimeSpanPlus> timeSpans ) {
+ // __parent = timelineRootNode;
+ // __timeSpan = timeSpan;
+ // __name = timeSpan.toString();
+ // __childNodes = new ArrayList<FunkyTimeSpanNode>( timeSpans.size() );
+ // Collections.sort( timeSpans, TimeSpanPlusComparator.getInstance() );
+ // for ( TimeSpanPlus funkyTimeSpan : timeSpans ) {
+ // __childNodes.add( new FunkyTimeSpanNode( timeline, this, funkyTimeSpan ) );
+ // }
+ // }
+ // public TimeSpan getTimeSpan() {
+ // return __timeSpan;
+ // }
+ // public TimelineRootNode getParent() {
+ // return __parent;
+ // }
+ // public FunkyTimeSpanNode getChildAt( final int childIndex ) {
+ // return __childNodes.get( childIndex );
+ // }
+ // public int getChildCount() {
+ // return __childNodes.size();
+ // }
+ // public int getIndex( final TreeNode node ) {
+ // if ( node instanceof FunkyTimeSpanNode ) {
+ // return __childNodes.indexOf( node );
+ // }
+ // return -1;
+ // }
+ // public boolean getAllowsChildren() {
+ // return false;
+ // }
+ // public boolean isLeaf() {
+ // return false;
+ // }
+ // public Enumeration<FunkyTimeSpanNode> children() {
+ // return new Enumeration<FunkyTimeSpanNode>() {
+ // private int ___index = -1;
+ // @Override
+ // public boolean hasMoreElements() {
+ // return ___index < getChildCount()-2;
+ // }
+ //
+ // @Override
+ // public FunkyTimeSpanNode nextElement() {
+ // ___index++;
+ // return getChildAt( ___index );
+ // }
+ // };
+ // }
+ // public String toString() {
+ // return __name;
+ // }
+ // public Iterator<FunkyTimeSpanNode> iterator() {
+ // return __childNodes.iterator();
+ // }
+ // }
+
+
+ static public class FunkyTimeSpanNode implements TreeNode {
+ private String __name = "Overlaps";
+ final private TimelineRootNode __parent;
+ final private List<EntityNode> __childNodes;
+
+ private FunkyTimeSpanNode( final Timeline timeline, final TimelineRootNode timelineRootNode,
+ final PointedTimeSpan timeSpan ) {
+ // It makes sense to the reader to read "Timex relates to Event" in this tree format, so get reciprocal text
+ __parent = timelineRootNode;
+ __name = timeSpan.toString();
+ __childNodes = new ArrayList<>();
+ final Collection<Entity> entities = timeline.getEntities( timeSpan );
+ final List<Entity> entityList = new ArrayList<>( entities );
+ Collections.sort( entityList, AnnotationTextComparator.getInstance() );
+ for ( Entity entity : entityList ) {
+ __childNodes.add( new EntityNode( this, entity ) );
+ }
+ }
+
+ public List<Entity> getEvents() {
+ final List<Entity> eventList = new ArrayList<>();
+ for ( EntityNode node : __childNodes ) {
+ eventList.add( node.getEntity() );
+ }
+ return eventList;
+ }
+
+ public TimelineRootNode getParent() {
+ return __parent;
+ }
+
+ public EntityNode getChildAt( final int childIndex ) {
+ return __childNodes.get( childIndex );
+ }
+
+ public int getChildCount() {
+ return __childNodes.size();
+ }
+
+ public int getIndex( final TreeNode node ) {
+ if ( node instanceof EntityNode ) {
+ return __childNodes.indexOf( node );
+ }
+ return -1;
+ }
+
+ public boolean getAllowsChildren() {
+ return false;
+ }
+
+ public boolean isLeaf() {
+ return false;
+ }
+
+ public Enumeration<EntityNode> children() {
+ return new Enumeration<EntityNode>() {
+ private int ___index = -1;
+
+ @Override
+ public boolean hasMoreElements() {
+ return ___index < getChildCount() - 2;
+ }
+
+ @Override
+ public EntityNode nextElement() {
+ ___index++;
+ return getChildAt( ___index );
+ }
+ };
+ }
+
+ public String toString() {
+ return __name;
+ }
+
+ public Iterator<EntityNode> iterator() {
+ return __childNodes.iterator();
+ }
+ }
+
+
+ static public class EntityNode implements TreeNode {
+ static private final Pattern SPACE_PATTERN = Pattern.compile( "\\s\\s\\s+" );
+ private String __name;
+ private FunkyTimeSpanNode __parentNode;
+ final private Entity __entity;
+
+ private EntityNode( final FunkyTimeSpanNode rockinTimeSpan, final Entity entity ) {
+ __name = SPACE_PATTERN.matcher( entity.getSpannedText() ).replaceAll( " ... " ).trim().toLowerCase();
+ __parentNode = rockinTimeSpan;
+ __entity = entity;
+ if ( entity instanceof CoreferenceChain ) {
+ for ( Entity reference : (CoreferenceChain)entity ) {
+ __name = SPACE_PATTERN.matcher( reference.getSpannedText() ).replaceAll( " ... " ).trim().toLowerCase();
+ break;
+ }
+ }
+ }
+
+ public Entity getEntity() {
+ return __entity;
+ }
+
+ public TreeNode getChildAt( final int childIndex ) {
+ return null;
+ }
+
+ public int getChildCount() {
+ return 0;
+ }
+
+ public TreeNode getParent() {
+ return __parentNode;
+ }
+
+ public int getIndex( final TreeNode node ) {
+ return -1;
+ }
+
+ public boolean getAllowsChildren() {
+ return false;
+ }
+
+ public boolean isLeaf() {
+ return true;
+ }
+
+ public Enumeration children() {
+ return null;
+ }
+
+ public String toString() {
+ return __name;
+ }
+ }
+
+
+}