Author: schor
Date: Thu Aug 18 15:59:12 2016
New Revision: 1756828

URL: http://svn.apache.org/viewvc?rev=1756828&view=rev
Log:
[UIMA-5030] support pears: when getting or setting feature values, do proper 
pear value conversion (the stored value is always the base (non-pear) value).

Added:
    
uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_bag_pear.java
    
uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_set_sorted_pear.java
    
uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/MethodHandlesLookup.java
Modified:
    
uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/CASImpl.java
    
uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FeatureStructureImplC.java
    
uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsGeneratorArray.java
    
uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIndex_bag.java
    
uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIndex_set_sorted.java
    
uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_bag.java
    
uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_set_sorted.java
    
uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/Id2FS.java
    
uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/TypeImpl.java
    
uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/TypeImpl_array.java
    
uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/TypeSystemImpl.java

Modified: 
uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/CASImpl.java
URL: 
http://svn.apache.org/viewvc/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/CASImpl.java?rev=1756828&r1=1756827&r2=1756828&view=diff
==============================================================================
--- 
uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/CASImpl.java
 (original)
+++ 
uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/CASImpl.java
 Thu Aug 18 15:59:12 2016
@@ -112,6 +112,7 @@ import org.apache.uima.jcas.cas.ShortArr
 import org.apache.uima.jcas.cas.Sofa;
 import org.apache.uima.jcas.cas.StringArray;
 import org.apache.uima.jcas.cas.TOP;
+import org.apache.uima.jcas.impl.JCasHashMap;
 import org.apache.uima.jcas.impl.JCasImpl;
 import org.apache.uima.jcas.tcas.Annotation;
 import org.apache.uima.util.Level;
@@ -281,12 +282,7 @@ public class CASImpl extends AbstractCas
      final private Id2FS id2fs;
      /** set to > 0 to reuse an id, 0 otherwise */
      private int reuseId = 0;
-     
-     /** 
-      * for Pear generation - set this to the base FS
-      */
-    FeatureStructureImplC pearBaseFs = null;  
-    
+         
     // Base CAS for all views
     final private CASImpl baseCAS;
     
@@ -331,7 +327,53 @@ public class CASImpl extends AbstractCas
     // FS cover classes for this CAS. Defaults to the ClassLoader used
     // to load the CASImpl class.
     private ClassLoader jcasClassLoader = this.getClass().getClassLoader();
-
+    
+    /*****************************
+     * PEAR Support
+     *****************************/
+    /**
+     * Only support one level of PEAR nesting; for more general approach, make 
this a deque
+     */
+    private ClassLoader previousJCasClassLoader = null;
+    /**
+     * Save area for suspending this while we create a base instance
+     */
+    private ClassLoader suspendPreviousJCasClassLoader;  
+    
+    /**
+     * A map from IDs to already created trampoline FSs for the base FS with 
that id.
+     * These are used when in a Pear and retrieving a FS (via index or deref) 
and you want the 
+     * Pear version for that ID.
+     * There are potentially multiple maps - one per PEAR Classpath
+     */
+    private JCasHashMap id2tramp = null;
+    /**
+     * a map from IDs of FSs that have a Pear version, to the base (non-Pear) 
version
+     * used to locate the base version for adding to indexes
+     */
+    private JCasHashMap id2base = null;
+    private final Map<ClassLoader, JCasHashMap> cl2id2tramp = new 
IdentityHashMap<>(); 
+    
+    /**
+     * The current (active, switches at Pear boundaries) FsGenerators 
(excluding array-generators)
+     * key = type code
+     * read-only, unsynchronized for this CAS
+     * Cache for setting this kept in TypeSystemImpl, by classloader 
+     *   - shared among all CASs that use that Type System and class loader
+     *   -- in turn, initialized from FSClassRegistry, once per classloader / 
typesystem combo 
+     *   
+     * Pear generators are mostly null except for instances where the PEAR has 
redefined
+     * the JCas cover class
+     */
+    private FsGenerator[] generators;
+    /**
+     * When generating a new instance of a FS in a PEAR where there's an 
alternate JCas class impl,
+     * generate the base version, and make the alternate a trampoline to it.
+     *   Note: in future, if it is known that this FS is never used outside of 
this PEAR, then can
+     *         skip generating the double version
+     */
+    private FsGenerator[] baseGenerators; 
+    
     // If this CAS can be flushed (reset) or not.
     // often, the framework disables this before calling users code
     private boolean flushEnabled = true;
@@ -470,6 +512,13 @@ public class CASImpl extends AbstractCas
       // fss
       fsIdGenerator = 0;
       id2fs.clear();
+      
+      // pear caches
+      id2tramp = null;
+      id2base = null;
+      for (JCasHashMap m : cl2id2tramp.values()) {
+        m.clear();
+      }
 
       // index corruption avoidance
       fssTobeAddedback.clear();
@@ -555,6 +604,37 @@ public class CASImpl extends AbstractCas
       trackingMark = null;
       if (null != modifiedPreexistingFSs) modifiedPreexistingFSs.clear();
     }
+    
+    void switchClassLoader(ClassLoader newClassLoader) {
+      if (null == newClassLoader) { // is null if no cl set
+        return;
+      }
+      if (newClassLoader != jcasClassLoader) {
+        // System.out.println("Switching to new class loader");
+        previousJCasClassLoader = jcasClassLoader;
+        jcasClassLoader = newClassLoader;
+        generators = tsi.getGeneratorsForClassLoader(newClassLoader, true); // 
true - isPear
+        
+        assert null == id2tramp;  // is null outside of a pear
+        id2tramp = cl2id2tramp.get(newClassLoader);
+        if (null == id2tramp) {
+          cl2id2tramp.put(newClassLoader, id2tramp = new JCasHashMap(32));
+        }
+        if (id2base == null) {
+          id2base = new JCasHashMap(32);
+        }
+      }
+    }
+    
+    void restoreClassLoader() {
+      if (null == previousJCasClassLoader || previousJCasClassLoader == 
jcasClassLoader) {
+        return;
+      }
+      // System.out.println("Switching back to previous class loader");
+      jcasClassLoader = previousJCasClassLoader;
+      generators = baseGenerators;
+      id2tramp = null;
+    }
   }
   
   /*****************************************************************
@@ -584,7 +664,7 @@ public class CASImpl extends AbstractCas
   private Sofa mySofaRef = null;
 
   /** the corresponding JCas object */
