You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@uima.apache.org by sc...@apache.org on 2010/08/03 16:43:55 UTC

svn commit: r981902 - in /uima/uimaj/trunk/uimaj-core/src: main/java/org/apache/uima/analysis_engine/impl/ test/java/org/apache/uima/analysis_engine/impl/

Author: schor
Date: Tue Aug  3 14:43:55 2010
New Revision: 981902

URL: http://svn.apache.org/viewvc?rev=981902&view=rev
Log:
[UIMA-1840] Implement a valid equals method for resultSpecs - old method only tested 2 of the fields (was defaulting from a superclass). This equals method is used in the test case to compare actual and expected result specs.  Implement a hashcode that throws unsupported operation, since computing a true hashcode is very expensive and isn't done.
One test broke in AnalysisEngine_implTest - where it compared the ResultSpec sent in (which had a type with language x-unspecified), with the resultSpec sent to the last primitive (which had an output capability of "en" for that type) - which made the result spec there != to the one sent in (it was "narrowed" to "en").

Fixed the method that added a spec to the new resultSpec in intersection to work, given that the bitsets for languages are not necessarily compatible.

Added a test case to the ResultSpecTest and verified it failed before the fix, and worked afterwards.

Modified:
    uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/ResultSpecification_impl.java
    uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/AnalysisEngine_implTest.java
    uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/ResultSpecTest.java

Modified: uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/ResultSpecification_impl.java
URL: http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/ResultSpecification_impl.java?rev=981902&r1=981901&r2=981902&view=diff
==============================================================================
--- uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/ResultSpecification_impl.java (original)
+++ uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/ResultSpecification_impl.java Tue Aug  3 14:43:55 2010
@@ -379,9 +379,23 @@ public final class ResultSpecification_i
     setNeedsCompilation();
   }
   
-  private void addClonedToF_Languages(ToF_Languages tofLangs) {
-    ToF_Languages cloned = (ToF_Languages) tofLangs.clone();
-    name2tof_langs.put(cloned.tof.getName(), cloned);
+  /**
+   * Create an entry in this result spec from the type or feature and its languages
+   * @param tofLangs
+   */
+  private void addClonedToF_Languages(ToF_Languages tofLangs, ResultSpecification_impl rs) {
+    List<String> languages = new ArrayList<String>();
+    BitSet bs = tofLangs.languages;
+    for (Map.Entry<String, Integer> si : rs.lang2int.entrySet()) {
+      if (bs.get(si.getValue())) {
+        languages.add(si.getKey());
+      }
+    }
+    
+    ToF_Languages n = new ToF_Languages(
+        tofLangs.tof, 
+        languages.toArray(new String[languages.size()]));
+    name2tof_langs.put(n.tof.getName(), n);
     setNeedsCompilation();
   }
 
@@ -884,11 +898,11 @@ public final class ResultSpecification_i
       // Type or Feature is in both; intersect the languages
       // if either has language x-unspecified, use the other's language spec.
       if (rs1Langs.languages.get(ResultSpecification_impl.UNSPECIFIED_LANGUAGE_INDEX)) {
-        newRs.addClonedToF_Languages(rs2Langs);
+        newRs.addClonedToF_Languages(rs2Langs, rs2);
         continue;
       }
       if (rs2Langs.languages.get(ResultSpecification_impl.UNSPECIFIED_LANGUAGE_INDEX)) {
-        newRs.addClonedToF_Languages(rs1Langs);
+        newRs.addClonedToF_Languages(rs1Langs, rs1);
         continue;
       }
 
@@ -964,4 +978,76 @@ public final class ResultSpecification_i
     }
     return rsltLangs;
   }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (this == obj) {
+      return true;
+    }
+    if (!super.equals(obj)) {
+      return false;
+    }
+    if (getClass() != obj.getClass()) {
+      return false;
+    }
+    ResultSpecification_impl other = (ResultSpecification_impl) obj;
+    if (lang2int == null) {
+      if (other.lang2int != null) {
+        return false;
+      }
+    }
+    if (mTypeSystem == null) {
+      if (other.mTypeSystem != null) {
+        return false;
+      }
+    } else if (mTypeSystem != other.mTypeSystem) {
+      return false;
+    }
+    if (name2tof_langs == null) {
+      if (other.name2tof_langs != null) {
+        return false;
+      }
+    } 
+    this.compileIfNeeded();
+    other.compileIfNeeded();
+    
+    if (withSubtypesName2tof_langs == null) {
+      if (other.withSubtypesName2tof_langs != null) {
+        return false;
+      }
+    }
+    
+    if (availName2tof_langs().size() != other.availName2tof_langs().size()) {
+      return false;
+    }
+    
+    // iterate over all types and features in this 
+    for (Map.Entry<String, ToF_Languages> item : availName2tof_langs().entrySet()) {
+      String tof = item.getKey();
+      ToF_Languages toflangs = item.getValue();
+      ToF_Languages otherToflangs = other.availName2tof_langs().get(tof);
+      BitSet thisBs = toflangs.languages;
+      BitSet otherBs = otherToflangs.languages;
+      if (thisBs.cardinality() != otherBs.cardinality()) {
+        return false;
+      }
+      for (Map.Entry<String, Integer>l2ie : lang2int.entrySet()) {
+        if (thisBs.get(l2ie.getValue())) {
+          if (!otherBs.get(other.lang2int.get(l2ie.getKey()))) {
+            return false;
+          }
+        }
+      }
+    }
+    
+    return true;
+  }
+  
+  /**
+   * Hash code not implemented
+   * @return
+   */
+  public int hashcode() {
+    throw new UnsupportedOperationException();
+  }
 }

