You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@uima.apache.org by al...@apache.org on 2006/12/21 22:35:25 UTC

svn commit: r489467 - in /incubator/uima/uimaj/trunk/uimaj-tools/src/main/java/org/apache/uima: klt/ tools/viewer/CasAnnotationViewer.java tools/viewer/EntityResolver.java

Author: alally
Date: Thu Dec 21 13:35:24 2006
New Revision: 489467

URL: http://svn.apache.org/viewvc?view=rev&rev=489467
Log:
Made CasAnnotationViewer's entity mode accept a pluggable 
EntityResolver object, and removed dependency on IBM-specific
type system.

UIMA-135: http://issues.apache.org/jira/browse/UIMA-135

Added:
    incubator/uima/uimaj/trunk/uimaj-tools/src/main/java/org/apache/uima/tools/viewer/EntityResolver.java
Removed:
    incubator/uima/uimaj/trunk/uimaj-tools/src/main/java/org/apache/uima/klt/
Modified:
    incubator/uima/uimaj/trunk/uimaj-tools/src/main/java/org/apache/uima/tools/viewer/CasAnnotationViewer.java

Modified: incubator/uima/uimaj/trunk/uimaj-tools/src/main/java/org/apache/uima/tools/viewer/CasAnnotationViewer.java
URL: http://svn.apache.org/viewvc/incubator/uima/uimaj/trunk/uimaj-tools/src/main/java/org/apache/uima/tools/viewer/CasAnnotationViewer.java?view=diff&rev=489467&r1=489466&r2=489467
==============================================================================
--- incubator/uima/uimaj/trunk/uimaj-tools/src/main/java/org/apache/uima/tools/viewer/CasAnnotationViewer.java (original)
+++ incubator/uima/uimaj/trunk/uimaj-tools/src/main/java/org/apache/uima/tools/viewer/CasAnnotationViewer.java Thu Dec 21 13:35:24 2006
@@ -98,10 +98,7 @@
 import org.apache.uima.cas.text.AnnotationFS;
 import org.apache.uima.cas.text.TCAS;
 import org.apache.uima.jcas.impl.JCas;
-import org.apache.uima.klt.Entity;
-import org.apache.uima.klt.EntityAnnotation;
-import org.apache.uima.klt.HasOccurrence;
-import org.apache.uima.klt.Link;
+import org.apache.uima.jcas.tcas.Annotation;
 
 /**
  * A Swing component that displays annotations in a text pane with highlighting. There is also a
@@ -217,7 +214,7 @@
 
   private Set mHiddenFeatureNames = new HashSet();
 
-  private Boolean mEntityViewEnabled; // null if user has made no choice
+  private boolean mEntityViewEnabled; 
 
   private short mViewMode = MODE_ANNOTATIONS;
 
@@ -268,6 +265,8 @@
 
   private JComboBox sofaSelectionComboBox;
 
+  private EntityResolver mEntityResolver = new DefaultEntityResolver();
+
   /**
    * Creates a CAS Annotation Viewer.
    */
@@ -480,19 +479,28 @@
 
   /**
    * Configures whether the viewer will allow the user to switch to "Entity" view, which highlight
-   * entities rather than annotations. Entity view mode is only useful if the CAS contains instances
-   * of org.apache.uima.klt.Entity.
-   * <p>
-   * NOTE: if this method is not called, the default is to display entities if and only if the
-   * org.apache.uima.klt.Entity type is present in the type system.
+   * entities rather than annotations.  Entity mode is typically only useful if the
+   * {@link #setEntityResolver(EntityResolver)} method has been called with a user-supplied
+   * class that can determine which annotations refer to the same entity.
    * 
    * @param aDisplayEntities
-   *          true to enable entity viewing mode, false to allow annotation viewing only
+   *          true to enable entity viewing mode, false to allow annotation viewing only.
+   *          The default is false.
    */
   public void setEntityViewEnabled(boolean aEnabled) {
-    mEntityViewEnabled = new Boolean(aEnabled);
+    mEntityViewEnabled = aEnabled;
     this.viewModePanel.setVisible(aEnabled);
   }