-  JCas jcas = null;
+  JCasImpl jcas = null;
 
   /**
    * Copies of frequently accessed data pulled up for 
@@ -594,6 +674,13 @@ public class CASImpl extends AbstractCas
    */
   
   private TypeSystemImpl tsi_local;
+  
+  /** 
+   * for Pear generation - set this to the base FS
+   * not in SharedViewData to reduce object traversal when
+   * generating FSs
+   */
+  FeatureStructureImplC pearBaseFs = null;  
 
   // CASImpl(TypeSystemImpl typeSystem) {
   // this(typeSystem, DEFAULT_INITIAL_HEAP_SIZE);
@@ -846,26 +933,89 @@ public class CASImpl extends AbstractCas
                      // must happen before the annotation is created, for 
compressed form 6 serialization order
                      // to insure sofa precedes the ref of it
     }
+
+    FsGenerator g = svd.generators[ti.getCode()];  // get generator or null
+    if (g != null) {
+      return (T) g.createFS(ti, this);
+    } else { // pear case, with no overriding pear - use base
+      return (T) createFsFromGenerator(svd.baseGenerators, ti);
+    }
+
+//    
+//    
+//    // not pear or no special cover class for this
+//      
+//    
+//      TOP fs = createFsFromGenerator(svd.baseGenerators, ti);
+//      
+//      FsGenerator g = svd.generators[ti.getCode()];  // get pear generator 
or null
+//      return (g != null) 
+//               ? (T) pearConvert(fs, g)
+//               : (T) fs;
+//    }
+//  
+//    return (T) createFsFromGenerator(svd.generators, ti);
+  }
   
-    T fs = (T) ti.getGenerator().createFS(ti, this);  
-//    T fs = (T) (((FsGenerator)getFsGenerator(ti.getCode())).createFS(ti, 
this));
-    return fs;
-  } 
-  
-  public int ll_createFSAnnotCheck(int typeCode) {
-    TOP fs = createFSAnnotCheck(getTypeFromCode(typeCode));
-    svd.id2fs.put(fs);
-    return fs._id;
+  /**
+   * Called during construction of FS.
+   * For normal FS "new" operators, if in PEAR context, make the base version
+   * @param fs
+   * @param ti
+   * @return true if made a base for a trampoline
+   */
+  boolean maybeMakeBaseVersionForPear(FeatureStructureImplC fs, TypeImpl ti) {
+    if (!inPearContext()) return false;
+    FsGenerator g = svd.generators[ti.getCode()];  // get pear generator or 
null
+    if (g == null) return false;
+    TOP baseFs;
+    try {
+      suspendPearContext();
+      svd.reuseId = fs._id;
+      baseFs = createFsFromGenerator(svd.baseGenerators, ti);
+    } finally {
+      restorePearContext();
+      svd.reuseId = 0;
+    }
+    svd.id2base.put(baseFs);
+    pearBaseFs = baseFs;
+    return true;
   }
+ 
+  private TOP createFsFromGenerator(FsGenerator[] gs, TypeImpl ti) {
+//    if (ti == null || gs == null || gs[ti.getCode()] == null) {
+//      System.out.println("debug");
+//    }
+    return gs[ti.getCode()].createFS(ti, this);
+  }
+  
+//  public int ll_createFSAnnotCheck(int typeCode) {
+//    TOP fs = createFSAnnotCheck(getTypeFromCode(typeCode));
+//    svd.id2fs.put(fs);  // required for low level, in order to "hold onto" / 
prevent GC of FS
+//    return fs._id;
+//  }
   
-  public TOP createArray(TypeImpl type, int arrayLength) {
-    TypeImpl_array tia = (TypeImpl_array) type;
-    if (tia.getComponentType().isPrimitive()) {
-      checkArrayPreconditions(arrayLength);  
-      return tia.getGeneratorArray().createFS(type, this, arrayLength); 
+  public TOP createArray(TypeImpl array_type, int arrayLength) {
+    TypeImpl_array tia = (TypeImpl_array) array_type;
+    TypeImpl componentType = tia.getComponentType();
+    if (componentType.isPrimitive()) {
+      checkArrayPreconditions(arrayLength);
+      switch (componentType.getCode()) {
+      case intTypeCode: return new IntegerArray(array_type, this, arrayLength);
+      case floatTypeCode: return new FloatArray(array_type, this, arrayLength);
+      case booleanTypeCode: return new BooleanArray(array_type, this, 
arrayLength);
+      case byteTypeCode: return new ByteArray(array_type, this, arrayLength);
+      case shortTypeCode: return new ShortArray(array_type, this, arrayLength);
+      case longTypeCode: return new LongArray(array_type, this, arrayLength);
+      case doubleTypeCode: return new DoubleArray(array_type, this, 
arrayLength);
+      case stringTypeCode: return new StringArray(array_type, this, 
arrayLength);
+      case javaObjectTypeCode: return new JavaObjectArray(array_type, this, 
arrayLength);
+      default: Misc.internalError();
+      }
+//      return tia.getGeneratorArray().createFS(type, this, arrayLength); 
 //      return 
(((FsGeneratorArray)getFsGenerator(type.getCode())).createFS(type, this, 
arrayLength));
     }
-    return (TOP) createArrayFS(type, arrayLength);
+    return (TOP) createArrayFS(array_type, arrayLength);
   }
 
   @Override
@@ -875,8 +1025,9 @@ public class CASImpl extends AbstractCas
   
   private ArrayFS createArrayFS(TypeImpl type, int length) {
     checkArrayPreconditions(length);
-    return (ArrayFS) getTypeSystemImpl().fsArrayType.getGeneratorArray()       
  // (((FsGeneratorArray)getFsGenerator(fsArrayTypeCode))
-        .createFS(type, this, length);
+    return (ArrayFS) new FSArray(type, this, length);         
+//        getTypeSystemImpl().fsArrayType.getGeneratorArray()         // 
(((FsGeneratorArray)getFsGenerator(fsArrayTypeCode))
+//        .createFS(type, this, length);
   }
   
   @Override
@@ -1197,15 +1348,17 @@ public class CASImpl extends AbstractCas
     // avoid race: two instances of a CAS from a pool attempting to commit the
     // ts
     // at the same time
+    final ClassLoader cl = getJCasClassLoader();
     synchronized (ts) {
       if (!ts.isCommitted()) {
-        TypeSystemImpl tsc = ts.commit();
+        TypeSystemImpl tsc = ts.commit(getJCasClassLoader());
         if (tsc != ts) {
           installTypeSystemInAllViews(tsc);
           ts = tsc;
         }
       }
     }       
+    svd.baseGenerators = svd.generators = ts.getGeneratorsForClassLoader(cl, 
false);  // false - not PEAR
     createIndexRepository();
     return ts;
   }
@@ -2115,7 +2268,9 @@ public class CASImpl extends AbstractCas
       }
     }
     TOP fs = (TOP) createFS(ti);
-    svd.id2fs.put(fs);
+    if (!fs._isPearTrampoline()) {
+      svd.id2fs.put(fs);  // hold on to it if nothing else is
+    }
     return fs._id;
   }
   