Modified: uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/AnalysisEngine_implTest.java
URL: http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/AnalysisEngine_implTest.java?rev=981902&r1=981901&r2=981902&view=diff
==============================================================================
--- uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/AnalysisEngine_implTest.java (original)
+++ uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/AnalysisEngine_implTest.java Tue Aug  3 14:43:55 2010
@@ -360,7 +360,8 @@ public class AnalysisEngine_implTest ext
       AnalysisEngineDescription aggWithCcDesc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription(
               new XMLInputSource(JUnitExtension
                       .getFile("TextAnalysisEngineImplTest/AggregateTaeWithCasConsumer.xml")));
-      _testProcess(aggWithCcDesc);      
+      
+      _testProcess(aggWithCcDesc, new String[] {"en"});      
       // test that CAS Consumer ran
       if (null == outFile) {
         outFile = JUnitExtension.getFile("CpmOutput.txt");
@@ -386,34 +387,61 @@ public class AnalysisEngine_implTest ext
   }
 
   /**
-   * Auxilliary method used by testProcess()
+   * Auxiliary method used by testProcess()
    * 
    * @param aTaeDesc
    *          description of TextAnalysisEngine to test
    */
   protected void _testProcess(AnalysisEngineDescription aTaeDesc) throws UIMAException {
-    // create and initialize TextAnalysisEngine
     AnalysisEngine ae = UIMAFramework.produceAnalysisEngine(aTaeDesc);
+    CAS tcas = ae.newCAS();
+
+    // process(CAS,ResultSpecification)
+    ResultSpecification resultSpec = new ResultSpecification_impl(tcas.getTypeSystem());
+    resultSpec.addResultType("NamedEntity", true);
+
+    _testProcessInner(ae, tcas, resultSpec, resultSpec);
+  }
+  
+  protected void _testProcess(AnalysisEngineDescription aTaeDesc, String[] languages) throws UIMAException {
+    AnalysisEngine ae = UIMAFramework.produceAnalysisEngine(aTaeDesc);
+    CAS tcas = ae.newCAS();
+
+    // process(CAS,ResultSpecification)
+    ResultSpecification resultSpec = new ResultSpecification_impl(tcas.getTypeSystem());
+    resultSpec.addResultType("NamedEntity", true);
+    
+    ResultSpecification expectedLastResultSpec = new ResultSpecification_impl(tcas.getTypeSystem());
+    expectedLastResultSpec.addResultType("NamedEntity", true, languages);
+
+    _testProcessInner(ae, tcas, resultSpec, expectedLastResultSpec);
+  }
+  
+  /**
+   * Auxiliary method used by testProcess()
+   * 
+   * @param aTaeDesc
+   *          description of TextAnalysisEngine to test
+   */
+  protected void _testProcessInner(AnalysisEngine ae, CAS tcas, ResultSpecification resultSpec,
+      ResultSpecification expectedLastResultSpec) throws UIMAException {
+    // create and initialize TextAnalysisEngine
 
     // Test each form of the process method. When TestAnnotator executes, it
     // stores in static fields the document text and the ResultSpecification.
     // We use thse to make sure the information propogates correctly to the annotator.
 
     // process(CAS)
-    CAS tcas = ae.newCAS();
     tcas.setDocumentText("new test");
     ae.process(tcas);
     assertEquals("new test", TestAnnotator.lastDocument);
     tcas.reset();
 
     // process(CAS,ResultSpecification)
-    ResultSpecification resultSpec = new ResultSpecification_impl(tcas.getTypeSystem());
-    resultSpec.addResultType("NamedEntity", true);
-
     tcas.setDocumentText("testing...");
     ae.process(tcas, resultSpec);
     assertEquals("testing...", TestAnnotator.lastDocument);
-    assertEquals(resultSpec, TestAnnotator.lastResultSpec);
+    assertEquals(expectedLastResultSpec, TestAnnotator.lastResultSpec);
     tcas.reset();
     ae.destroy();
   }

