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 2009/09/15 00:54:47 UTC

svn commit: r814897 - in /incubator/uima/uimaj/trunk/uimaj-core/src: main/java/org/apache/uima/cas/ main/java/org/apache/uima/cas/impl/ test/java/org/apache/uima/cas/impl/ test/java/org/apache/uima/cas/test/

Author: schor
Date: Mon Sep 14 22:54:47 2009
New Revision: 814897

URL: http://svn.apache.org/viewvc?rev=814897&view=rev
Log:
[UIMA-1569] applied patch and several adjustments to the patch, including comments to the code.

Modified:
    incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/Marker.java
    incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/CASImpl.java
    incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/CASSerializer.java
    incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/MarkerImpl.java
    incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/Serialization.java
    incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/XmiCasSerializer.java
    incubator/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/cas/impl/XmiCasDeserializerTest.java
    incubator/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/cas/test/SerializationReinitTest.java

Modified: incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/Marker.java
URL: http://svn.apache.org/viewvc/incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/Marker.java?rev=814897&r1=814896&r2=814897&view=diff
==============================================================================
--- incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/Marker.java (original)
+++ incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/Marker.java Mon Sep 14 22:54:47 2009
@@ -40,6 +40,14 @@
   * @return boolean 
   */
  boolean isModified(FeatureStructure fs);
+ 
+ /**
+  * Return true if the Marker is still valid.
+  * A Marker becomes invalid when the <code>CAS</code> from which it was obtained
+  * is reset.
+  * @return
+  */
+ boolean isValid();
 
 }
 

Modified: incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/CASImpl.java
URL: http://svn.apache.org/viewvc/incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/CASImpl.java?rev=814897&r1=814896&r2=814897&view=diff
==============================================================================
--- incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/CASImpl.java (original)
+++ incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/CASImpl.java Mon Sep 14 22:54:47 2009
@@ -211,6 +211,17 @@
 
     private FSGenerator[] localFsGenerators;
     
+    /**
+     * This tracks the changes for delta cas
+     * May also in the future support Journaling by component,
+     * allowing determination of which component in a flow 
+     * created/updated a FeatureStructure (not implmented)
+     * 
+     * TrackingMarkers are held on to by things outside of the 
+     * Cas, to support switching from one tracking marker to 
+     * another (currently not used, but designed to support
+     * Component Journaling).
+     */
     private MarkerImpl trackingMark;
     
     private IntVector modifiedPreexistingFSs;
@@ -222,6 +233,13 @@
     private IntVector modifiedShortHeapCells;
     
     private IntVector modifiedLongHeapCells;
