*/
private void readFS(final int addr, Attributes attrs, boolean toIndex) throws SAXParseException {
// Hang on address for setting content feature
this.currentAddr = addr;
int id = -1;
IntVector indexRep = new IntVector(); // empty means not indexed
String attrName, attrValue;
final int heapValue = cas.getHeapValue(addr);
final Type type = cas.ll_getTypeSystem().ll_getTypeForCode(cas.ll_getFSRefType(addr));
// Special handling for Sofas
if (sofaTypeCode == heapValue) {
// create some maps to handle v1 format XCAS ...
// ... where the sofa feature of annotations was an int not a ref
// determine if this is the one and only initial view Sofa
boolean isInitialView = false;
String sofaID = attrs.getValue(CAS.FEATURE_BASE_NAME_SOFAID);
if (sofaID.equals("_DefaultTextSofaName")) {
sofaID = CAS.NAME_DEFAULT_SOFA;
}
// if (uimaContext != null) {
// // Map incoming SofaIDs
// sofaID = uimaContext.mapToSofaID(sofaID).getSofaID();
// }
if (sofaID.equals(CAS.NAME_DEFAULT_SOFA)) {
isInitialView = true;
}
// get the sofaNum
String sofaNum = attrs.getValue(CAS.FEATURE_BASE_NAME_SOFANUM);
int thisSofaNum = Integer.parseInt(sofaNum);
// get the sofa's FeatureStructure id
int sofaFsId = Integer.parseInt(attrs.getValue(XCASSerializer.ID_ATTR_NAME));
// for v1 and v2 formats, create the index map
// ***we assume Sofas are always received in Sofanum order***
// Two scenarios ... the initial view is the first sofa, or not.
// If not, the _indexed values need to be remapped to leave room for the initial view,
// which may or may not be in the received CAS.
if (this.indexMap.size() == 1) {
if (isInitialView) {
// the first Sofa an initial view
if (thisSofaNum == 2) {
// this sofa was mapped to the initial view
this.indexMap.add(-1); // for this CAS, there should not be a sofanum = 1
this.indexMap.add(1); // map 2 to 1
this.nextIndex = 2;
} else {
this.indexMap.add(1);
this.nextIndex = 2;
}
} else {
if (thisSofaNum > 1) {
// the first Sofa not initial, but sofaNum > 1
// must be a v2 format, and sofaNum better be 2
this.indexMap.add(1);
assert (thisSofaNum == 2);
this.indexMap.add(2);
this.nextIndex = 3;
} else {
// must be v1 format
this.indexMap.add(2);
this.nextIndex = 3;
}
}
} else {
// if the new Sofa is the initial view, always map to 1
if (isInitialView) {
// the initial view is not the first
// if v2 format, space already reserved in mapping
if (this.indexMap.size() == thisSofaNum) {
// v1 format, add mapping for initial view
this.indexMap.add(1);
}
} else {
this.indexMap.add(this.nextIndex);
this.nextIndex++;
}
}
// Now update the mapping from annotation int to ref values
if (this.sofaRefMap.size() == thisSofaNum) {
// Sofa received in sofaNum order, add new one
this.sofaRefMap.add(sofaFsId);
} else if (this.sofaRefMap.size() > thisSofaNum) {
// new Sofa has lower sofaNum than last one
this.sofaRefMap.set(thisSofaNum, sofaFsId);
} else {
// new Sofa has skipped ahead more than 1
this.sofaRefMap.setSize(thisSofaNum + 1);
this.sofaRefMap.set(thisSofaNum, sofaFsId);
}
}
for (int i = 0; i < attrs.getLength(); i++) {
attrName = attrs.getQName(i);
attrValue = attrs.getValue(i);
if (attrName.startsWith(reservedAttrPrefix)) {
if (attrName.equals(XCASSerializer.ID_ATTR_NAME)) {
try {
id = Integer.parseInt(attrValue);
} catch (NumberFormatException e) {
throw createException(XCASParsingException.ILLEGAL_ID, attrValue);
}
} else if (attrName.equals(XCASSerializer.CONTENT_ATTR_NAME)) {
this.currentContentFeat = attrValue;
// this.state = CONTENT_STATE; APL-6/28/04 - removed, see below
} else if (attrName.equals(XCASSerializer.INDEXED_ATTR_NAME)) {
// if (attrValue.equals(XCASSerializer.TRUE_VALUE) && toIndex)
String[] arrayvals = parseArray(attrValue);
for (int s = 0; s < arrayvals.length; s++) {
indexRep.add(Integer.parseInt(arrayvals[s]));
}
} else {
handleFeature(type, addr, attrName, attrValue, false);
}
} else {