Modified: uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/ResultSpecTest.java
URL: http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/ResultSpecTest.java?rev=981902&r1=981901&r2=981902&view=diff
==============================================================================
--- uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/ResultSpecTest.java (original)
+++ uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/ResultSpecTest.java Tue Aug  3 14:43:55 2010
@@ -40,6 +40,7 @@ public class ResultSpecTest extends Test
   private static final String EN = "en";
   private static final String X  = "x-unspecified";
   private static final String EN_US = "en-us";
+  private static final String PTBR = "pt-br";
   private static final String I = "I";  // split designator
   
   /**
@@ -60,6 +61,9 @@ public class ResultSpecTest extends Test
     checkl(X, EN, I, EN, X, I, X);
     checkl(X, EN, I, EN, I, EN);
     checkl(EN, EN_US, I, X, I, EN, EN_US);
+    
+    checkl(X, PTBR, I, EN, I, EN);
+    checkl(PTBR, I, EN, I, null);
   }
   
   private void checkl(String... args) {
@@ -73,7 +77,9 @@ public class ResultSpecTest extends Test
       if (args[i] == I) {
         tgtI ++;
       } else {
-        tgts[tgtI].add(args[i]);            
+        if (args[i] != null) {
+          tgts[tgtI].add(args[i]);    
+        }
       }
     }
     String[] rs1langs = rs1List.toArray(new String[rs1List.size()]);
@@ -84,14 +90,28 @@ public class ResultSpecTest extends Test
     ResultSpecification_impl rs2 = new ResultSpecification_impl();
     ResultSpecification_impl rsE = new ResultSpecification_impl(); //expected
     
-    rs1.addResultType("T1", true, rs1langs);
-    rs2.addResultType("T1", true, rs2langs);
-    rsE.addResultType("T1", true, explangs);
+    addResultTypeOneAtATime(rs1, rs1langs);
+    addResultTypeOneAtATime(rs2, rs2langs);
+    addResultTypeOneAtATime(rsE, explangs);
     
     ResultSpecification_impl rsQ = ResultSpecification_impl.intersect(rs1, rs2);
     assertTrue(rsQ.equals(rsE));
   }
   
+  // we do this to avoid language normalization from collapsing x-unspecified 
+  // plus other languages into just x-unspecified
+  private void addResultTypeOneAtATime(ResultSpecification_impl rs, String[] languages) {
+    if (languages.length == 0) {
+      return;
+    }
+    if (languages.length == 1) {
+      rs.addResultType("T1", true, languages);
+    } else {
+      for (int i = 0; i < languages.length; i++) {
+        rs.addResultType("T1", true, new String[]{languages[i]});
+      }
+    } 
+  }
   public void testComputeAnalysisComponentResultSpec() throws Exception {
     try {
       AnalysisEngineDescription aeDesc = UIMAFramework.getXMLParser()