+    
+    /**
+     * This list currently only contains at most 1 element.
+     * If Journaling is implemented, it may contain an
+     * element per component being journaled.
+     */
+    private ArrayList<MarkerImpl> trackingMarkList;
 
     private SharedViewData(boolean useFSCache) {
       this.useFSCache = useFSCache;
@@ -333,12 +351,7 @@
     this.svd.initialSofaCreated = false;
     this.svd.viewCount = 0;
     
-    this.svd.trackingMark = null;
-    this.svd.modifiedPreexistingFSs = null; 
-    this.svd.modifiedFSHeapCells = null;
-    this.svd.modifiedByteHeapCells = null;
-    this.svd.modifiedShortHeapCells = null;
-    this.svd.modifiedLongHeapCells = null;
+    clearTrackingMarks();
   }
 
   /**
@@ -926,13 +939,7 @@
     if (this.jcas != null) {
       JCasImpl.clearData(this);
     }
-    
-    this.svd.trackingMark = null;
-    this.svd.modifiedPreexistingFSs = null;
-    this.svd.modifiedFSHeapCells = null;
-    this.svd.modifiedByteHeapCells = null;
-    this.svd.modifiedShortHeapCells = null;
-    this.svd.modifiedLongHeapCells = null;
+    clearTrackingMarks();
   }
 
   /**
@@ -1087,12 +1094,27 @@
     // to.
     this.jcas = null;
     // this.sofa2jcasMap.clear();
+    
+    clearTrackingMarks();
+  }
+  
+  private void clearTrackingMarks() {
+    // resets all markers that might be held by things outside the Cas
+    // Currently (2009) this list has a max of 1 element
+    // Future impl may have one element per component for component Journaling
+    if (this.svd.trackingMarkList != null) {
+      for (int i=0; i < this.svd.trackingMarkList.size(); i++) {
+        this.svd.trackingMarkList.get(i).isValid = false;
+      }
+    }
+
     this.svd.trackingMark = null;
     this.svd.modifiedPreexistingFSs = null;
     this.svd.modifiedFSHeapCells = null;
     this.svd.modifiedByteHeapCells = null;
     this.svd.modifiedShortHeapCells = null;
     this.svd.modifiedLongHeapCells = null;
+    this.svd.trackingMarkList = null;     
   }
 
   void reinit(int[] heapMetadata, int[] heapArray, String[] stringTable, int[] fsIndex,
@@ -4241,34 +4263,51 @@
     return this.isUsedJcasCache;
   }
 
+  /**
+   * The current implementation only supports 1 marker call per 
+   * CAS.  Subsequent calls will throw an error.
+   * 
+   * The design is intended to support (at some future point)
+   * multiple markers; for this to work, the intent is to 
+   * extend the MarkerImpl to keep track of indexes into
+   * these IntVectors specifying where that marker starts/ends.
+   */
   public Marker createMarker() {
     if (!this.svd.flushEnabled) {
 	  throw new CASAdminException(CASAdminException.FLUSH_DISABLED);
-	}
-	this.svd.trackingMark = new MarkerImpl(this.getHeap().getNextId(), 
-			this.getStringHeap().getSize(),
-			this.getByteHeap().getSize(),
-			this.getShortHeap().getSize(),
-			this.getLongHeap().getSize(),
-			this);
-	if (this.svd.modifiedPreexistingFSs == null) {
-	  this.svd.modifiedPreexistingFSs = new IntVector();
-	}
-	if (this.svd.modifiedFSHeapCells == null) {
-	  this.svd.modifiedFSHeapCells = new IntVector();
-	}
-	if (this.svd.modifiedByteHeapCells == null) {
-      this.svd.modifiedByteHeapCells = new IntVector();
-	}
-	if (this.svd.modifiedShortHeapCells == null) { 
-      this.svd.modifiedShortHeapCells = new IntVector();
-	}
-	if (this.svd.modifiedLongHeapCells == null) {
-      this.svd.modifiedLongHeapCells = new IntVector();
-	}
-	return this.svd.trackingMark;
+  	}
+  	this.svd.trackingMark = new MarkerImpl(this.getHeap().getNextId(), 
+  			this.getStringHeap().getSize(),
+  			this.getByteHeap().getSize(),
+  			this.getShortHeap().getSize(),
+  			this.getLongHeap().getSize(),
+  			this);
+  	if (this.svd.modifiedPreexistingFSs == null) {
+  	  this.svd.modifiedPreexistingFSs = new IntVector();
+  	} else {errorMultipleMarkers();}
+  	if (this.svd.modifiedFSHeapCells == null) {
+  	  this.svd.modifiedFSHeapCells = new IntVector();
+  	} else {errorMultipleMarkers();}
+  	if (this.svd.modifiedByteHeapCells == null) {
+        this.svd.modifiedByteHeapCells = new IntVector();
+  	} else {errorMultipleMarkers();}
+  	if (this.svd.modifiedShortHeapCells == null) { 
+        this.svd.modifiedShortHeapCells = new IntVector();
+  	} else {errorMultipleMarkers();}
+  	if (this.svd.modifiedLongHeapCells == null) {
+        this.svd.modifiedLongHeapCells = new IntVector();
+  	} else {errorMultipleMarkers();}
+  	if (this.svd.trackingMarkList == null) {
+  	  this.svd.trackingMarkList = new ArrayList<MarkerImpl>();
+  	} else {errorMultipleMarkers();}
+  	this.svd.trackingMarkList.add(this.svd.trackingMark);
+  	return this.svd.trackingMark;
   }
 