@@ -2248,11 +2403,20 @@ public class CASImpl extends AbstractCas
     }
   }
 
+  /**
+   * Safety - any time the low level API to a FS is requested,
+   * hold on to that FS until CAS reset to mimic how v2 works.
+   */
   @Override
   public final int ll_getFSRef(FeatureStructure fs) {
     if (null == fs) {
       return NULL;
     }
+    TOP fst = (TOP) fs;
+    if (fst._isPearTrampoline()) {
+      return fst._id;  // no need to hold on to this one - it's in jcas hash 
maps
+    }
+    svd.id2fs.putUnconditionally(fst);  // hold on to it
     return ((FeatureStructureImplC)fs)._id;
   }
 
@@ -2327,7 +2491,7 @@ public class CASImpl extends AbstractCas
 
   @Override
   public final int ll_getRefValue(int fsRef, int featureCode) {
-    return 
getFsFromId_checked(fsRef).getFeatureValue(getFeatFromCode_checked(featureCode)).id();
+    return 
getFsFromId_checked(fsRef).getFeatureValue(getFeatFromCode_checked(featureCode))._id();
   }
 
 //  public final int ll_getRefValueFeatOffset(int fsRef, int featureOffset) {
@@ -2380,7 +2544,7 @@ public class CASImpl extends AbstractCas
     if (doTypeChecks) {
       checkFsRefConditions(fsRef, featureCode);
     }
-    return 
getFsFromId_checked(fsRef).getFeatureValue(getFeatFromCode_checked(featureCode)).id();
+    return 
getFsFromId_checked(fsRef).getFeatureValue(getFeatFromCode_checked(featureCode))._id();
   }
   
   /**
@@ -2953,7 +3117,7 @@ public class CASImpl extends AbstractCas
 
   @Override
   public final int ll_getRefArrayValue(int fsRef, int position) {
-    return ((TOP)getRefArrayValue(((FSArray)getFsFromId_checked(fsRef)), 
position)).id();
+    return ((TOP)getRefArrayValue(((FSArray)getFsFromId_checked(fsRef)), 
position))._id();
   }
 
   private void throwAccessTypeError(int fsRef, int typeCode) {
@@ -3193,23 +3357,7 @@ public class CASImpl extends AbstractCas
   public void switchClassLoaderLockCasCL(ClassLoader newClassLoader) {
     // lock out CAS functions to which annotator should not have access
     enableReset(false);
-
-//    switchClassLoader(newClassLoader);
-  }
-
-  // switches ClassLoader but does not lock CAS
-  // needed for backward compatibility only
-  public void switchClassLoader(ClassLoader newClassLoader) {
-    if (null == newClassLoader) { // is null if no cl set
-      return;
-    }
-    if (newClassLoader != this.svd.jcasClassLoader) {
-      // System.out.println("Switching to new class loader");
-      this.svd.jcasClassLoader = newClassLoader;
-//      if (null != this.jcas) {
-//        ((JCasImpl) this.jcas).switchClassLoader(newClassLoader);
-//      }
-    }
+    svd.switchClassLoader(newClassLoader);
   }
 
 //  // internal use, public for cross-package ref
@@ -3221,16 +3369,7 @@ public class CASImpl extends AbstractCas
     // unlock CAS functions
     enableReset(true);
     // this might be called without the switch ever being called
-//    if (null == this.svd.previousJCasClassLoader) {
-//      return;
-//    }
-//    if (this.svd.previousJCasClassLoader != this.svd.jcasClassLoader) {
-//      // System.out.println("Switching back to previous class loader");
-//      this.svd.jcasClassLoader = this.svd.previousJCasClassLoader;
-//      if (null != this.jcas) {
-//        ((JCasImpl) 
this.jcas).switchClassLoader(this.svd.previousJCasClassLoader);
-//      }
-//    }
+    svd.restoreClassLoader();
 
   }
   
@@ -3578,7 +3717,7 @@ public class CASImpl extends AbstractCas
   public int ll_createAnnotation(int typeCode, int begin, int end) {
     TOP fs = createAnnotation(getTypeFromCode(typeCode), begin, end);
 //    setId2fs(fs);
-    return fs.id();
+    return fs._id();
   }
   
   /**
@@ -3652,7 +3791,6 @@ public class CASImpl extends AbstractCas
   public <T extends Annotation> T createDocumentAnnotationNoRemoveNoIndex(int 
length) {
     final TypeSystemImpl ts = getTypeSystemImpl();
     AnnotationFS docAnnot = createAnnotation(ts.docType, 0, length);
-    setId2FSs(docAnnot);  // because FeaturePath uses low-level access to it
     docAnnot.setStringValue(ts.langFeat, CAS.DEFAULT_LANGUAGE_NAME);
     return (T) docAnnot;    
   }
@@ -3743,7 +3881,7 @@ public class CASImpl extends AbstractCas
     
     FSIterator<FeatureStructure> it = 
getIndexRepository().getIndex(CAS.STD_ANNOTATION_INDEX, 
getTypeSystemImpl().docType).iterator();
     if (it.isValid()) {
-      return it.get().id();
+      return it.get()._id();
     }
     return 0;
   }
@@ -3819,7 +3957,7 @@ public class CASImpl extends AbstractCas
    */
   @Override
   public int ll_getSofa() {
-    return mySofaIsValid() ? mySofaRef.id() : 0;
+    return mySofaIsValid() ? mySofaRef._id() : 0;
   }
 
   @Override
