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 2016/05/25 14:59:52 UTC

svn commit: r1745499 [2/2] - in /uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima: cas/impl/ jcas/cas/

Modified: uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/OutOfTypeSystemData.java
URL: http://svn.apache.org/viewvc/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/OutOfTypeSystemData.java?rev=1745499&r1=1745498&r2=1745499&view=diff
==============================================================================
--- uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/OutOfTypeSystemData.java (original)
+++ uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/OutOfTypeSystemData.java Wed May 25 14:59:52 2016
@@ -26,6 +26,7 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
+import org.apache.uima.internal.util.Pair;
 import org.apache.uima.jcas.cas.TOP;
 
 /**
@@ -41,27 +42,27 @@ public class OutOfTypeSystemData {
   /**
    * List of FSData objects for out-of-typesystem FSs.
    */
-  List<FSData> fsList = new ArrayList<FSData>();
+  final List<FSData> fsList = new ArrayList<FSData>();
 
   /**
    * Map from Feature Structure to List of String arrays holding feature names and values for
    * out-of-typesystem features on in-typesystem FSs.
    */
-  Map<TOP, List<String[]>> extraFeatureValues = new IdentityHashMap<>();
+  final Map<TOP, List<Pair<String, Object>>> extraFeatureValues = new IdentityHashMap<>();
 
   /**
    * Map from FSArray instances to List of ArrayElement objects, each of which
    * holds an array index and value (as a string).
    *   key: FSArray instance represented as an xmiId
    */
-  Map<TOP, List<ArrayElement>> arrayElements = new IdentityHashMap<>();
+  final Map<TOP, List<ArrayElement>> arrayElements = new IdentityHashMap<>();
 
   /**
    * Map used during re-serialization. Stores mapping from out-of-typesystem FS IDs to the actual
    * IDs used in the generated XCAS.
    */
-  Map<String, String> idMap = new HashMap<String, String>();
-
+  final Map<String, String> idMap = new HashMap<String, String>();
+  
   /**
    * For debugging purposes only.
    */
@@ -73,17 +74,22 @@ public class OutOfTypeSystemData {
       buf.append(fs.toString()).append('\n');
     }
     buf.append("\nFeatures\n-----------------\n");
-    for (Map.Entry<TOP, List<String[]>> entry : extraFeatureValues.entrySet()) {
+    for (Map.Entry<TOP, List<Pair<String, Object>>> entry : extraFeatureValues.entrySet()) {
       TOP id = entry.getKey();
       buf.append(id._id).append(": ");
-      for (String[] attr : entry.getValue()) {
-        buf.append(attr[0]).append('=').append(attr[1]).append('\n');
+      for (Pair<String, Object> p : entry.getValue()) {
+        TOP fs = (p.u instanceof TOP) ? (TOP) p.u : null;       
+        String sv = (p.u instanceof String) ? (String)p.u : fs.toShortString(); 
+        buf.append(p.t).append('=').append(sv).append('\n');
       }
     }
     return buf.toString();
   }
 }
 
+/****************************************************************
+ *  W A R N I N G   Not an Inner Class ! !  
+ ****************************************************************/
 class ArrayElement {
   int index;
 
@@ -95,6 +101,9 @@ class ArrayElement {
   }
 }
 