+  private void errorMultipleMarkers() {
+    throw new CASRuntimeException(CASRuntimeException.MULTIPLE_CREATE_MARKER);
+  }
+  
   private void logFSUpdate(int fsaddr, int position, ModifiedHeap whichheap, int howmany) {
 	if (this.svd.trackingMark != null && !this.svd.trackingMark.isNew(fsaddr)) {
 	  //log the FS

Modified: incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/CASSerializer.java
URL: http://svn.apache.org/viewvc/incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/CASSerializer.java?rev=814897&r1=814896&r2=814897&view=diff
==============================================================================
--- incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/CASSerializer.java (original)
+++ incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/CASSerializer.java Mon Sep 14 22:54:47 2009
@@ -315,6 +315,11 @@
   public void addCAS(CASImpl cas, OutputStream ostream, Marker trackingMark) {
 
     try {
+      if (!trackingMark.isValid() ) {
+        CASRuntimeException exception = new CASRuntimeException(
+    		          CASRuntimeException.INVALID_MARKER, new String[] { "Invalid Marker." });
+        throw exception;
+      }
       MarkerImpl mark = (MarkerImpl) trackingMark;
       DataOutputStream dos = new DataOutputStream(ostream);
 

Modified: incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/MarkerImpl.java
URL: http://svn.apache.org/viewvc/incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/MarkerImpl.java?rev=814897&r1=814896&r2=814897&view=diff
==============================================================================
--- incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/MarkerImpl.java (original)
+++ incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/MarkerImpl.java Mon Sep 14 22:54:47 2009
@@ -23,6 +23,18 @@
 import org.apache.uima.cas.FeatureStructure;
 import org.apache.uima.cas.Marker;
 
+/**
+ * A MarkerImpl holds a high-water "mark" in the CAS,
+ * for all views.
+ * Typically, one is obtained via the createMarker call
+ * on a CAS.
+ * 
+ * Currently only one marker is used per CAS.
+ * The Marker enables testing on each CAS update if the
+ * update is "below" or "above" the marker - this is
+ * used for implementing delta serialization, in which
+ * only the changed data is sent.
+ */
 public class MarkerImpl implements Marker {
 	
   protected int nextFSId;    //next FS addr
@@ -30,6 +42,7 @@
   protected int nextByteHeapAddr;
   protected int nextShortHeapAddr;
   protected int nextLongHeapAddr;
+  protected boolean isValid;
   
   CASImpl cas;
 
@@ -42,39 +55,45 @@
     this.nextShortHeapAddr = nextShortHeapAddr;
     this.nextLongHeapAddr = nextLongHeapAddr;
     this.cas = cas;
+    this.isValid = true;
   }
 
   public boolean isNew(FeatureStructure fs) {
-	//check if same CAS instance
-	//TODO: define a CASRuntimeException
-	if (((FeatureStructureImpl) fs).getCASImpl() != this.cas) {
-		CASRuntimeException e = new CASRuntimeException(
-		          CASRuntimeException.CAS_MISMATCH,
-		          new String[] { "FS and Marker are not from the same CAS." });
-		      throw e;
-	}
-	return isNew( ((FeatureStructureImpl) fs).getAddress());
+  	//check if same CAS instance
+  	//TODO: define a CASRuntimeException
+  	if (!isValid || ((FeatureStructureImpl) fs).getCASImpl() != this.cas) {
+  		CASRuntimeException e = new CASRuntimeException(
+  		          CASRuntimeException.CAS_MISMATCH,
+  		          new String[] { "FS and Marker are not from the same CAS." });
+  		      throw e;
+  	}
+  	return isNew( ((FeatureStructureImpl) fs).getAddress());
   }
 
   public boolean isModified(FeatureStructure fs) {
-	if (((FeatureStructureImpl) fs).getCASImpl() != this.cas) {
+	if (!isValid || ((FeatureStructureImpl) fs).getCASImpl() != this.cas) {
 		CASRuntimeException e = new CASRuntimeException(
 		          CASRuntimeException.CAS_MISMATCH,
 		          new String[] { "FS and Marker are not from the same CAS." });
 		      throw e;
 	}
 	int addr = ((FeatureStructureImpl) fs).getAddress();
-	return isModified(addr);
+	  return isModified(addr);
   }
   
   boolean isNew(int addr) {
-	return (addr == nextFSId || addr > nextFSId);
+	  return (addr >= nextFSId);
   }
   
   boolean isModified(int addr) {
-	if (isNew(addr)) {
-		return false;
-    }
-	return this.cas.getModifiedFSList().contains(addr);
+  	if (isNew(addr)) {
+  		return false;
+      }
+  	return this.cas.getModifiedFSList().contains(addr);
+  }
+  
+  public boolean isValid() {
+    return isValid;
   }
+  
 }

Modified: incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/Serialization.java
URL: http://svn.apache.org/viewvc/incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/Serialization.java?rev=814897&r1=814896&r2=814897&view=diff
==============================================================================
--- incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/Serialization.java (original)
+++ incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/Serialization.java Mon Sep 14 22:54:47 2009
@@ -23,6 +23,7 @@
 import java.io.OutputStream;
 
 import org.apache.uima.cas.CAS;
+import org.apache.uima.cas.CASRuntimeException;
 import org.apache.uima.cas.Marker;
 import org.apache.uima.cas.admin.CASMgr;
 
@@ -86,8 +87,11 @@
    * @param mark
    */
   public static void serializeCAS(CAS cas, OutputStream ostream, Marker mark) {
-	    CASSerializer ser = new CASSerializer();
-	    ser.addCAS((CASImpl) cas, ostream, mark);
+  	if (!mark.isValid() ) {
+  	  throw new CASRuntimeException(CASRuntimeException.INVALID_MARKER);
+  	}
+  	CASSerializer ser = new CASSerializer();
+  	ser.addCAS((CASImpl) cas, ostream, mark);
   }
 
 }

Modified: incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/XmiCasSerializer.java
URL: http://svn.apache.org/viewvc/incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/XmiCasSerializer.java?rev=814897&r1=814896&r2=814897&view=diff
==============================================================================
--- incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/XmiCasSerializer.java (original)
+++ incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/XmiCasSerializer.java Mon Sep 14 22:54:47 2009
@@ -33,6 +33,7 @@
 import org.apache.uima.UimaContext;
 import org.apache.uima.cas.ByteArrayFS;
 import org.apache.uima.cas.CAS;
+import org.apache.uima.cas.CASRuntimeException;
 import org.apache.uima.cas.CommonArrayFS;
 import org.apache.uima.cas.FSIndex;
 import org.apache.uima.cas.FeatureStructure;
@@ -192,7 +193,15 @@
       this.arrayAndListFSs = new IntRedBlackTree();
       this.sharedData = sharedData;
       this.isFiltering = filterTypeSystem != null && filterTypeSystem != cas.getTypeSystemImpl();
-      this.marker = marker;
+      if (marker != null ) {
+      	if (marker.isValid())
+          this.marker = marker;
+        else {
+    	    CASRuntimeException exception = new CASRuntimeException(
+    	          CASRuntimeException.INVALID_MARKER, new String[] { "Invalid Marker." });
+    	    throw exception;
+        }
+      }
       this.isDelta = false;
       if (this.marker != null) this.isDelta = true;
     }
@@ -1534,6 +1543,7 @@
    */
   public void serialize(CAS cas, ContentHandler contentHandler, ErrorHandler errorHandler,
           XmiSerializationSharedData sharedData, Marker marker) throws SAXException {
+	  
     contentHandler.startDocument();
     XmiCasDocSerializer ser = new XmiCasDocSerializer(contentHandler, errorHandler, ((CASImpl) cas)
             .getBaseCAS(), sharedData, (MarkerImpl) marker);

Modified: incubator/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/cas/impl/XmiCasDeserializerTest.java
URL: http://svn.apache.org/viewvc/incubator/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/cas/impl/XmiCasDeserializerTest.java?rev=814897&r1=814896&r2=814897&view=diff
==============================================================================
--- incubator/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/cas/impl/XmiCasDeserializerTest.java (original)
+++ incubator/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/cas/impl/XmiCasDeserializerTest.java Mon Sep 14 22:54:47 2009
@@ -39,6 +39,7 @@
 import junit.framework.TestCase;
 
 import org.apache.uima.UIMAFramework;
+import org.apache.uima.UIMARuntimeException;
 import org.apache.uima.cas.ArrayFS;
 import org.apache.uima.cas.CAS;
 import org.apache.uima.cas.CASRuntimeException;
@@ -853,6 +854,59 @@
 	}
   }
   
+  
+  public void testDeltaCasInvalidMarker() throws Exception {
+	  try {
+      CAS cas1 = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(),
+              indexes);
+      CAS cas2 = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(),
+              indexes);
+
+      //serialize complete  
+      XmiSerializationSharedData sharedData = new XmiSerializationSharedData();
+      String xml = serialize(cas1, sharedData);
+      int maxOutgoingXmiId = sharedData.getMaxXmiId();
+      
+      //deserialize into cas2
+      XmiSerializationSharedData sharedData2 = new XmiSerializationSharedData();      
+      this.deserialize(xml, cas2, sharedData2, true, -1);
+      CasComparer.assertEquals(cas1, cas2);
+      
+      //create Marker, add/modify fs and serialize in delta xmi format.
+      Marker marker = cas2.createMarker();
+      boolean caughtMutlipleMarker = false;
+      try {
+        Marker marker2 = cas2.createMarker();
+      } catch (UIMARuntimeException e) {
+        caughtMutlipleMarker = true;
+        System.out.format("Should catch MultipleCreateMarker message: %s%n", e.getMessage());
+      }
+      assertTrue(caughtMutlipleMarker);
+      
+      //reset cas
+      cas2.reset();
+      boolean serfailed = false;
+      try {
+      	serialize(cas2, sharedData2, marker);
+      } catch (CASRuntimeException e) {
+      	serfailed = true;
+      }
+      assertTrue(serfailed);
+      
+//      serfailed = false;
+//      try {
+//      	serialize(cas2, sharedData2, marker2);
+//      } catch (CASRuntimeException e) {
+//      	serfailed = true;
+//      }
+//      assertTrue(serfailed);
+	      
+		} catch (Exception e) {
+			  JUnitExtension.handleException(e);
+		}
+  }
+  
+  
   public void testDeltaCasNoChanges() throws Exception {
 	    try {
 	      CAS cas1 = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(),

Modified: incubator/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/cas/test/SerializationReinitTest.java
URL: http://svn.apache.org/viewvc/incubator/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/cas/test/SerializationReinitTest.java?rev=814897&r1=814896&r2=814897&view=diff
==============================================================================
--- incubator/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/cas/test/SerializationReinitTest.java (original)
+++ incubator/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/cas/test/SerializationReinitTest.java Mon Sep 14 22:54:47 2009
@@ -34,6 +34,7 @@
 import org.apache.uima.cas.ByteArrayFS;
 import org.apache.uima.cas.CAS;
 import org.apache.uima.cas.CASException;
+import org.apache.uima.cas.CASRuntimeException;
 import org.apache.uima.cas.FSIndex;
 import org.apache.uima.cas.FSIndexRepository;
 import org.apache.uima.cas.FSIterator;
@@ -907,6 +908,37 @@
 	}
   }
   