@@ -4467,10 +4605,6 @@ public class CASImpl extends AbstractCas
     default: throw new IllegalArgumentException();
     }
   }
-
-  public TypeImpl getTypeImplFromJCasTypeIndex(int typeIndexID) {
-    return getTypeSystemImpl().getJCasRegisteredType(typeIndexID);
-  }
   
 //  /**
 //   * Copies a feature, from one fs to another
@@ -4557,32 +4691,65 @@ public class CASImpl extends AbstractCas
 
   /******************************************
    * PEAR support
-   *   Type system not modified - is in use on multiple threads
+   *   Don't modify the type system because it is in use on multiple threads
    *   
    *   Handling of id2fs for low level APIs:
    *     FSs in id2fs map are the outer non-pear ones
    *     Any gets do pear conversion if needed.
    *   
    ******************************************/
+  /**
+   * 3 cases:
+   *   1) no trampoline needed, no conversion, return the original fs
+   *   2) trampoline already exists - return that one
+   *   3) create new trampoline
+   * @param aFs
+   * @return
+   */
   static <T extends FeatureStructure> T pearConvert(T aFs) {
+    if (null == aFs) {
+      return null;
+    }
     final TOP fs = (TOP) aFs;
     final CASImpl view = fs._casView;
     final TypeImpl ti = fs._getTypeImpl();
-    final FsGenerator g = view.getPearGeneratorForType(ti);
-    view.svd.reuseId = fs._id;  // create new FS using base FS's ID
-    view.svd.pearBaseFs = fs;
+    final FsGenerator generator = view.svd.generators[ti.getCode()];
+    if (null == generator) {
+      return aFs;
+    }
+    return (T) view.pearConvert(fs, generator);
+  }  
+  
+  private TOP pearConvert(TOP fs, FsGenerator g) {
+    TOP r = svd.id2tramp.getReserve(fs._id);
+    if (r != null) {
+      return r;
+    }
+    
+    svd.reuseId = fs._id;  // create new FS using base FS's ID
+    pearBaseFs = fs;
     try {
-      return (T) g.createFS(ti, view);
+      r = g.createFS(fs._getTypeImpl(), this);
     } finally {
-      view.svd.reuseId = 0;
-      view.svd.pearBaseFs = null;
+      svd.reuseId = 0;
+      pearBaseFs = null;
     }
+    svd.id2tramp.put(r);
+    return r;
   }
   