+/****************************************************************
+ *  W A R N I N G   Not an Inner Class ! !  
+ ****************************************************************/
 class FSData {
   String id;
 
@@ -102,18 +111,24 @@ class FSData {
 
   String indexRep; // space-separated sequence of index repository numbers
 
-  Map<String, String> featVals = new HashMap<String, String>();
-
+  /** map from feature name to value which is a string or a ref to a not-out-of-type-system FS */
+  Map<String, Object> featVals = new HashMap<>();
+  
   public String toString() {
     StringBuffer buf = new StringBuffer();
     buf.append(type).append('[');
-    Iterator<Map.Entry<String, String>> it = featVals.entrySet().iterator();
+    Iterator<Map.Entry<String, Object>> it = featVals.entrySet().iterator();
     while (it.hasNext()) {
-      Map.Entry<String, String> entry = it.next();
-      buf.append(entry.getKey()).append('=').append(entry.getValue()).append(',');
+      Map.Entry<String, Object> entry = it.next();
+      Object v = entry.getValue();
+      if (v instanceof TOP) {
+        TOP fs = (TOP) v;
+        v = "FS:" + fs.toShortString(); 
+      }
+      buf.append(entry.getKey()).append('=').append(v).append(',');
     }
     buf.append("](ID=").append(id).append(')');
     return buf.toString();
   }
-
+  
 }

Modified: uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/TypeSystemImpl.java
URL: http://svn.apache.org/viewvc/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/TypeSystemImpl.java?rev=1745499&r1=1745498&r2=1745499&view=diff
==============================================================================
--- uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/TypeSystemImpl.java (original)
+++ uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/TypeSystemImpl.java Wed May 25 14:59:52 2016
@@ -126,7 +126,7 @@ import com.strobel.decompiler.Decompiler
  *   -- implemented via custom hashcode and equals.
  *         
  */
-public class TypeSystemImpl implements TypeSystem, TypeSystemMgr, LowLevelTypeSystem, TypeSystemConstants {  
+public class TypeSystemImpl implements TypeSystem, TypeSystemMgr, LowLevelTypeSystem {  
   
   /**
    * Define this JVM property to disable equal type system consolidation.  
@@ -1266,10 +1266,6 @@ public class TypeSystemImpl implements T
    */
   @Override
   public TypeSystemImpl commit() {
-    if (this.locked) {
-      return this; // might be called multiple times, but only need to do once
-    }
-    
     synchronized(this) {
       if (this.locked) {
         return this; // might be called multiple times, but only need to do once
@@ -2006,55 +2002,55 @@ public class TypeSystemImpl implements T
     
   @Override
   public final int ll_getTypeClass(int typeCode) {
-    if (typeCode == booleanTypeCode) {
+    if (typeCode == TypeSystemConstants.booleanTypeCode) {
       return LowLevelCAS.TYPE_CLASS_BOOLEAN;
     }
-    if (typeCode == byteTypeCode) {
+    if (typeCode == TypeSystemConstants.byteTypeCode) {
       return LowLevelCAS.TYPE_CLASS_BYTE;
     }
-    if (typeCode == shortTypeCode) {
+    if (typeCode == TypeSystemConstants.shortTypeCode) {
       return LowLevelCAS.TYPE_CLASS_SHORT;
     }
-    if (typeCode == intTypeCode) {
+    if (typeCode == TypeSystemConstants.intTypeCode) {
       return LowLevelCAS.TYPE_CLASS_INT;
     }
-    if (typeCode == floatTypeCode) {
+    if (typeCode == TypeSystemConstants.floatTypeCode) {
       return LowLevelCAS.TYPE_CLASS_FLOAT;
     }
-    if (typeCode == longTypeCode) {
+    if (typeCode == TypeSystemConstants.longTypeCode) {
       return LowLevelCAS.TYPE_CLASS_LONG;
     }
-    if (typeCode == doubleTypeCode) {
+    if (typeCode == TypeSystemConstants.doubleTypeCode) {
       return LowLevelCAS.TYPE_CLASS_DOUBLE;
     }
     // false if string type code not yet set up (during initialization)
     //   need this to avoid NPE in subsumes
-    if ((stringTypeCode != LowLevelTypeSystem.UNKNOWN_TYPE_CODE) &&
-          ll_subsumes(stringTypeCode, typeCode)) {
+    if ((TypeSystemConstants.stringTypeCode != LowLevelTypeSystem.UNKNOWN_TYPE_CODE) &&
+          ll_subsumes(TypeSystemConstants.stringTypeCode, typeCode)) {
       return LowLevelCAS.TYPE_CLASS_STRING;
     }
-    if (typeCode == booleanArrayTypeCode) {
+    if (typeCode == TypeSystemConstants.booleanArrayTypeCode) {
       return LowLevelCAS.TYPE_CLASS_BOOLEANARRAY;
     }
-    if (typeCode == byteArrayTypeCode) {
+    if (typeCode == TypeSystemConstants.byteArrayTypeCode) {
       return LowLevelCAS.TYPE_CLASS_BYTEARRAY;
     }
-    if (typeCode == shortArrayTypeCode) {
+    if (typeCode == TypeSystemConstants.shortArrayTypeCode) {
       return LowLevelCAS.TYPE_CLASS_SHORTARRAY;
     }
-    if (typeCode == intArrayTypeCode) {
+    if (typeCode == TypeSystemConstants.intArrayTypeCode) {
       return LowLevelCAS.TYPE_CLASS_INTARRAY;
     }
-    if (typeCode == floatArrayTypeCode) {
+    if (typeCode == TypeSystemConstants.floatArrayTypeCode) {
       return LowLevelCAS.TYPE_CLASS_FLOATARRAY;
     }
-    if (typeCode == longArrayTypeCode) {
+    if (typeCode == TypeSystemConstants.longArrayTypeCode) {
       return LowLevelCAS.TYPE_CLASS_LONGARRAY;
     }
-    if (typeCode == doubleArrayTypeCode) {
+    if (typeCode == TypeSystemConstants.doubleArrayTypeCode) {
       return LowLevelCAS.TYPE_CLASS_DOUBLEARRAY;
     }
-    if (typeCode == stringArrayTypeCode) {
+    if (typeCode == TypeSystemConstants.stringArrayTypeCode) {
       return LowLevelCAS.TYPE_CLASS_STRINGARRAY;
     }
     if (ll_isArrayType(typeCode)) {
@@ -2355,23 +2351,23 @@ public class TypeSystemImpl implements T
   
   public static final int getTypeClass(TypeImpl ti) { 
     switch (ti.getCode()) {
-    case TypeSystemImpl.intTypeCode: return CASImpl.TYPE_CLASS_INT;
-    case TypeSystemImpl.floatTypeCode: return CASImpl.TYPE_CLASS_FLOAT;
-    case TypeSystemImpl.stringTypeCode: return CASImpl.TYPE_CLASS_STRING;
-    case TypeSystemImpl.intArrayTypeCode: return CASImpl.TYPE_CLASS_INTARRAY;
-    case TypeSystemImpl.floatArrayTypeCode: return CASImpl.TYPE_CLASS_FLOATARRAY;
-    case TypeSystemImpl.stringArrayTypeCode: return CASImpl.TYPE_CLASS_STRINGARRAY;
-    case TypeSystemImpl.fsArrayTypeCode: return CASImpl.TYPE_CLASS_FSARRAY;
-    case TypeSystemImpl.booleanTypeCode: return CASImpl.TYPE_CLASS_BOOLEAN;
-    case TypeSystemImpl.byteTypeCode: return CASImpl.TYPE_CLASS_BYTE;
-    case TypeSystemImpl.shortTypeCode: return CASImpl.TYPE_CLASS_SHORT;
-    case TypeSystemImpl.longTypeCode: return CASImpl.TYPE_CLASS_LONG;
-    case TypeSystemImpl.doubleTypeCode: return CASImpl.TYPE_CLASS_DOUBLE;
-    case TypeSystemImpl.booleanArrayTypeCode: return CASImpl.TYPE_CLASS_BOOLEANARRAY;
-    case TypeSystemImpl.byteArrayTypeCode: return CASImpl.TYPE_CLASS_BYTEARRAY;
-    case TypeSystemImpl.shortArrayTypeCode: return CASImpl.TYPE_CLASS_SHORTARRAY;
-    case TypeSystemImpl.longArrayTypeCode: return CASImpl.TYPE_CLASS_LONGARRAY;
-    case TypeSystemImpl.doubleArrayTypeCode: return CASImpl.TYPE_CLASS_DOUBLEARRAY;
+    case TypeSystemConstants.intTypeCode: return CASImpl.TYPE_CLASS_INT;
+    case TypeSystemConstants.floatTypeCode: return CASImpl.TYPE_CLASS_FLOAT;
+    case TypeSystemConstants.stringTypeCode: return CASImpl.TYPE_CLASS_STRING;
+    case TypeSystemConstants.intArrayTypeCode: return CASImpl.TYPE_CLASS_INTARRAY;
+    case TypeSystemConstants.floatArrayTypeCode: return CASImpl.TYPE_CLASS_FLOATARRAY;
+    case TypeSystemConstants.stringArrayTypeCode: return CASImpl.TYPE_CLASS_STRINGARRAY;
+    case TypeSystemConstants.fsArrayTypeCode: return CASImpl.TYPE_CLASS_FSARRAY;
+    case TypeSystemConstants.booleanTypeCode: return CASImpl.TYPE_CLASS_BOOLEAN;
+    case TypeSystemConstants.byteTypeCode: return CASImpl.TYPE_CLASS_BYTE;
+    case TypeSystemConstants.shortTypeCode: return CASImpl.TYPE_CLASS_SHORT;
+    case TypeSystemConstants.longTypeCode: return CASImpl.TYPE_CLASS_LONG;
+    case TypeSystemConstants.doubleTypeCode: return CASImpl.TYPE_CLASS_DOUBLE;
+    case TypeSystemConstants.booleanArrayTypeCode: return CASImpl.TYPE_CLASS_BOOLEANARRAY;
+    case TypeSystemConstants.byteArrayTypeCode: return CASImpl.TYPE_CLASS_BYTEARRAY;
+    case TypeSystemConstants.shortArrayTypeCode: return CASImpl.TYPE_CLASS_SHORTARRAY;
+    case TypeSystemConstants.longArrayTypeCode: return CASImpl.TYPE_CLASS_LONGARRAY;
+    case TypeSystemConstants.doubleArrayTypeCode: return CASImpl.TYPE_CLASS_DOUBLEARRAY;
     }
     
     if (ti.isStringOrStringSubtype()) {

Modified: uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/XCASDeserializer.java
URL: http://svn.apache.org/viewvc/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/XCASDeserializer.java?rev=1745499&r1=1745498&r2=1745499&view=diff
==============================================================================
--- uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/XCASDeserializer.java (original)
+++ uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/XCASDeserializer.java Wed May 25 14:59:52 2016
@@ -33,6 +33,7 @@ import org.apache.uima.cas.Type;
 import org.apache.uima.cas.TypeSystem;
 import org.apache.uima.internal.util.IntVector;
 import org.apache.uima.internal.util.Misc;
+import org.apache.uima.internal.util.Pair;
 import org.apache.uima.internal.util.StringUtils;
 import org.apache.uima.internal.util.rb_trees.RedBlackTree;
 import org.apache.uima.jcas.cas.CommonPrimitiveArray;
@@ -124,7 +125,7 @@ public class XCASDeserializer {
     private static final String unknownXMLSource = "<unknown>";
 
     // SofaFS type
-    static final private int sofaTypeCode = TypeSystemImpl.sofaTypeCode;
+    static final private int sofaTypeCode = TypeSystemConstants.sofaTypeCode;
 
     // private long time;
 
@@ -603,19 +604,19 @@ public class XCASDeserializer {
                              ? Integer.toString(this.sofaRefMap.get(
                                  ((Sofa)fsTree.get(Integer.parseInt(featValIn)).fs).getSofaNum()))
                              : featValIn;
-
-//      // can't do this in v3, dropping support  
+  
       // handle v1.x sofanum values, remapping so that _InitialView always == 1
+      // Bypassed in v3 of UIMA because sofa was already created with the right sofanum
 //      if (featName.equals(CAS.FEATURE_BASE_NAME_SOFAID) && (fs instanceof Sofa)) {
 //        Sofa sofa = (Sofa) fs;
 //        int sofaNum = sofa.getSofaNum();
-//        sofa.  --- oops, not possible to update the sofanum - it's final
+//        sofa._setIntValueNcNj(Sofa._FI_sofaNum, this.indexMap.get(sofaNum));
 //        
-//        Type sofaType = ts.sofaType;
-//        final FeatureImpl sofaNumFeat = (FeatureImpl) sofaType
-//                .getFeatureByBaseName(CAS.FEATURE_BASE_NAME_SOFANUM);
-//        int sofaNum = cas.getFeatureValue(addr, sofaNumFeat.getCode());
-//        cas.setFeatureValue(addr, sofaNumFeat.getCode(), this.indexMap.get(sofaNum));
+////        Type sofaType = ts.sofaType;
+////        final FeatureImpl sofaNumFeat = (FeatureImpl) sofaType
+////                .getFeatureByBaseName(CAS.FEATURE_BASE_NAME_SOFANUM);
+////        int sofaNum = cas.getFeatureValue(addr, sofaNumFeat.getCode());
+////        cas.setFeatureValue(addr, sofaNumFeat.getCode(), this.indexMap.get(sofaNum));
 //      }
 
       String realFeatName = getRealFeatName(featName);
@@ -624,12 +625,12 @@ public class XCASDeserializer {
       if (feat == null) { // feature does not exist in typesystem
         if (outOfTypeSystemData != null) {
           // Add to Out-Of-Typesystem data (APL)
-          List<String[]> ootsAttrs = outOfTypeSystemData.extraFeatureValues.get(fs);
+          List<Pair<String, Object>> ootsAttrs = outOfTypeSystemData.extraFeatureValues.get(fs);
           if (ootsAttrs == null) {
-            ootsAttrs = new ArrayList<String[]>();
+            ootsAttrs = new ArrayList<Pair<String, Object>>();
             outOfTypeSystemData.extraFeatureValues.put(fs, ootsAttrs);
           }
-          ootsAttrs.add(new String[] { featName, featVal });
+          ootsAttrs.add(new Pair(featName, featVal));
         } else if (!lenient) {
           throw createException(XCASParsingException.UNKNOWN_FEATURE, featName);
         }
@@ -863,25 +864,25 @@ public class XCASDeserializer {
         // this feature may be a ref to an out-of-typesystem FS.
         // add it to the Out-of-typesystem features list (APL)
         if (extId != 0 && outOfTypeSystemData != null) {
-          List<String[]> ootsAttrs = outOfTypeSystemData.extraFeatureValues.get(extId);
+          List<Pair<String, Object>> ootsAttrs = outOfTypeSystemData.extraFeatureValues.get(fs);
           if (ootsAttrs == null) {
-            ootsAttrs = new ArrayList<String[]>();
+            ootsAttrs = new ArrayList<Pair<String, Object>>();
             outOfTypeSystemData.extraFeatureValues.put(fs, ootsAttrs);
           }
           String featFullName = fi.getName();
           int separatorOffset = featFullName.indexOf(TypeSystem.FEATURE_SEPARATOR);
           String featName = "_ref_" + featFullName.substring(separatorOffset + 1);
-          ootsAttrs.add(new String[] { featName, Integer.toString(extId) });
+          ootsAttrs.add(new Pair(featName, Integer.toString(extId)));
         }
         fs.setFeatureValue(fi, null);
       } else {
         // the sofa ref in annotationBase is set when the fs is created, not here
-        if (fi.getCode() != TypeSystemImpl.annotBaseSofaFeatCode) { 
+        if (fi.getCode() != TypeSystemConstants.annotBaseSofaFeatCode) { 
           if (fs instanceof Sofa) {
             // special setters for sofa values
             Sofa sofa = (Sofa) fs;
             switch (fi.getRangeImpl().getCode()) {
-            case TypeSystemImpl.sofaArrayFeatCode: sofa.setLocalSofaData(fsInfo.fs); break;
+            case TypeSystemConstants.sofaArrayFeatCode: sofa.setLocalSofaData(fsInfo.fs); break;
             default: throw new CASRuntimeException(CASRuntimeException.INTERNAL_ERROR);
             }
             return;
@@ -948,16 +949,17 @@ public class XCASDeserializer {
       // make ID unique by prefixing a letter
       aFS.id = 'a' + aFS.id;
       // remap ref features
-      for (Map.Entry<String, String> entry : aFS.featVals.entrySet()) {
+      for (Map.Entry<String, Object> entry : aFS.featVals.entrySet()) {
         String attrName =  entry.getKey();
         if (attrName.startsWith("_ref_")) {
-          int val = Integer.parseInt(entry.getValue());
+          int val = Integer.parseInt((String)entry.getValue());
           if (val >= 0) // negative numbers represent null and are left unchanged
           {
             // attempt to locate target in type system
             FSInfo fsValInfo = fsTree.get(val);
             if (fsValInfo != null) {
-              entry.setValue(Integer.toString(fsValInfo.fs._id));
+//              entry.setValue(Integer.toString(fsValInfo.fs._id));
+              entry.setValue(fsValInfo.fs);
             } else
             // out of type system - remap by prepending letter
             {
@@ -974,20 +976,21 @@ public class XCASDeserializer {
      */
     private void finalizeOutOfTypeSystemFeatures() {
       // remap ref features
-      for (List<String[]> attrs : outOfTypeSystemData.extraFeatureValues.values()) {
-        for (String[] attr : attrs) {
-          if (attr[0].startsWith("_ref_")) {
-            int val = Integer.parseInt(attr[1]);
+      for (List<Pair<String, Object>> attrs : outOfTypeSystemData.extraFeatureValues.values()) {
+        for (Pair<String, Object> p : attrs) {
+          String sv = (p.u instanceof String) ? (String) p.u : "";
+          if (p.t.startsWith("_ref_")) {
+            int val = Integer.parseInt(sv);
             if (val >= 0) // negative numbers represent null and are left unchanged
             {
               // attempt to locate target in type system
               FSInfo fsValInfo = fsTree.get(val);
               if (fsValInfo != null) {
-                attr[1] = Integer.toString(fsValInfo.fs._id);
+                p.u = fsValInfo.fs;
               } else
               // out of type system - remap by prepending letter
               {
-                attr[1] = "a" + val;
+                p.u = "a" + val;
               }
             }
           }

Modified: uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/XCASSerializer.java
URL: http://svn.apache.org/viewvc/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/XCASSerializer.java?rev=1745499&r1=1745498&r2=1745499&view=diff
==============================================================================
--- uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/XCASSerializer.java (original)
+++ uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/XCASSerializer.java Wed May 25 14:59:52 2016
@@ -29,12 +29,14 @@ import java.util.IdentityHashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
 
 import org.apache.uima.UimaContext;
 import org.apache.uima.cas.CAS;
 import org.apache.uima.cas.Feature;
 import org.apache.uima.cas.TypeSystem;
 import org.apache.uima.internal.util.IntVector;
+import org.apache.uima.internal.util.Pair;
 import org.apache.uima.internal.util.StringUtils;
 import org.apache.uima.jcas.cas.BooleanArray;
 import org.apache.uima.jcas.cas.ByteArray;
@@ -79,7 +81,7 @@ public class XCASSerializer {
     // The CAS we're serializing.
     private CASImpl cas;
 
-    // Any FS reference we've touched goes in here.
+    /** Any FS reference we've touched goes in here. value is index repo (first one?), or MULTIPLY_INDEXED */
     final private Map<TOP, Integer> queued = new IdentityHashMap<>();
 
     private static final int NOT_INDEXED = -1;
@@ -88,22 +90,29 @@ public class XCASSerializer {
 
     private static final int INVALID_INDEX = -3;
 
-    // Any FS indexed in more than one IR goes in here
+    
+    /** Any FS indexed in more than one IR goes in here, the value is the associated duplicate key,
+     * Key is used to index into dupVectors */
     final private Map<TOP, Integer> duplicates = new IdentityHashMap<>();
 
-    // Number of FS indexed in more than one IR
+    /** A key identifying a particular FS indexed in multiple indexes.
+     *  Starts a 0, incr by 1 for each new FS discovered to be indexed in more than one IR */
     int numDuplicates;
 
-    // Vector of IntVectors for duplicates
+    /** list of IntVectors holding lists of repo numbers.
+     * Indexed by the key above, for fss that are in multiple index repos */
     final List<IntVector> dupVectors = new ArrayList<>();
 
-    // All FSs that are in an index somewhere.
+
+    // next 2 are a pair; the first is a fs, the 2nd is the index repo its indexed in
+    /** list of FSs that are in an index somewhere.  */
     final private List<TOP> indexedFSs = new ArrayList<>();
 
-    // Specific IndexRepository for indexed FSs
+    /** Specific IndexRepository for indexed FSs */
     final private IntVector indexReps = new IntVector();
 
-    // The current queue for FSs to write out.
+    
+    /** The current queue for FSs to write out. */
     final private Deque<TOP> queue = new ArrayDeque<>();
 
     private final AttributesImpl emptyAttrs = new AttributesImpl();
@@ -184,7 +193,7 @@ public class XCASSerializer {
             dupVectors.get(thisDup).add(indexRep);
             break;
           }
-          // duplicate index detected!
+          // first time we notice this FS is indexed in multiple indexes
           duplicates.put(fs, numDuplicates);
           dupVectors.add(new IntVector());
           dupVectors.get(numDuplicates).add(prevIndex);
@@ -353,7 +362,7 @@ public class XCASSerializer {
     }
     
     private void enqueueList(List<TOP> fss, int sofaNum) {
-      for (TOP fs : fss) {   // enqueues the Sofas
+      for (TOP fs : fss) {   // enqueues the fss for one view (incl view 0 - the base view
         enqueueIndexed(fs, sofaNum);
       }
     }
@@ -485,7 +494,7 @@ public class XCASSerializer {
         }
         default: {
           // Internal error.
-          System.err.println("Error classifying FS type.");
+          throw new RuntimeException("Internal error: classifying FS type.");
         }
       } // end of switch
       // common code for most of the cases
@@ -602,17 +611,18 @@ public class XCASSerializer {
      * Encode Out-Of-TypeSystem Features.
      */
     private void encodeOutOfTypeSystemFeatures(TOP fs, AttributesImpl attrs) {
-      List<String[]> attrList = mOutOfTypeSystemData.extraFeatureValues.get(fs);
+      List<Pair<String, Object>> attrList = mOutOfTypeSystemData.extraFeatureValues.get(fs);
       if (attrList != null) {
-        for (String[] attr : attrList) {
+        for (Pair<String, Object> p : attrList) {
+          String sv = (p.u instanceof String) ? (String) p.u : "";
           // remap ID if necessary
-          if (attr[0].startsWith(REF_PREFIX)) {
-            if (attr[1].startsWith("a")) { // reference to OOTS FS
+          if (p.t.startsWith(REF_PREFIX)) {
+            if (sv.startsWith("a")) { // reference to OOTS FS
               // - remap
-              attr[1] = mOutOfTypeSystemData.idMap.get(attr[1]);
+              p.u = sv = mOutOfTypeSystemData.idMap.get(sv);
             }
           }
-          addAttribute(attrs, attr[0], attr[1]);
+          addAttribute(attrs, p.t, sv);
         }
       }
     }
@@ -621,18 +631,20 @@ public class XCASSerializer {
      * Encode Out-Of-TypeSystem Features.
      */
     private void enqueueOutOfTypeSystemFeatures(TOP fs) {
-      List<String[]> attrList = mOutOfTypeSystemData.extraFeatureValues.get(fs);
+      List<Pair<String, Object>> attrList = mOutOfTypeSystemData.extraFeatureValues.get(fs);
       if (attrList != null) {
-        Iterator<String[]> it = attrList.iterator();
+        Iterator<Pair<String, Object>> it = attrList.iterator();
         while (it.hasNext()) {
-          String[] attr = it.next();
+          Pair<String, Object> p = it.next();
+          String sv = (p.u instanceof String) ? (String) p.u : "";
           // remap ID if necessary
-          if (attr[0].startsWith(REF_PREFIX)) {
+          if (p.t.startsWith(REF_PREFIX)) {
             // references whose ID starts with the character 'a' are references to out of type
             // system FS. All other references should be to in-typesystem FS, which we need to
             // enqueue.
-            if (!attr[1].startsWith("a")) {
-              enqueue(cas.getFsFromId_checked(Integer.parseInt(attr[1])));
+            if (p.u instanceof TOP) {
+              enqueue((TOP) p.u);
+//              enqueue(cas.getFsFromId_checked(Integer.parseInt(attr[1])));
             }
           }
         }
@@ -657,15 +669,16 @@ public class XCASSerializer {
      */
     private void enqueueOutOfTypeSystemData(OutOfTypeSystemData aData) {
       for (FSData fs : aData.fsList) {
-        for (Map.Entry<String, String> entry : fs.featVals.entrySet()) {
+        for (Entry<String, Object> entry : fs.featVals.entrySet()) {
           String attrName = entry.getKey();
           if (attrName.startsWith(REF_PREFIX)) {
-            String attrVal = entry.getValue();
+            Object attrVal = entry.getValue();
             // references whose ID starts with the character 'a' are references to out of type
             // system FS. All other references should be to in-typesystem FS, which we need to
             // enqueue.
-            if (!attrVal.startsWith("a")) {
-              enqueue(cas.getFsFromId_checked(Integer.parseInt(attrVal)));
+            if (attrVal instanceof TOP /*String && !((String)attrVal).startsWith("a")*/) {
+              enqueue((TOP)attrVal);
+//              enqueue(cas.getFsFromId_checked(Integer.parseInt(attrVal)));
             }
           }
         }
@@ -684,11 +697,11 @@ public class XCASSerializer {
         addAttribute(workAttrs, ID_ATTR_NAME, fs.id);
 
         // Add other attributes (remap OOTS refs)
-        for (Map.Entry<String, String> entry : fs.featVals.entrySet()) {
+        for (Entry<String, Object> entry : fs.featVals.entrySet()) {
           String attrName = entry.getKey();
-          String attrVal = entry.getValue();
+          Object attrVal = entry.getValue();
           if (attrName.startsWith(REF_PREFIX)) {
-            if (attrVal.startsWith("a")) {
+            if (attrVal instanceof String && ((String)attrVal).startsWith("a")) {
               // "a" prefix indicates a reference from one OOTS FS
               // to another OOTS FS;
               // we need to remap those IDs to the actual IDs used
@@ -696,7 +709,9 @@ public class XCASSerializer {
               attrVal = mOutOfTypeSystemData.idMap.get(attrVal);
             }
           }
-          addAttribute(workAttrs, attrName, attrVal);
+          addAttribute(workAttrs, attrName, (attrVal instanceof TOP) 
+                                              ? Integer.toString(((TOP)attrVal)._id) 
+                                              : (String)attrVal);
         }
         // send events
         String xcasElementName = getXCasElementName(fs.type);

Modified: uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/XmiSerializationSharedData.java
URL: http://svn.apache.org/viewvc/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/XmiSerializationSharedData.java?rev=1745499&r1=1745498&r2=1745499&view=diff
==============================================================================
--- uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/XmiSerializationSharedData.java (original)
+++ uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/XmiSerializationSharedData.java Wed May 25 14:59:52 2016
@@ -507,9 +507,9 @@ public class XmiSerializationSharedData
    * is a reference to an out-of-typesystem FS.
    */
   public static class XmiArrayElement {
-    public int index;
+    final public int index;
 
-    public String xmiId;
+    final public String xmiId;
 
     XmiArrayElement(int index, String xmiId) {
       this.index = index;

Modified: uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/jcas/cas/AnnotationBase.java
URL: http://svn.apache.org/viewvc/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/jcas/cas/AnnotationBase.java?rev=1745499&r1=1745498&r2=1745499&view=diff
==============================================================================
--- uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/jcas/cas/AnnotationBase.java (original)
+++ uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/jcas/cas/AnnotationBase.java Wed May 25 14:59:52 2016
@@ -22,9 +22,12 @@ package org.apache.uima.jcas.cas;
 import org.apache.uima.cas.AnnotationBaseFS;
 import org.apache.uima.cas.CAS;
 import org.apache.uima.cas.CASRuntimeException;
-import org.apache.uima.cas.SofaFS;
+import org.apache.uima.cas.Feature;
+import org.apache.uima.cas.FeatureStructure;
 import org.apache.uima.cas.impl.CASImpl;
+import org.apache.uima.cas.impl.FeatureImpl;
 import org.apache.uima.cas.impl.TypeImpl;
+import org.apache.uima.cas.impl.TypeSystemConstants;
 import org.apache.uima.cas.impl.TypeSystemImpl;
 import org.apache.uima.jcas.JCas;
 import org.apache.uima.jcas.JCasRegistry;
@@ -80,7 +83,7 @@ public class AnnotationBase extends TOP
       throw new CASRuntimeException(CASRuntimeException.DISALLOW_CREATE_ANNOTATION_IN_BASE_CAS, this.getClass().getName());
     }
     // no journaling, no index corruption checking
-    _setRefValueCommon(_FI_sofa, _casView.getSofa());
+    _setRefValueCommon(_FI_sofa, _casView.getSofaRef());
   }
 
   /**
@@ -96,7 +99,7 @@ public class AnnotationBase extends TOP
       throw new CASRuntimeException(CASRuntimeException.DISALLOW_CREATE_ANNOTATION_IN_BASE_CAS, this.getClass().getName());
     }
     // no journaling, no index corruption checking
-    _setRefValueCommon(_FI_sofa, _casView.getSofa());
+    _setRefValueCommon(_FI_sofa, _casView.getSofaRef());
   }
 
   // *------------------*
@@ -114,5 +117,17 @@ public class AnnotationBase extends TOP
   public CAS getView() {
     return _casView;
   }
-   
+  
+  @Override
+  public void setFeatureValue(Feature feat, FeatureStructure v) {
+    FeatureImpl fi = (FeatureImpl) feat;
+    if (fi.getCode() == TypeSystemConstants.annotBaseSofaFeatCode) {
+      // trying to set the sofa - don't do this, but check if the value
+      // is OK (note: may break backwards compatibility)  
+      if (v != _getFeatureValueNc(AnnotationBase._FI_sofa)) {
+        throw new CASRuntimeException(CASRuntimeException.ILLEGAL_SOFAREF_MODIFICATION);
+      }
+    }
+    super.setFeatureValue(feat,  v);
+  }
 }