+  public void testDeltaBlobWithInvalidMarker() throws Exception {
+    try {
+       CAS cas1 = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(),
+               indexes);
+       boolean serfailed = false;
+       Marker mark1 = cas1.createMarker();
+//       Marker mark2 = cas1.createMarker();  // multiple markers not supported, tested in other test case
+       
+       cas1.reset();
+       
+       try {
+      	 ByteArrayOutputStream fos = new ByteArrayOutputStream();
+      	 Serialization.serializeCAS(cas1, fos, mark1);
+       } catch (CASRuntimeException e) {
+      	 serfailed = true;
+       }
+       assertTrue(serfailed);
+       
+//       serfailed = false;
+//       try {
+//      	 ByteArrayOutputStream fos = new ByteArrayOutputStream();
+//      	 Serialization.serializeCAS(cas1, fos, mark2);
+//       } catch (CASRuntimeException e) {
+//      	 serfailed = true;
+//       }
+//       assertTrue(serfailed);
+    } catch (Exception e) {
+      JUnitExtension.handleException(e);
+    }
+  }
+
   private AnnotationFS createPersonAnnot(CAS cas, int begin, int end) {
 	Type personType = cas.getTypeSystem().getType("org.apache.uima.testTypeSystem.Person");
 	AnnotationFS person = cas.createAnnotation(personType, begin, end);