private FeatureStructure copyFsInner(FeatureStructure aFS) {
// FS must be in the source CAS
assert ((CASImpl) aFS.getCAS()).getBaseCAS() == mSrcBaseCas;
// check if we already copied this FS
FeatureStructure copy = (FeatureStructure) mFsMap.get(aFS);
if (copy != null)
return copy;
// get the type of the FS
Type srcType = aFS.getType();
// Certain types need to be handled specially
// Sofa - cannot be created by normal methods. Instead, we return the Sofa with the
// same Sofa ID in the target CAS. If it does not exist it will be created.
if (aFS instanceof SofaFS) {
String destSofaId = getDestSofaId(((SofaFS) aFS).getSofaID());
return getOrCreateView(mDestBaseCas, destSofaId).getSofa();
}
// DocumentAnnotation - instead of creating a new instance, reuse the automatically created
// instance in the destination view.
if (isDocumentAnnotation(aFS)) {
String destViewName = getDestSofaId(((AnnotationFS) aFS).getView().getViewName());
// the DocumentAnnotation could be indexed in a different view than the one being copied
// Note: The view might not exist in the target
// but this is unlikely. To have this case this would require
// indexing some other feature structure in this view, which, in turn,
// has a reference to the DocumentAnnotation FS belonging to another view
CAS destView = getOrCreateView(mDestBaseCas, destViewName);
FeatureStructure destDocAnnot = destView.getDocumentAnnotation();
if (destDocAnnot != null) { // Note: is always non-null, getDocumentAnnotation creates if not exist
copyFeatures(aFS, destDocAnnot);
}
return destDocAnnot;
}
// Arrays - need to be created a populated differently than "normal" FS
if (aFS.getType().isArray()) {
copy = copyArray(aFS);
mFsMap.put(aFS, copy);
return copy;
}
// create a new FS of the same type in the target CAS
Type destType = (mDestBaseCas.getTypeSystem() == mSrcBaseCas.getTypeSystem()) ? srcType : mDestBaseCas
.getTypeSystem().getType(srcType.getName());
if (destType == null) {
// If in lenient mode, do not act on this FS. Instead just
// return (null) to the caller and let the caller deal with this case.
if (lenient) {
return null; // No FS to create
} else {
throw new UIMARuntimeException(UIMARuntimeException.TYPE_NOT_FOUND_DURING_CAS_COPY,
new Object[] { srcType.getName() });
}
}
// We need to use the LowLevel CAS interface to create the FS, because the usual
// CAS.createFS() call doesn't allow us to create subtypes of AnnotationBase from
// a base CAS. In any case we don't need the Sofa reference to be automatically
// set because we'll set it manually when in the copyFeatures method.
int typeCode = mLowLevelDestCas.ll_getTypeSystem().ll_getCodeForType(destType);
int destFsAddr = mLowLevelDestCas.ll_createFS(typeCode);
FeatureStructure destFs = mLowLevelDestCas.ll_getFSForRef(destFsAddr);
// add to map so we don't try to copy this more than once
mFsMap.put(aFS, destFs);
fsToDo.add(aFS); // order important