+  
+  /**
+   * Sets the {@link EntityResolver} to use when the viewer is in entity mode.
+   * Entity mode must be turned on using the {@link #setEntityViewEnabled(boolean)} method.
+   * @param aEntityResolver user-supplied class that can determine which annotations correspond
+   *   to the same entity.
+   */
+  public void setEntityResolver(EntityResolver aEntityResolver) {
+    mEntityResolver = aEntityResolver;
+  }
 
   /**
    * Sets whether colors will be consistent in all documents viewed using this viewer. If set to
@@ -576,13 +584,8 @@
     mBoldfaceKeywords = new String[0];
     mBoldfaceSpans = new int[0];
 
-    // enable entity view if the org.apache.uima.klt.EntityAnnotation type is
-    // present (if user has not called setEntityViewEnalbed)
-    if (mEntityViewEnabled == null) {
-      boolean entityTypeExists = mCAS.getTypeSystem().getType(
-              "org.apache.uima.klt.EntityAnnotation") != null;
-      this.viewModePanel.setVisible(entityTypeExists);
-    }
+    // enable or disable entity view depending on user's choice 
+    this.viewModePanel.setVisible(mEntityViewEnabled);
 
     // Populate sofa combo box with the names of all text Sofas in the CAS
     sofaSelectionComboBox.removeAllItems();
@@ -983,7 +986,8 @@
       throw new RuntimeException(e);
     }
 
-    // Iterate over EntityAnnotations using JCAS
+    // Iterate over EntityAnnotations using JCAS, because the EntityResolver interface
+    // uses JCAS as a convenience to the user.
     JCas jcas;
     try {
       // NOTE: for a large type system, this can take a few seconds, which results in a
@@ -992,54 +996,37 @@
     } catch (CASException e) {
       throw new RuntimeException(e);
     }
-    FSIterator iter = jcas.getJFSIndexRepository().getAnnotationIndex(EntityAnnotation.type)
-            .iterator();
+    FSIterator iter = jcas.getJFSIndexRepository().getAnnotationIndex().iterator();
     while (iter.isValid()) {
-      EntityAnnotation entityAnnot = (EntityAnnotation) iter.get();
+      Annotation annot = (Annotation) iter.get();
       iter.moveToNext();
 
-      // find out what entity this annotations represents
-      LinkedList entityList = Link.getFromValues(entityAnnot.getLinks(), HasOccurrence.class);
-      if (entityList.isEmpty()) {
-        continue;
-      }
-      // currently assume only one Entity per annotation
-      Entity entity = (Entity) entityList.getFirst();
+      // find out what entity this annotation represents
+      String entityCanonicalForm = mEntityResolver.getCanonicalForm(annot);
 
+      //if not an entity, skip it
+      if (entityCanonicalForm == null)
+        continue;
+      
       // have we seen this entity before?
-      JCheckBox checkbox = (JCheckBox) mEntityToCheckboxMap.get(entity);
+      JCheckBox checkbox = (JCheckBox) mEntityToCheckboxMap.get(entityCanonicalForm);
       if (checkbox == null) {
         // assign next available color
         Color c = COLORS[mEntityToCheckboxMap.size() % COLORS.length];
         // add checkbox
-        String label = entity.getCanonicalForm();
-        if (label == null) // canonical form not known
-        {
-          // initially set label to this occurrence; we will later set it to the longest
-          // occurrence
-          label = entityAnnot.getCoveredText();
-        }
-        checkbox = new JCheckBox(label, true);
-        checkbox.setToolTipText(label);
+        checkbox = new JCheckBox(entityCanonicalForm, true);
+        checkbox.setToolTipText(entityCanonicalForm);
         checkbox.addActionListener(this);
         checkbox.setBackground(c);
         entityCheckboxPanel.add(checkbox);
         // add to (Entity, Checkbox) map
-        mEntityToCheckboxMap.put(entity, checkbox);
-      } else {
-        // ensure longest occurrence used as label if canonical form not known
-        if (entity.getCanonicalForm() == null) {
-          String thisOccurrence = entityAnnot.getCoveredText();
-          if (thisOccurrence.length() > checkbox.getText().length()) {
-            checkbox.setText(thisOccurrence);
-          }
-        }
+        mEntityToCheckboxMap.put(entityCanonicalForm, checkbox);
       }
 
       // if checkbox is checked, assign color to text
       if (checkbox.isSelected()) {
-        int begin = entityAnnot.getBegin();
-        int end = entityAnnot.getEnd();
+        int begin = annot.getBegin();
+        int end = annot.getEnd();
         // be careful of 0-length annotation. If we try to set background color when there
         // is no selection, it will set the input text style, which is not what we want.
         if (begin != end) {
@@ -1718,5 +1705,20 @@
       return 10;
     }
 
+  }
+  
+  /**
+   * Trivial entity resolver that's applied if the user turns on entity mode without
+   * specifying their own entity resolver.  Returns the covered text as the canonical form.
+   */
+  static class DefaultEntityResolver implements EntityResolver {
+
+    /* (non-Javadoc)
+     * @see org.apache.uima.tools.viewer.EntityResolver#getCanonicalForm(org.apache.uima.jcas.tcas.Annotation)
+     */
+    public String getCanonicalForm(Annotation aAnnotation) {
+      return aAnnotation.getCoveredText();
+    }
+    
   }
 }

Added: incubator/uima/uimaj/trunk/uimaj-tools/src/main/java/org/apache/uima/tools/viewer/EntityResolver.java
URL: http://svn.apache.org/viewvc/incubator/uima/uimaj/trunk/uimaj-tools/src/main/java/org/apache/uima/tools/viewer/EntityResolver.java?view=auto&rev=489467
==============================================================================
--- incubator/uima/uimaj/trunk/uimaj-tools/src/main/java/org/apache/uima/tools/viewer/EntityResolver.java (added)
+++ incubator/uima/uimaj/trunk/uimaj-tools/src/main/java/org/apache/uima/tools/viewer/EntityResolver.java Thu Dec 21 13:35:24 2006
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.uima.tools.viewer;
+
+import org.apache.uima.jcas.tcas.Annotation;
+
+/**
+ * Pluggable interface that supports Entity View mode in the CasAnnotationViewer. Users implement
+ * this interface with logic that for their particular type system can return the canonical form of
+ * an annotation in the CAS.
+ * <p>
+ * In the viewer, all annotations whose canonical form strings are <code>equal</code> will be
+ * displayed in the same color, and the canonical form will be shown in the legend.
+ */
+public interface EntityResolver {
+
+  /**
+   * Returns the canonical form String for an annotation.
+   * <p>
+   * For two annotations that refer to the same Entity, this should return canonical form strings that
+   * are <code>equal</code>.
+   * <p>
+   * If the annotation does not represent an entity at all, <code>null</code> should be returned.
+   * 
+   * @param aAnnotation
+   *          the annotation to resolve
+   * 
+   * @return the canonical form of the annotation, null if the annotation does not represent an
+   *         entity
+   */
+  String getCanonicalForm(Annotation aAnnotation);
+}