-  private FsGenerator getPearGeneratorForType(TypeImpl ti) {
-    return null;  // TODO FIXME
+  /**
+   * Given a trampoline FS, return the corresponding base Fs
+   * Supports adding Fs (which must be a non-trampoline version) to indexes
+   * @param fs trampoline fs
+   * @return the corresponding base fs
+   */
+  <T extends TOP> T getBaseFsFromTrampoline(T fs) {
+    TOP r = svd.id2base.getReserve(fs._id);
+    assert r != null;
+    return (T) r;
   }
-
+  
   /******************************************
    * DEBUGGING and TRACING
    ******************************************/
@@ -4870,6 +5037,27 @@ public class CASImpl extends AbstractCas
   @Override
   @Deprecated
   public void setCAS(CAS cas) {}
+  
+  /**
+   * @return true if in Pear context, or external context outside 
AnalysisEngine having a UIMA Extension class loader
+   *                e.g., if calling a call-back routine loaded outside the AE.
+   */
+  boolean inPearContext() {
+    return svd.previousJCasClassLoader != null;
+  }
+  
+  /**
+   * Pear context suspended while creating a base version, when we need to 
create a new FS 
+   *   (we need to create both the base and the trampoline version)
+   */
+  private void suspendPearContext() {
+    svd.suspendPreviousJCasClassLoader = svd.previousJCasClassLoader;
+    svd.previousJCasClassLoader = null;
+  }
+  
+  private void restorePearContext() {
+    svd.previousJCasClassLoader = svd.suspendPreviousJCasClassLoader;
+  }
 
 //  int allocIntData(int sz) {
 //    

Modified: 
uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FeatureStructureImplC.java
URL: 
http://svn.apache.org/viewvc/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FeatureStructureImplC.java?rev=1756828&r1=1756827&r2=1756828&view=diff
==============================================================================
--- 
uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FeatureStructureImplC.java
 (original)
+++ 
uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FeatureStructureImplC.java
 Thu Aug 18 15:59:12 2016
@@ -35,7 +35,6 @@ import org.apache.uima.cas.impl.SlotKind
 import org.apache.uima.internal.util.Misc;
 import org.apache.uima.internal.util.StringUtils;
 import org.apache.uima.jcas.JCas;
-import org.apache.uima.jcas.cas.AnnotationBase;
 import org.apache.uima.jcas.cas.BooleanArray;
 import org.apache.uima.jcas.cas.ByteArray;
 import org.apache.uima.jcas.cas.CommonArray;
@@ -175,19 +174,29 @@ public class FeatureStructureImplC imple
   }
   
   /**
-   * For non-JCas use
+   * For non-JCas use, Internal Use Only, called by cas.createFS via generators
    * @param casView -
    * @param type -
    */
   protected FeatureStructureImplC(TypeImpl type, CASImpl casView) {
     _casView = casView;
     _typeImpl = type;
+    _id = casView.getNextFsId((TOP)this);   
     
-    FeatureStructureImplC baseFs = _casView.svd.pearBaseFs;
-    _intData = (baseFs == null) ? _allocIntData() : baseFs._intData;
-    _refData = (baseFs == null) ? _allocRefData() : baseFs._refData;    
+    if (_casView.maybeMakeBaseVersionForPear(this, _typeImpl)) {
+      _setPearTrampoline();
+    }
+
+    FeatureStructureImplC baseFs = _casView.pearBaseFs;
+    if (null != baseFs) {
+      _intData = baseFs._intData;
+      _refData = baseFs._refData;
+      _casView.pearBaseFs = null;
+    } else {
+      _intData = _allocIntData();
+      _refData = _allocRefData();
+    }
 
-    _id = casView.getNextFsId((TOP)this);   
     
     if (traceFSs && !(this instanceof CommonArray)) {
       _casView.traceFSCreate(this);
@@ -203,17 +212,26 @@ public class FeatureStructureImplC imple
   protected FeatureStructureImplC(JCasImpl jcasImpl) {
     _casView = jcasImpl.getCasImpl();
     _typeImpl = 
_casView.getTypeSystemImpl().getJCasRegisteredType(getTypeIndexID());
+    _id = _casView.getNextFsId((TOP)this); 
     
     if (null == _typeImpl) {
       throw new CASRuntimeException(CASRuntimeException.JCAS_TYPE_NOT_IN_CAS, 
this.getClass().getName());
     }
+
+    if (_casView.maybeMakeBaseVersionForPear(this, _typeImpl)) {
+      _setPearTrampoline();
+    }
     
-    FeatureStructureImplC baseFs = _casView.svd.pearBaseFs;
-    _intData = (baseFs == null) ? _allocIntData() : baseFs._intData;
-    _refData = (baseFs == null) ? _allocRefData() : baseFs._refData;    
+    FeatureStructureImplC baseFs = _casView.pearBaseFs;
+    if (null != baseFs) {
+      _intData = baseFs._intData;
+      _refData = baseFs._refData;
+      _casView.pearBaseFs = null;
+    } else {
+      _intData = _allocIntData();
+      _refData = _allocRefData();
+    }
     
-    _id = _casView.getNextFsId((TOP)this); 
-
     if (traceFSs && !(this instanceof CommonArray)) {
       _casView.traceFSCreate(this);
     }
@@ -296,7 +314,7 @@ public class FeatureStructureImplC imple
   public final int getAddress() { return _id; };
 
   @Override
-  public final int id() {return _id; };
+  public final int _id() {return _id; };
   
   /**
    * Returns the UIMA TypeImpl value
@@ -305,11 +323,7 @@ public class FeatureStructureImplC imple
   public Type getType() {
     return _typeImpl;
   }
-  
-  public TypeImpl getTypeImpl() {
-    return _typeImpl;
-  }
-  
+    
   /**
    * starts with _ 
    * @return the UIMA TypeImpl for this Feature Structure
@@ -525,7 +539,7 @@ public class FeatureStructureImplC imple
     if (IS_ENABLE_RUNTIME_FEATURE_VALUE_VALIDATION) 
featureValueValidation(feat, v);
 
     // no need to check for index corruption because fs refs can't be index 
keys
-    _setRefValueCommon(fi, v);
+    _setRefValueCommon(fi, _maybeGetBaseForPearFs((TOP)v));
     _casView.maybeLogUpdate(this, fi);
   }
   
@@ -537,9 +551,21 @@ public class FeatureStructureImplC imple
     _setRefValueCommon(adjOffset, v);
   }
 
-
-  public void _setFeatureValueNcWj(int adjOffset, Object v) { 
-    _setRefValueCommonWj(_getFeatFromAdjOffset(adjOffset, false), v);
+  /**
+   * Called when setting a FS value which might be a trampoline
+   * @param v the FS to check
+   * @return the FS or if it was a trampoline, the base FS
+   */
+  private TOP _maybeGetBaseForPearFs(TOP v) {
+    return (v == null) 
+             ? null
+             : v._isPearTrampoline() 
+                 ? v._casView.getBaseFsFromTrampoline(v)
+                 : v;
+  }
+  
+  public void _setFeatureValueNcWj(int adjOffset, FeatureStructure v) {
+    _setRefValueCommonWj(_getFeatFromAdjOffset(adjOffset, false), 
_maybeGetBaseForPearFs((TOP)v));
   }
 
   @Override
@@ -733,7 +759,12 @@ public class FeatureStructureImplC imple
   
   public TOP _getFeatureValueNc(FeatureImpl feat) { return 
_getFeatureValueNc(feat.getAdjustedOffset()); }
 
-  public TOP _getFeatureValueNc(int adjOffset) { return (TOP) 
_refData[adjOffset /*+ _getRefDataArrayOffset()*/]; }
+  public TOP _getFeatureValueNc(int adjOffset) { 
+    TOP r = (TOP) _refData[adjOffset /*+ _getRefDataArrayOffset()*/];
+    return (_casView.inPearContext()) 
+             ? _casView.pearConvert(r)
+             : r;      
+  }
  
   @Override
   public Object getJavaObjectValue(Feature feat) { 

Modified: 
uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsGeneratorArray.java
URL: 
http://svn.apache.org/viewvc/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsGeneratorArray.java?rev=1756828&r1=1756827&r2=1756828&view=diff
==============================================================================
--- 
uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsGeneratorArray.java
 (original)
+++ 
uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsGeneratorArray.java
 Thu Aug 18 15:59:12 2016
@@ -23,6 +23,7 @@ import org.apache.uima.jcas.cas.TOP;
 
 /**
  * A Functional Interface for generating Java Feature Structures
+ * NO LONGER USED
  */
 @FunctionalInterface
 public interface FsGeneratorArray {

Modified: 
uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIndex_bag.java
URL: 
http://svn.apache.org/viewvc/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIndex_bag.java?rev=1756828&r1=1756827&r2=1756828&view=diff
==============================================================================
--- 
uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIndex_bag.java
 (original)
+++ 
uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIndex_bag.java
 Thu Aug 18 15:59:12 2016
@@ -85,7 +85,7 @@ public class FsIndex_bag<T extends Featu
    */
   @Override
   public int compare(FeatureStructure fs1, FeatureStructure fs2) {
-    return (fs1 == fs2) ? 0 : (fs1.id() < fs2.id()) ? -1 : 1;
+    return (fs1 == fs2) ? 0 : (fs1._id() < fs2._id()) ? -1 : 1;
   }
 
   /*
@@ -185,7 +185,9 @@ public class FsIndex_bag<T extends Featu
    */
   @Override
   public FSIterator<T> iterator() {
-    return new FsIterator_bag<T>(this, type);
+    return casImpl.inPearContext()
+             ? new FsIterator_bag_pear<>(this, type)
+             : new FsIterator_bag     <>(this, type);
   }
   
   ObjHashSet<TOP> getObjHashSet() {

Modified: 
uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIndex_set_sorted.java
URL: 
http://svn.apache.org/viewvc/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIndex_set_sorted.java?rev=1756828&r1=1756827&r2=1756828&view=diff
==============================================================================
--- 
uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIndex_set_sorted.java
 (original)
+++ 
uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIndex_set_sorted.java
 Thu Aug 18 15:59:12 2016
@@ -130,7 +130,7 @@ public class FsIndex_set_sorted<T extend
           ? (o1, o2) -> {
               final int c = compare(o1,  o2); 
               // augment normal comparator with one that compares IDs if 
everything else equal
-              return (c == 0) ? (Integer.compare(o1.id(), o2.id())) : c;} 
+              return (c == 0) ? (Integer.compare(o1._id(), o2._id())) : c;} 
           : comparatorWithoutID;
     }          
 //    comparatorO = new Comparator() {
@@ -329,8 +329,9 @@ public class FsIndex_set_sorted<T extend
    
   @Override
   public FSIterator<T> iterator() {
-//    maybeProcessBulkAdds(); // moved to OrderedFsSet_array class
-    return new FsIterator_set_sorted<T>(this, type, this);
+    return casImpl.inPearContext()
+             ? new FsIterator_set_sorted_pear<>(this, type, this)
+             : new FsIterator_set_sorted     <>(this, type, this);
   }
     
 //  synchronized void maybeProcessBulkAdds() {

Modified: 
uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_bag.java
URL: 
http://svn.apache.org/viewvc/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_bag.java?rev=1756828&r1=1756827&r2=1756828&view=diff
==============================================================================
--- 
uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_bag.java
 (original)
+++ 
uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_bag.java
 Thu Aug 18 15:59:12 2016
@@ -32,7 +32,7 @@ class FsIterator_bag<T extends FeatureSt
   
   private boolean isGoingForward = true;
 
-  final private FsIndex_bag<T> fsBagIndex; // just an optimization, is == to 
fsLeafIndexImpl from super class, allows dispatch w/o casting
+  final protected FsIndex_bag<T> fsBagIndex; // just an optimization, is == to 
fsLeafIndexImpl from super class, allows dispatch w/o casting
 
   FsIterator_bag(FsIndex_bag<T> fsBagIndex, TypeImpl ti) {
     super(ti, null);  // null: null comparator for bags
@@ -142,10 +142,14 @@ class FsIterator_bag<T extends FeatureSt
   @Override
   public FsIterator_bag<T> copy() {
     FsIterator_bag<T> copy = new FsIterator_bag<T>(this.fsBagIndex, this.ti);
-    copy.position = position;
-    copy.isGoingForward = isGoingForward;   
+    copyCommonSetup(copy);
     return copy;
   }
+  
+  protected void copyCommonSetup(FsIterator_bag<T> copy) {
+    copy.position = position;
+    copy.isGoingForward = isGoingForward;
+  }
 
   /* (non-Javadoc)
    * @see org.apache.uima.cas.impl.LowLevelIterator#ll_indexSize()

Added: 
uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_bag_pear.java
URL: 
http://svn.apache.org/viewvc/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_bag_pear.java?rev=1756828&view=auto
==============================================================================
--- 
uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_bag_pear.java
 (added)
+++ 
uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_bag_pear.java
 Thu Aug 18 15:59:12 2016
@@ -0,0 +1,49 @@
+/*
+ * 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.cas.impl;
+
+import org.apache.uima.cas.FeatureStructure;
+
+/**
+ * @param <T> the type of FSs being returned from the iterator, supplied by 
the calling context
+ */
+class FsIterator_bag_pear<T extends FeatureStructure> extends 
FsIterator_bag<T> {
+
+  FsIterator_bag_pear(FsIndex_bag<T> fsBagIndex, TypeImpl ti) {
+    super(fsBagIndex, ti);
+  }    
+
+  @Override
+  public T get() {
+    return CASImpl.pearConvert(super.get());
+  }
+
+  @Override
+  public T getNvc() {
+    return CASImpl.pearConvert(super.getNvc());
+  }
+  
+  @Override
+  public FsIterator_bag_pear<T> copy() {
+    FsIterator_bag_pear<T> copy = new FsIterator_bag_pear<T>(this.fsBagIndex, 
this.ti);
+    copyCommonSetup(copy);
+    return copy;
+  }
+}
\ No newline at end of file

Modified: 
uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_set_sorted.java
URL: 
http://svn.apache.org/viewvc/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_set_sorted.java?rev=1756828&r1=1756827&r2=1756828&view=diff
==============================================================================
--- 
uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_set_sorted.java
 (original)
+++ 
uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_set_sorted.java
 Thu Aug 18 15:59:12 2016
@@ -38,7 +38,7 @@ class FsIterator_set_sorted<T extends Fe
   // in UIMA we can use, say an Annotation instance as a moveTo arg, for a 
navSet of some subtype of Annotation.
   final private NavigableSet<TOP> navSet;  // == fsSortIndex.getNavigableSet()
   
-  final private FsIndex_set_sorted<T> fsSetSortIndex;  // only for 
ll_getIndex, backwards compatibility
+  final protected FsIndex_set_sorted<T> fsSetSortIndex;  // only for 
ll_getIndex, backwards compatibility
   
   private T currentElement;
   

Added: 
uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_set_sorted_pear.java
URL: 
http://svn.apache.org/viewvc/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_set_sorted_pear.java?rev=1756828&view=auto
==============================================================================
--- 
uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_set_sorted_pear.java
 (added)
+++ 
uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_set_sorted_pear.java
 Thu Aug 18 15:59:12 2016
@@ -0,0 +1,54 @@
+/*
+ * 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.cas.impl;
+
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.NavigableSet;
+import java.util.NoSuchElementException;
+
+import org.apache.uima.cas.FeatureStructure;
+import org.apache.uima.internal.util.OrderedFsSet_array;
+import org.apache.uima.jcas.cas.TOP;
+
+/**
+ * @param <T> the type of FSs being returned from the iterator, supplied by 
the calling context
+ */
+class FsIterator_set_sorted_pear<T extends FeatureStructure> extends 
FsIterator_set_sorted<T> {
+
+  FsIterator_set_sorted_pear(FsIndex_set_sorted<T> fsSetSortIndex, TypeImpl 
ti, Comparator<FeatureStructure> comp) {
+    super(fsSetSortIndex, ti, comp);
+  }    
+
+  @Override
+  public T get() {
+    return CASImpl.pearConvert(super.get());
+  }
+
+  @Override
+  public T getNvc() {
+    return CASImpl.pearConvert(super.getNvc());
+  }
+
+  @Override
+  public FsIterator_set_sorted_pear<T> copy() {
+    return new FsIterator_set_sorted_pear<T>(this.fsSetSortIndex, ti, 
this.comparator);
+  }
+}
\ No newline at end of file

Modified: 
uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/Id2FS.java
URL: 
http://svn.apache.org/viewvc/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/Id2FS.java?rev=1756828&r1=1756827&r2=1756828&view=diff
==============================================================================
--- 
uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/Id2FS.java
 (original)
+++ 
uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/Id2FS.java
 Thu Aug 18 15:59:12 2016
@@ -66,6 +66,10 @@ public class Id2FS {
     assert prev == null;
   }
   
+  void putUnconditionally(TOP fs) {
+    id2fs.put(fs._id, fs);
+  }
+  
   /**
    * make an id map to an fs, asserting there was a previous mapping for this 
id
    * @param id -

Added: 
uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/MethodHandlesLookup.java
URL: 
http://svn.apache.org/viewvc/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/MethodHandlesLookup.java?rev=1756828&view=auto
==============================================================================
--- 
uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/MethodHandlesLookup.java
 (added)
+++ 
uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/MethodHandlesLookup.java
 Thu Aug 18 15:59:12 2016
@@ -0,0 +1,32 @@
+/*
+ * 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.cas.impl;
+
+import java.lang.invoke.MethodHandles;
+
+public class MethodHandlesLookup {
+
+  private MethodHandlesLookup(){}
+  
+  public static MethodHandles.Lookup getMethodHandlesLookup() {
+    return MethodHandles.lookup();
+  }
+
+}

Modified: 
uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/TypeImpl.java
URL: 
http://svn.apache.org/viewvc/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/TypeImpl.java?rev=1756828&r1=1756827&r2=1756828&view=diff
==============================================================================
--- 
uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/TypeImpl.java
 (original)
+++ 
uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/TypeImpl.java
 Thu Aug 18 15:59:12 2016
@@ -35,7 +35,6 @@ import org.apache.uima.cas.Feature;
 import org.apache.uima.cas.Type;
 import org.apache.uima.cas.TypeSystem;
 import org.apache.uima.cas.admin.CASAdminException;
-import org.apache.uima.cas.impl.FSClassRegistry.JCasClassInfo;
 import org.apache.uima.cas.impl.SlotKinds.SlotKind;
 import org.apache.uima.internal.util.Misc;
 import org.apache.uima.jcas.cas.CommonArray;
@@ -71,8 +70,9 @@ public class TypeImpl implements Type, C
    *   set when type is committed and JCas cover classes are loaded
    */
   protected       Class<?> javaClass;
-  private         JCasClassInfo jcasClassInfo; 
-  private         FsGenerator generator;  // not used for arrays
+    // next 2 not kept in the type, because there could be different versions 
for different class loaders
+//  private         JCasClassInfo jcasClassInfo; 
+//  private         FsGenerator generator;  // not used for arrays
 //  final protected Class<?> getter_funct_intfc_class;
 //  final protected Class<?> setter_funct_intfc_class;
   /* ***************** boolean flags *****************/
@@ -851,18 +851,13 @@ public class TypeImpl implements Type, C
 
   
   /**
+   * Of limited use because the java class value, over time, is multi- valued; 
e.g. when PEARs are in use,
+   * or different extension classpaths are in use for multiple pipelines.
    * @return the javaClass
    */
   Class<?> getJavaClass() {
     return javaClass;
   }
-
-  Class<?> getJavaPrimitiveClassOrObject() {
-    if (!isPrimitive() || isStringOrStringSubtype()) {
-      return Object.class;
-    }
-    return javaClass;
-  }
   
   /**
    * @param javaClass the javaClass to set
@@ -1032,28 +1027,28 @@ public class TypeImpl implements Type, C
     staticMergedRefFeaturesList = v;
   }
 
-  /**
-   * @return the generator
-   */
-  FsGenerator getGenerator() {
-    return generator;
-  }
+//  /**
+//   * @return the generator
+//   */
+//  FsGenerator getGenerator() {
+//    return generator;
+//  }
 
-  /**
-   * @return the jcasClassInfo
-   */
-  JCasClassInfo getJcasClassInfo() {
-    return jcasClassInfo;
-  }
+//  /**
+//   * @return the jcasClassInfo
+//   */
+//  JCasClassInfo getJcasClassInfo() {
+//    return jcasClassInfo;
+//  }
 
-  /**
-   * @param jcasClassInfo the jcasClassInfo to set
-   */
-  void setJcasClassInfo(JCasClassInfo jcasClassInfo) {
-    this.jcasClassInfo = jcasClassInfo;
-    Object g = jcasClassInfo.generator;
-    this.generator = (g instanceof FsGenerator) ? (FsGenerator)g : null;
-  }
+//  /**
+//   * @param jcasClassInfo the jcasClassInfo to set
+//   */
+//  void setJcasClassInfo(JCasClassInfo jcasClassInfo) {
+//    this.jcasClassInfo = jcasClassInfo;
+//    Object g = jcasClassInfo.generator;
+//    this.generator = (g instanceof FsGenerator) ? (FsGenerator)g : null;
+//  }
 
   //  public boolean hasOnlyInts() {
 //    return hasOnlyInts;

Modified: 
uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/TypeImpl_array.java
URL: 
http://svn.apache.org/viewvc/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/TypeImpl_array.java?rev=1756828&r1=1756827&r2=1756828&view=diff
==============================================================================
--- 
uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/TypeImpl_array.java
 (original)
+++ 
uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/TypeImpl_array.java
 Thu Aug 18 15:59:12 2016
@@ -19,7 +19,6 @@
 
 package org.apache.uima.cas.impl;
 
-import org.apache.uima.cas.impl.FSClassRegistry.JCasClassInfo;
 import org.apache.uima.cas.impl.SlotKinds.SlotKind;
 
 public class TypeImpl_array extends TypeImpl implements TypeSystemConstants {
@@ -143,15 +142,6 @@ public class TypeImpl_array extends Type
   }
 
   /**
-   * @param jcasClassInfo the jcasClassInfo to set
-   */
-  @Override
-  void setJcasClassInfo(JCasClassInfo jcasClassInfo) {
-    super.setJcasClassInfo(jcasClassInfo);
-    this.generatorArray = (FsGeneratorArray)jcasClassInfo.generator;
-  }
-
-  /**
    * @return the generatorArray
    */
   FsGeneratorArray getGeneratorArray() {

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=1756828&r1=1756827&r2=1756828&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
 Thu Aug 18 15:59:12 2016
@@ -347,11 +347,18 @@ public class TypeSystemImpl implements T
   { types.add(null); }  // use up slot 0
 
   /**
-   * used as a map, the key is the JCas loaded type id, set once when each 
JCas class is loaded.
+   * Used to go from a JCas class's JCasTypeID to the corresponding UIMA type 
for this type system.
+   *   - when doing "new Foo(jcas)"
+   *   - when referring to a type using its JCas typeID
+   *   
+   * Used as a map, the key is the JCas loaded type id, set once when each 
JCas class is loaded.
    * value is the corresponding TypeImpl
    * 
    * When multiple type systems are being initialized in parallel, this list 
maybe updated
    * on different threads.  Access to it is synchronized on the object itself
+   * 
+   * A single JCas type ID (corresponding to a single JCas type) might be used 
for many UIMA types.
+   * but they are always in a type hierarchy, and the top most one is the one 
stored here
    */
   private final List<TypeImpl> jcasRegisteredTypes = new 
ArrayList<>(INIT_SIZE_ARRAYS_BUILT_IN_TYPES);
   /**
@@ -403,7 +410,12 @@ public class TypeSystemImpl implements T
   FeatureImpl sofaUri;
   FeatureImpl annotBaseSofaFeat;
 
-
+  /**
+   * Cache for implementing map from type code -> FsGenerator
+   * Shared by all CASes using this type system
+   *   Excludes FsGeneratorArrays - those are built-in and constant 
+   */
+  private final Map<ClassLoader, FsGenerator[]> generatorsByClassLoader = new 
IdentityHashMap<>();
 
   public TypeSystemImpl() {
 
@@ -648,7 +660,7 @@ public class TypeSystemImpl implements T
   }
 
   public final int getTypeArraySize() {
-    return getNumberOfTypes() + getSmallestType();
+    return types.size(); //        getNumberOfTypes() + getSmallestType();
   }
 
   public Vector<Feature> getIntroFeatures(Type type) {
@@ -1259,6 +1271,10 @@ public class TypeSystemImpl implements T
    */
   @Override
   public TypeSystemImpl commit() {
+    return commit(this.getClass().getClassLoader());  // default if not called 
with a CAS context 
+  }
+  
+  public TypeSystemImpl commit(ClassLoader cl) {
     synchronized(this) {
       if (this.locked) {
         return this; // might be called multiple times, but only need to do 
once
@@ -1304,8 +1320,11 @@ public class TypeSystemImpl implements T
       // Has to follow above, because information computed above is used when
       // loading and checking JCas classes
       
+      
+      // not done here, done in caller (CASImpl commitTypeSystem), 
+      // when it gets the generators for the class loader for this type system 
for the first time.
 //      fsClassRegistry = new FSClassRegistry(this, true);
-      FSClassRegistry.loadAtTypeSystemCommitTime(this, true);
+//      FSClassRegistry.loadAtTypeSystemCommitTime(this, true, cl);
       
       this.locked = true;
       return this;
@@ -2336,12 +2355,32 @@ public class TypeSystemImpl implements T
 //    return fsClassRegistry;
 //  }
   
+  /**
+   * 
+   * @param typeIndexID the JCasTypeID for the JCas cover class that will be 
used when creating instances of ti
+   *                       - may be a supertype of ti, if ti has no JCas class 
itself
+   *                       - may be a subtype of the supertype of ti, if ti 
has no JCas class itself
+   * @param ti the UIMA type
+   */
   void setJCasRegisteredType(int typeIndexID, TypeImpl ti) {
 //    if (typeIndexID == 0 && !ti.getShortName().equals("TOP")) {
 //      System.out.println("debug");
 //    }
     synchronized (jcasRegisteredTypes) {
-      Misc.setWithExpand(jcasRegisteredTypes, typeIndexID, ti);
+      TypeImpl existing = Misc.getWithExpand(jcasRegisteredTypes,  
typeIndexID);
+      if (existing != null) {
+        if (ti != existing) {
+          // allowed 
+          if (ti == null) {
+            Misc.internalError();
+          }
+          if (!existing.subsumes(ti)) {
+            Misc.internalError();
+          }
+        }
+      } else {
+        jcasRegisteredTypes.set(typeIndexID, ti);
+      }
     }
   }
   
@@ -2508,5 +2547,22 @@ public class TypeSystemImpl implements T
       }
     }
   }
+  
+  /**
+   * Called when switching or initializing CAS's shared-view-data instance of 
FsGenerator[]
+   * @param cl the class loader
+   * @param baseGenerators null or the outside-of-PEARs (base) generators
+   * @return the generators
+   */
+  public FsGenerator[] getGeneratorsForClassLoader(ClassLoader cl, boolean 
isPear) {
+    synchronized (generatorsByClassLoader) {
+      FsGenerator[] g = generatorsByClassLoader.get(cl);
+      if (g == null) {
+        g = FSClassRegistry.getGeneratorsForClassLoader(cl, isPear, this);
+        generatorsByClassLoader.put(cl, g);
+      }
+      return g;
+    }
+  }
 
 }


Reply via email to