You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@uima.apache.org by al...@apache.org on 2007/02/27 21:58:40 UTC

svn commit: r512404 [2/2] - in /incubator/uima/uimaj/trunk/uimaj-core/src: main/java/org/apache/uima/cas/impl/ main/java/org/apache/uima/internal/util/ test/java/org/apache/uima/cas/impl/ test/java/org/apache/uima/cas_data/impl/ test/resources/ExampleCas/

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?view=diff&rev=512404&r1=512403&r2=512404
==============================================================================
--- 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 Tue Feb 27 12:58:39 2007
@@ -28,34 +28,49 @@
 import java.io.StringReader;
 import java.io.StringWriter;
 import java.util.Iterator;
+import java.util.List;
+import java.util.Stack;
 
+import javax.xml.parsers.FactoryConfigurationError;
+import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.parsers.SAXParser;
 import javax.xml.parsers.SAXParserFactory;
 
 import junit.framework.TestCase;
 
 import org.apache.uima.UIMAFramework;
+import org.apache.uima.cas.ArrayFS;
 import org.apache.uima.cas.CAS;
 import org.apache.uima.cas.FSIndex;
+import org.apache.uima.cas.FSIterator;
 import org.apache.uima.cas.Feature;
 import org.apache.uima.cas.FeatureStructure;
 import org.apache.uima.cas.IntArrayFS;
 import org.apache.uima.cas.StringArrayFS;
 import org.apache.uima.cas.Type;
 import org.apache.uima.cas.TypeSystem;
+import org.apache.uima.cas.impl.XmiSerializationSharedData.OotsElementData;
+import org.apache.uima.cas.impl.XmiSerializationSharedData.XmiArrayElement;
 import org.apache.uima.cas.text.AnnotationFS;
 import org.apache.uima.cas_data.impl.CasComparer;
+import org.apache.uima.internal.util.XmlAttribute;
+import org.apache.uima.internal.util.XmlElementNameAndContents;
 import org.apache.uima.resource.metadata.FsIndexDescription;
+import org.apache.uima.resource.metadata.TypeDescription;
 import org.apache.uima.resource.metadata.TypeSystemDescription;
 import org.apache.uima.resource.metadata.impl.TypePriorities_impl;
 import org.apache.uima.resource.metadata.impl.TypeSystemDescription_impl;
 import org.apache.uima.test.junit_extension.JUnitExtension;
 import org.apache.uima.util.CasCreationUtils;
+import org.apache.uima.util.FileUtils;
 import org.apache.uima.util.XMLInputSource;
 import org.apache.uima.util.XMLSerializer;
+import org.xml.sax.Attributes;
 import org.xml.sax.ContentHandler;
 import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
 import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.DefaultHandler;
 
 
 public class XmiCasDeserializerTest extends TestCase {
@@ -109,22 +124,19 @@
     serCasStream.close();
 
     // reserialize as XMI
-    StringWriter sw = new StringWriter();
-    XMLSerializer xmlSer = new XMLSerializer(sw, false);
-    XmiCasSerializer xmiSer = new XmiCasSerializer(cas.getTypeSystem());
-    xmiSer.serialize(cas, xmlSer.getContentHandler());
-    String xml = sw.getBuffer().toString();
-
+    String xml = serialize(cas, null);
+    
     // deserialize into another CAS
     CAS cas2 = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes);
     XmiCasDeserializer deser2 = new XmiCasDeserializer(cas2.getTypeSystem());
     ContentHandler deserHandler2 = deser2.getXmiCasHandler(cas2);
     xmlReader.setContentHandler(deserHandler2);
     xmlReader.parse(new InputSource(new StringReader(xml)));
-
+    
     // compare
     assertEquals(cas.getAnnotationIndex().size(), cas2.getAnnotationIndex().size());
-    // CasComparer.assertEquals(tcas,tcas2);
+    assertEquals(cas.getDocumentText(), cas2.getDocumentText());
+    CasComparer.assertEquals(cas,cas2);
 
     // check that array refs are not null
     Type entityType = cas2.getTypeSystem().getType("org.apache.uima.testTypeSystem.Entity");
@@ -417,5 +429,472 @@
     bais.close();
     
     CasComparer.assertEquals(cas, cas2);
+  }
+  
+  public void testMerging() throws Exception {
+    // deserialize a complex CAS from XCAS
+    CAS cas = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes);
+    InputStream serCasStream = new FileInputStream(JUnitExtension.getFile("ExampleCas/cas.xml"));
+    XCASDeserializer.deserialize(serCasStream, cas);
+    serCasStream.close();
+    int numAnnotations = cas.getAnnotationIndex().size(); //for comparison later
+    String docText = cas.getDocumentText(); //for comparison later
+    
+    // do XMI serialization to a string, using XmiSerializationSharedData
+    // to keep track of maximum ID generated
+    XmiSerializationSharedData serSharedData = new XmiSerializationSharedData();
+    String xmiStr = serialize(cas, serSharedData);
+    int maxOutgoingXmiId = serSharedData.getMaxXmiId();
+    
+    //deserialize into two new CASes, again using XmiSerializationSharedData so
+    //we can get consistent IDs later.  
+    CAS newCas1 = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes);
+    XmiSerializationSharedData deserSharedData1 = new XmiSerializationSharedData();
+    deserialize(xmiStr, newCas1, deserSharedData1, false, -1);
+    
+    CAS newCas2 = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes);
+    XmiSerializationSharedData deserSharedData2 = new XmiSerializationSharedData();
+    deserialize(xmiStr, newCas2, deserSharedData2, false, -1);
+    
+    //add new FS to each new CAS
+    createPersonAnnot(newCas1, 0, 10);
+    createPersonAnnot(newCas1, 20, 30);
+    createPersonAnnot(newCas2, 40, 50);
+    AnnotationFS person = createPersonAnnot(newCas2, 60, 70);
+    
+    //add an Owner relation that points to an organization in the original CAS,
+    //to test links across merge boundary
+    Type orgType = newCas2.getTypeSystem().getType(
+            "org.apache.uima.testTypeSystem.Organization");
+    AnnotationFS org = (AnnotationFS)newCas2.getAnnotationIndex(orgType).iterator().next();
+    Type ownerType = newCas2.getTypeSystem().getType(
+            "org.apache.uima.testTypeSystem.Owner");
+    Feature argsFeat = ownerType.getFeatureByBaseName("relationArgs");
+    Feature componentIdFeat = ownerType.getFeatureByBaseName("componentId");
+    Type relArgsType = newCas2.getTypeSystem().getType(
+            "org.apache.uima.testTypeSystem.BinaryRelationArgs");
+    Feature domainFeat = relArgsType.getFeatureByBaseName("domainValue");
+    Feature rangeFeat = relArgsType.getFeatureByBaseName("rangeValue");
+    AnnotationFS ownerAnnot = newCas2.createAnnotation(ownerType, 0, 70);
+    FeatureStructure relArgs = newCas2.createFS(relArgsType);
+    relArgs.setFeatureValue(domainFeat, person);
+    relArgs.setFeatureValue(rangeFeat, org);
+    ownerAnnot.setFeatureValue(argsFeat, relArgs);
+    ownerAnnot.setStringValue(componentIdFeat, "XCasDeserializerTest");
+    newCas2.addFsToIndexes(ownerAnnot);
+    int orgBegin = org.getBegin();
+    int orgEnd = org.getEnd();
+    
+    //add Sofas
+    CAS newView1 = newCas1.createView("newSofa1");
+    final String sofaText1 = "This is a new Sofa, created in CAS 1.";
+    newView1.setDocumentText(sofaText1);
+    final String annotText = "Sofa";
+    int annotStart1 = sofaText1.indexOf(annotText);
+    AnnotationFS annot1 = newView1.createAnnotation(orgType, annotStart1, annotStart1 + annotText.length());
+    newView1.addFsToIndexes(annot1);
+    CAS newView2 = newCas1.createView("newSofa2");
+    final String sofaText2 = "This is another new Sofa, created in CAS 2.";
+    newView2.setDocumentText(sofaText2);
+    int annotStart2 = sofaText2.indexOf(annotText);
+    AnnotationFS annot2 = newView2.createAnnotation(orgType, annotStart2, annotStart2 + annotText.length());
+    newView2.addFsToIndexes(annot2);
+
+    //re-serialize each new CAS back to XMI, keeping consistent ids
+    String newSerCas1 = serialize(newCas1, deserSharedData1);
+    String newSerCas2 = serialize(newCas2, deserSharedData2);
+    
+    //merge the two XMI CASes back into the original CAS
+    XmiSerializationSharedData deserSharedData3 = new XmiSerializationSharedData();
+    deserialize(newSerCas1, cas, deserSharedData3, false, -1);
+    
+    assertEquals(numAnnotations +2, cas.getAnnotationIndex().size());
+    
+    deserialize(newSerCas2, cas, deserSharedData3, false, maxOutgoingXmiId);
+    
+    assertEquals(numAnnotations + 5, cas.getAnnotationIndex().size());
+    
+    assertEquals(docText, cas.getDocumentText());
+    
+    //check covered text of annotations
+    FSIterator iter = cas.getAnnotationIndex().iterator();
+    while (iter.hasNext()) {
+      AnnotationFS annot = (AnnotationFS)iter.next();
+      assertEquals(cas.getDocumentText().substring(
+              annot.getBegin(), annot.getEnd()), annot.getCoveredText());
+    }
+    //check Owner annotation we created to test link across merge boundary
+    iter = cas.getAnnotationIndex(ownerType).iterator();
+    while (iter.hasNext()) {
+      AnnotationFS annot = (AnnotationFS)iter.next();
+      String componentId = annot.getStringValue(componentIdFeat);
+      if ("XCasDeserializerTest".equals(componentId)) {
+        FeatureStructure targetRelArgs = annot.getFeatureValue(argsFeat);
+        AnnotationFS targetDomain = (AnnotationFS)targetRelArgs.getFeatureValue(domainFeat);
+        assertEquals(60, targetDomain.getBegin());
+        assertEquals(70, targetDomain.getEnd());
+        AnnotationFS targetRange = (AnnotationFS)targetRelArgs.getFeatureValue(rangeFeat);
+        assertEquals(orgBegin, targetRange.getBegin());
+        assertEquals(orgEnd, targetRange.getEnd());
+      }     
+    } 
+    //check Sofas
+    CAS targetView1 = cas.getView("newSofa1");
+    assertEquals(sofaText1, targetView1.getDocumentText());
+    CAS targetView2 = cas.getView("newSofa2");
+    assertEquals(sofaText2, targetView2.getDocumentText());
+    AnnotationFS targetAnnot1 = (AnnotationFS) 
+      targetView1.getAnnotationIndex(orgType).iterator().get();
+    assertEquals(annotText, targetAnnot1.getCoveredText());
+    AnnotationFS targetAnnot2 = (AnnotationFS) 
+    targetView2.getAnnotationIndex(orgType).iterator().get();
+    assertEquals(annotText, targetAnnot2.getCoveredText());
+    assertTrue(targetView1.getSofa().getSofaRef() != 
+            targetView2.getSofa().getSofaRef());
+  }
+  
+  public void testOutOfTypeSystemData() throws Exception {
+    // deserialize a simple XMI into a CAS with no TypeSystem    
+    CAS cas = CasCreationUtils.createCas(new TypeSystemDescription_impl(),
+            new TypePriorities_impl(), new FsIndexDescription[0]);
+    File xmiFile = JUnitExtension.getFile("ExampleCas/simpleCas.xmi");
+    String xmiStr = FileUtils.file2String(xmiFile, "UTF-8");
+    
+    XmiSerializationSharedData sharedData = new XmiSerializationSharedData();
+    deserialize(xmiStr, cas, sharedData, true, -1);
+    
+    //do some checks on the out-of-type system data
+    List ootsElems = sharedData.getOutOfTypeSystemElements();
+    assertEquals(9, ootsElems.size());
+    List ootsViewMembers = sharedData.getOutOfTypeSystemViewMembers("1");
+    assertEquals(7, ootsViewMembers.size());
+    
+    // now reserialize including OutOfTypeSystem data
+    String xmiStr2 = serialize(cas, sharedData);
+    
+    //deserialize both original and new XMI into CASes that do have the full typesystem
+    CAS newCas1 = CasCreationUtils.createCas(typeSystem, null, indexes);
+    deserialize(xmiStr, newCas1, null, false, -1);
+    CAS newCas2 = CasCreationUtils.createCas(typeSystem, null, indexes);
+    deserialize(xmiStr2, newCas2, null, false, -1);
+    CasComparer.assertEquals(newCas1, newCas2);  
+    
+    //Test a partial type system with a missing some missing features and
+    //missing "Organization" type
+    File partialTypeSystemFile = JUnitExtension.getFile("ExampleCas/partialTestTypeSystem.xml");
+    TypeSystemDescription partialTypeSystem = UIMAFramework.getXMLParser().parseTypeSystemDescription(
+            new XMLInputSource(partialTypeSystemFile));
+    CAS partialTsCas = CasCreationUtils.createCas(partialTypeSystem, null, indexes);
+    XmiSerializationSharedData sharedData2 = new XmiSerializationSharedData();
+    deserialize(xmiStr, partialTsCas, sharedData2, true, -1);
+    
+    assertEquals(1,sharedData2.getOutOfTypeSystemElements().size());
+    OotsElementData ootsFeats3 = sharedData2.getOutOfTypeSystemFeatures(sharedData2.getFsAddrForXmiId(3));
+    assertEquals(1, ootsFeats3.attributes.size());
+    XmlAttribute ootsAttr = (XmlAttribute)ootsFeats3.attributes.get(0);
+    assertEquals("mentionType", ootsAttr.name);
+    assertEquals("NAME", ootsAttr.value);
+    OotsElementData ootsFeats5 = sharedData2.getOutOfTypeSystemFeatures(sharedData2.getFsAddrForXmiId(5));
+    assertEquals(0, ootsFeats5.attributes.size());
+    assertEquals(1, ootsFeats5.childElements.size());
+    XmlElementNameAndContents ootsChildElem = (XmlElementNameAndContents)
+            ootsFeats5.childElements.get(0);
+    assertEquals("mentionType", ootsChildElem.name.qName);
+    assertEquals("NAME", ootsChildElem.contents);
+    
+    OotsElementData ootsFeats8 = sharedData2.getOutOfTypeSystemFeatures(sharedData2.getFsAddrForXmiId(8));
+    assertEquals(1, ootsFeats8.attributes.size());
+    OotsElementData ootsFeats10 = sharedData2.getOutOfTypeSystemFeatures(sharedData2.getFsAddrForXmiId(10));
+    assertEquals(1, ootsFeats10.attributes.size());
+    OotsElementData ootsFeats11 = sharedData2.getOutOfTypeSystemFeatures(sharedData2.getFsAddrForXmiId(11));
+    assertEquals(4, ootsFeats11.childElements.size());
+    
+    String xmiStr3 = serialize(partialTsCas, sharedData2);
+    newCas2.reset();
+    deserialize(xmiStr3, newCas2, null, false, -1);
+    CasComparer.assertEquals(newCas1, newCas2);    
+ }
+  
+  public void testOutOfTypeSystemArrayElement() throws Exception {
+    //add to type system an annotation type that has an FSArray feature
+    TypeDescription testAnnotTypeDesc = typeSystem.addType("org.apache.uima.testTypeSystem.TestAnnotation", "", "uima.tcas.Annotation");
+    testAnnotTypeDesc.addFeature("arrayFeat", "", "uima.cas.FSArray");
+    //populate a CAS with such an array
+    CAS cas = CasCreationUtils.createCas(typeSystem, null, null);
+    Type testAnnotType = cas.getTypeSystem().getType("org.apache.uima.testTypeSystem.TestAnnotation");
+    Type orgType = cas.getTypeSystem().getType(
+      "org.apache.uima.testTypeSystem.Organization");
+    AnnotationFS orgAnnot1 = cas.createAnnotation(orgType, 0, 10);
+    cas.addFsToIndexes(orgAnnot1);
+    AnnotationFS orgAnnot2 = cas.createAnnotation(orgType, 10, 20);
+    cas.addFsToIndexes(orgAnnot2);
+    AnnotationFS testAnnot = cas.createAnnotation(testAnnotType, 0, 20);
+    cas.addFsToIndexes(testAnnot);
+    ArrayFS arrayFs = cas.createArrayFS(2);
+    arrayFs.set(0, orgAnnot1);
+    arrayFs.set(1, orgAnnot2);
+    Feature arrayFeat = testAnnotType.getFeatureByBaseName("arrayFeat");
+    testAnnot.setFeatureValue(arrayFeat, arrayFs);
+    
+    //serialize to XMI
+    String xmiStr = serialize(cas, null);
+    
+    //deserialize into a CAS that's missing the Organization type
+    File partialTypeSystemFile = JUnitExtension.getFile("ExampleCas/partialTestTypeSystem.xml");
+    TypeSystemDescription partialTypeSystem = UIMAFramework.getXMLParser().parseTypeSystemDescription(
+            new XMLInputSource(partialTypeSystemFile));
+    testAnnotTypeDesc = partialTypeSystem.addType("org.apache.uima.testTypeSystem.TestAnnotation", "", "uima.tcas.Annotation");
+    testAnnotTypeDesc.addFeature("arrayFeat", "", "uima.cas.FSArray");
+    CAS partialTsCas = CasCreationUtils.createCas(partialTypeSystem, null, null);
+    XmiSerializationSharedData sharedData = new XmiSerializationSharedData();
+    deserialize(xmiStr, partialTsCas, sharedData, true, -1);
+    
+    //check out of type system data
+    Type testAnnotType2 = partialTsCas.getTypeSystem().getType("org.apache.uima.testTypeSystem.TestAnnotation");
+    FeatureStructure testAnnot2 = partialTsCas.getAnnotationIndex(testAnnotType2).iterator().get(); 
+    Feature arrayFeat2 = testAnnotType2.getFeatureByBaseName("arrayFeat");
+    FeatureStructure arrayFs2 = testAnnot2.getFeatureValue(arrayFeat2);
+    List ootsElems = sharedData.getOutOfTypeSystemElements();
+    assertEquals(2, ootsElems.size());
+    List ootsArrayElems = sharedData.getOutOfTypeSystemArrayElements(arrayFs2.hashCode());
+    assertEquals(2, ootsArrayElems.size());
+    for (int i = 0; i < 2; i++) {
+      OotsElementData oed = (OotsElementData)ootsElems.get(i);
+      XmiArrayElement arel = (XmiArrayElement)ootsArrayElems.get(i);
+      assertEquals(oed.xmiId, arel.xmiId);      
+    }
+    
+    //reserialize along with out of type system data
+    String xmiStr2 = serialize(partialTsCas, sharedData);
+    
+    //deserialize into a new CAS and compare
+    CAS cas2 = CasCreationUtils.createCas(typeSystem, null, null);
+    deserialize(xmiStr2, cas2, null, false, -1);
+    
+    CasComparer.assertEquals(cas, cas2);    
+  }
+  
+  public void testOutOfTypeSystemListElement() throws Exception {
+    //add to type system an annotation type that has an FSList feature
+    TypeDescription testAnnotTypeDesc = typeSystem.addType("org.apache.uima.testTypeSystem.TestAnnotation", "", "uima.tcas.Annotation");
+    testAnnotTypeDesc.addFeature("listFeat", "", "uima.cas.FSList");
+    //populate a CAS with such an list
+    CAS cas = CasCreationUtils.createCas(typeSystem, null, null);
+    Type testAnnotType = cas.getTypeSystem().getType("org.apache.uima.testTypeSystem.TestAnnotation");
+    Type orgType = cas.getTypeSystem().getType(
+      "org.apache.uima.testTypeSystem.Organization");
+    AnnotationFS orgAnnot1 = cas.createAnnotation(orgType, 0, 10);
+    cas.addFsToIndexes(orgAnnot1);
+    AnnotationFS orgAnnot2 = cas.createAnnotation(orgType, 10, 20);
+    cas.addFsToIndexes(orgAnnot2);
+    AnnotationFS testAnnot = cas.createAnnotation(testAnnotType, 0, 20);
+    cas.addFsToIndexes(testAnnot);
+    Type nonEmptyFsListType = cas.getTypeSystem().getType(CAS.TYPE_NAME_NON_EMPTY_FS_LIST);
+    Type emptyFsListType = cas.getTypeSystem().getType(CAS.TYPE_NAME_EMPTY_FS_LIST);
+    Feature headFeat = nonEmptyFsListType.getFeatureByBaseName("head");
+    Feature tailFeat = nonEmptyFsListType.getFeatureByBaseName("tail");
+    FeatureStructure emptyNode = cas.createFS(emptyFsListType);
+    FeatureStructure secondNode = cas.createFS(nonEmptyFsListType);
+    secondNode.setFeatureValue(headFeat, orgAnnot2);
+    secondNode.setFeatureValue(tailFeat, emptyNode);
+    FeatureStructure firstNode = cas.createFS(nonEmptyFsListType);
+    firstNode.setFeatureValue(headFeat, orgAnnot1);
+    firstNode.setFeatureValue(tailFeat, secondNode);
+    
+    Feature listFeat = testAnnotType.getFeatureByBaseName("listFeat");
+    testAnnot.setFeatureValue(listFeat, firstNode);
+    
+    //serialize to XMI
+    String xmiStr = serialize(cas, null);
+    System.out.println(xmiStr);
+    
+    //deserialize into a CAS that's missing the Organization type
+    File partialTypeSystemFile = JUnitExtension.getFile("ExampleCas/partialTestTypeSystem.xml");
+    TypeSystemDescription partialTypeSystem = UIMAFramework.getXMLParser().parseTypeSystemDescription(
+            new XMLInputSource(partialTypeSystemFile));
+    testAnnotTypeDesc = partialTypeSystem.addType("org.apache.uima.testTypeSystem.TestAnnotation", "", "uima.tcas.Annotation");
+    testAnnotTypeDesc.addFeature("listFeat", "", "uima.cas.FSList");
+    CAS partialTsCas = CasCreationUtils.createCas(partialTypeSystem, null, null);
+    XmiSerializationSharedData sharedData = new XmiSerializationSharedData();
+    deserialize(xmiStr, partialTsCas, sharedData, true, -1);
+    
+    //check out of type system data
+    Type testAnnotType2 = partialTsCas.getTypeSystem().getType("org.apache.uima.testTypeSystem.TestAnnotation");
+    FeatureStructure testAnnot2 = partialTsCas.getAnnotationIndex(testAnnotType2).iterator().get(); 
+    Feature listFeat2 = testAnnotType2.getFeatureByBaseName("listFeat");
+    FeatureStructure listFs = testAnnot2.getFeatureValue(listFeat2);
+    List ootsElems = sharedData.getOutOfTypeSystemElements();
+    assertEquals(2, ootsElems.size());
+    OotsElementData oed = sharedData.getOutOfTypeSystemFeatures(listFs.hashCode());
+    XmlAttribute attr = (XmlAttribute)oed.attributes.get(0);
+    assertNotNull(attr);
+    assertEquals(CAS.FEATURE_BASE_NAME_HEAD, attr.name);
+    assertEquals(attr.value, ((OotsElementData)ootsElems.get(0)).xmiId);
+    
+    //reserialize along with out of type system data
+    String xmiStr2 = serialize(partialTsCas, sharedData);
+    System.out.println(xmiStr2);
+    
+    //deserialize into a new CAS and compare
+    CAS cas2 = CasCreationUtils.createCas(typeSystem, null, null);
+    deserialize(xmiStr2, cas2, null, false, -1);
+    
+    CasComparer.assertEquals(cas, cas2);    
+  }
+  
+  public void testOutOfTypeSystemDataComplexCas() throws Exception {
+    // deserialize a complex XCAS
+    CAS originalCas = CasCreationUtils.createCas(typeSystem, null, indexes);
+    InputStream serCasStream = new FileInputStream(JUnitExtension.getFile("ExampleCas/cas.xml"));
+    XCASDeserializer.deserialize(serCasStream, originalCas);
+    serCasStream.close();
+    
+    //serialize to XMI
+    String xmiStr = serialize(originalCas, null);
+    
+    //deserialize into a CAS with no type system
+    CAS casWithNoTs = CasCreationUtils.createCas(new TypeSystemDescription_impl(),
+            new TypePriorities_impl(), new FsIndexDescription[0]);
+    XmiSerializationSharedData sharedData = new XmiSerializationSharedData();
+    deserialize(xmiStr, casWithNoTs, sharedData, true, -1);
+        
+    // now reserialize including OutOfTypeSystem data
+    String xmiStr2 = serialize(casWithNoTs, sharedData);
+    
+    //deserialize into a new CAS that has the full type system
+    CAS newCas = CasCreationUtils.createCas(typeSystem, null, indexes);
+    deserialize(xmiStr, newCas, null, false, -1);
+    
+    //compare
+    CasComparer.assertEquals(originalCas, newCas);
+    
+    //Test a partial type system with a missing some missing features and
+    //missing "Organization" type
+    File partialTypeSystemFile = JUnitExtension.getFile("ExampleCas/partialTestTypeSystem.xml");
+    TypeSystemDescription partialTypeSystem = UIMAFramework.getXMLParser().parseTypeSystemDescription(
+            new XMLInputSource(partialTypeSystemFile));
+    CAS partialTsCas = CasCreationUtils.createCas(partialTypeSystem, null, indexes);
+    XmiSerializationSharedData sharedData2 = new XmiSerializationSharedData();
+    deserialize(xmiStr, partialTsCas, sharedData2, true, -1);
+        
+    String xmiStr3 = serialize(partialTsCas, sharedData2);
+    newCas.reset();
+    deserialize(xmiStr3, newCas, null, false, -1);
+    CasComparer.assertEquals(originalCas, newCas);    
+ }
+  
+  public void testGetNumChildren() throws Exception {
+    // deserialize a complex XCAS
+    CAS cas = CasCreationUtils.createCas(typeSystem, null, indexes);
+//    InputStream serCasStream = new FileInputStream(JUnitExtension.getFile("ExampleCas/cas.xml"));
+//    XCASDeserializer.deserialize(serCasStream, cas);
+//    serCasStream.close();
+  InputStream serCasStream = new FileInputStream(JUnitExtension.getFile("ExampleCas/simpleCas.xmi"));
+  XmiCasDeserializer.deserialize(serCasStream, cas);
+  serCasStream.close();
+    
+    // call serializer with a ContentHandler that checks numChildren
+    XmiCasSerializer xmiSer = new XmiCasSerializer(cas.getTypeSystem());
+    GetNumChildrenTestHandler handler = new GetNumChildrenTestHandler(xmiSer);
+    xmiSer.serialize(cas, handler);
+  }
+
+  /** Utility method for serializing a CAS to an XMI String 
+   * */
+  private String serialize(CAS cas, XmiSerializationSharedData serSharedData) throws IOException, SAXException {
+    ByteArrayOutputStream baos = new ByteArrayOutputStream();    
+    XmiCasSerializer.serialize(cas, null, baos, false, serSharedData);
+    baos.close();
+    String xmiStr = new String(baos.toByteArray(), "UTF-8");   //note by default XmiCasSerializer generates UTF-8
+    
+    //workaround for newline serialization problem in Sun Java 1.4.2
+    //this test file should contain CRLF line endings, but Sun Java loses them
+    //when it serializes XML.
+    if(!builtInXmlSerializationSupportsCRs()) {
+      xmiStr = xmiStr.replaceAll("&#10;", "&#13;&#10;");
+    }        
+    return xmiStr;
+  }
+
+
+  /** Utility method for deserializing a CAS from an XMI String */
+  private void deserialize(String xmlStr, CAS cas, XmiSerializationSharedData sharedData, boolean lenient, int mergePoint) throws FactoryConfigurationError, ParserConfigurationException, SAXException, IOException {
+    byte[] bytes = xmlStr.getBytes("UTF-8"); //this assumes the encoding is UTF-8, which is the default output encoding of the XmiCasSerializer
+    ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+    XmiCasDeserializer.deserialize(bais, cas, lenient, sharedData, mergePoint);
+    bais.close();
+  }  
+  
+  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);
+    cas.addFsToIndexes(person);
+    return person;
+  }
+  
+  /**
+   * Checks the Java vendor and version and returns true if running a version
+   * of Java whose built-in XSLT support can properly serialize carriage return
+   * characters, and false if not.  It seems to be the case that Sun JVMs prior
+   * to 1.5 do not properly serialize carriage return characters.  We have to
+   * modify our test case to account for this.
+   * @return true if XML serialization of CRs behave properly in the current JRE
+   */
+  private boolean builtInXmlSerializationSupportsCRs() {
+    String javaVendor = System.getProperty("java.vendor");
+    if( javaVendor.startsWith("Sun") ) {
+        String javaVersion = System.getProperty("java.version");
+        if( javaVersion.startsWith("1.3") || javaVersion.startsWith("1.4") )
+            return false;
+    }
+    return true;
+  }  
+  
+  static class GetNumChildrenTestHandler extends DefaultHandler {
+    XmiCasSerializer xmiSer;
+    Stack childCountStack = new Stack();
+    
+    GetNumChildrenTestHandler(XmiCasSerializer xmiSer) {
+      this.xmiSer = xmiSer;
+      childCountStack.push(new Integer(1));
+    }
+
+    /* (non-Javadoc)
+     * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
+     */
+    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
+      // TODO Auto-generated method stub
+      super.startElement(uri, localName, qName, attributes);
+      childCountStack.push(new Integer(xmiSer.getNumChildren()));
+    }
+
+    /* (non-Javadoc)
+     * @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
+     */
+    public void endElement(String uri, String localName, String qName) throws SAXException {
+      // TODO Auto-generated method stub
+      super.endElement(uri, localName, qName);
+      //check that we've seen the expected number of child elements
+      //(count on top of stack should be 0)
+      Integer count = (Integer)childCountStack.pop();
+      assertEquals(0, count.intValue());
+      
+      //decremenet child count of our parent
+      count = (Integer)childCountStack.pop();
+      childCountStack.push(new Integer(count.intValue() - 1));
+    }
+
+    /* (non-Javadoc)
+     * @see org.xml.sax.helpers.DefaultHandler#characters(char[], int, int)
+     */
+    public void characters(char[] ch, int start, int length) throws SAXException {
+      // text node is considered a child
+      if (length > 0) {
+        Integer count = (Integer)childCountStack.pop();
+        childCountStack.push(new Integer(count.intValue() - 1));
+      }
+    }
+    
+    
   }
 }

Modified: incubator/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/cas_data/impl/XCasToCasDataSaxHandlerTest.java
URL: http://svn.apache.org/viewvc/incubator/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/cas_data/impl/XCasToCasDataSaxHandlerTest.java?view=diff&rev=512404&r1=512403&r2=512404
==============================================================================
--- incubator/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/cas_data/impl/XCasToCasDataSaxHandlerTest.java (original)
+++ incubator/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/cas_data/impl/XCasToCasDataSaxHandlerTest.java Tue Feb 27 12:58:39 2007
@@ -119,19 +119,7 @@
       CAS cas = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(),
               new FsIndexDescription[0]);
 
-      InputStream serCasStream;
-      if (builtInXmlSerializationSupportsCRs()) {
-        serCasStream = new FileInputStream(JUnitExtension.getFile("ExampleCas/cas.xml"));
-      }
-      else {      
-        //Java version we are running can't serialize CR (\r) characters in XML output.
-        //Therefore we need to remove them from our test example XCAS or we will get 
-        //comparison failiures later in this test case.
-        String casXml = FileUtils.file2String(JUnitExtension.getFile("ExampleCas/cas.xml"), "UTF-8");
-        casXml = casXml.replaceAll("&#13;", "");
-        byte[] bytes = casXml.getBytes("UTF-8");
-        serCasStream = new ByteArrayInputStream(bytes);
-      }
+      InputStream serCasStream = new FileInputStream(JUnitExtension.getFile("ExampleCas/cas.xml"));
       
       XCASDeserializer deser = new XCASDeserializer(cas.getTypeSystem());
       ContentHandler deserHandler = deser.getXCASHandler(cas);
@@ -182,6 +170,12 @@
 
     generator.generateXCas(casData);
     String xml = sw.getBuffer().toString();
+    
+    //workaround for XML serializatioj problem on Sun Java 1.4
+    if (!builtInXmlSerializationSupportsCRs()) {
+      xml = xml.replaceAll("&#10;", "&#13;&#10;");  
+    }
+    
     UIMAFramework.getLogger(XCasToCasDataSaxHandlerTest.class).log(Level.FINE, xml);
 
     // deserialize back into CAS for comparison

Modified: incubator/uima/uimaj/trunk/uimaj-core/src/test/resources/ExampleCas/partialTestTypeSystem.xml
URL: http://svn.apache.org/viewvc/incubator/uima/uimaj/trunk/uimaj-core/src/test/resources/ExampleCas/partialTestTypeSystem.xml?view=diff&rev=512404&r1=512403&r2=512404
==============================================================================
--- incubator/uima/uimaj/trunk/uimaj-core/src/test/resources/ExampleCas/partialTestTypeSystem.xml (original)
+++ incubator/uima/uimaj/trunk/uimaj-core/src/test/resources/ExampleCas/partialTestTypeSystem.xml Tue Feb 27 12:58:39 2007
@@ -63,11 +63,11 @@
           <description/>
           <rangeTypeName>uima.tcas.Annotation</rangeTypeName>
         </featureDescription>
-        <featureDescription>
+<!--        <featureDescription>
           <name>relationArgs</name>
           <description/>
           <rangeTypeName>org.apache.uima.testTypeSystem.RelationArgs</rangeTypeName>
-        </featureDescription>
+        </featureDescription>-->
       </features>
     </typeDescription>
     <typeDescription>
@@ -119,21 +119,23 @@
           <description/>
           <rangeTypeName>uima.cas.String</rangeTypeName>
         </featureDescription>
-        <featureDescription>
+<!--        <featureDescription>
           <name>classes</name>
           <description/>
           <rangeTypeName>uima.cas.StringArray</rangeTypeName>
-        </featureDescription>
+        </featureDescription> 
+-->
         <featureDescription>
           <name>canonicalForm</name>
           <description/>
           <rangeTypeName>uima.cas.String</rangeTypeName>
         </featureDescription>
-        <featureDescription>
+<!--        <featureDescription>
           <name>variantForms</name>
           <description/>
           <rangeTypeName>uima.cas.StringList</rangeTypeName>
         </featureDescription>
+-->
         <featureDescription>
           <name>id</name>
           <description/>

Added: incubator/uima/uimaj/trunk/uimaj-core/src/test/resources/ExampleCas/simpleCas.xmi
URL: http://svn.apache.org/viewvc/incubator/uima/uimaj/trunk/uimaj-core/src/test/resources/ExampleCas/simpleCas.xmi?view=auto&rev=512404
==============================================================================
--- incubator/uima/uimaj/trunk/uimaj-core/src/test/resources/ExampleCas/simpleCas.xmi (added)
+++ incubator/uima/uimaj/trunk/uimaj-core/src/test/resources/ExampleCas/simpleCas.xmi Tue Feb 27 12:58:39 2007
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+ -->
+<xmi:XMI xmlns:testTypeSystem="http:///org/apache/uima/testTypeSystem.ecore"
+  xmlns:cas="http:///uima/cas.ecore" xmlns:tcas="http:///uima/tcas.ecore"
+  xmlns:xmi="http://www.omg.org/XMI" xmi:version="2.0">
+  <cas:NULL xmi:id="0"/>
+  <cas:Sofa xmi:id="1" sofaNum="1" sofaID="_InitialView" mimeType="text"
+    sofaString="IBM Announces Recipients Of Internet Research Grants&#13;&#10;&#13;&#10;Resources Will Help Universities Explore Internet2 Applications    &#13;&#10;&#13;&#10; Waltham, Mass., January 15, 1998 -- As part of its $3.5 million commitment to support the development of Internet2, IBM has announced the names of seven higher education institutions that will receive resources through the company's sponsored research program. These resources will facilitate development of Internet2 applications and participation in the Internet2 project.  The grant recipients are Clemson University in South Carolina, Duke University in North Carolina, Indiana University, Northwestern University in Illinois, the University of Chicago, the University of Michigan, and the University of South Carolina.  &#13;&#10;&#13;&#10;      Donated resources will be in the form of hardware, software, switches and other pieces of network infrastructure critical to Internet2 applications, connections, 
 and operation.  In addition, grant recipients have access to the technological expertise of IBM personnel. Many of the grant recipients will use the donations to create networked consortiums with other higher educational institutions in their areas.  Grant resources will be used to enhance specific advanced technology applications -- ranging from telemedicine to the maintenance of a digital Movietone newsreel archive.  &#13;&#10;&#13;&#10;      Irving Wladawsky-Berger, general manager of IBM's Internet Division, emphasized the company's commitment to the  new  Internet.  He said,  The Internet has succeeded beyond our wildest imagination.  More and more people are getting connected around the world, as the Internet is being embraced across the research community, educational institutions, businesses of all sizes, and society at large.  The Internet2 efforts will take us all to the next levels, with significant improvements in bandwidth and quality of service.  Most important
 , the Internet2 efforts will make possible all kinds of new, exciting applications.  IBM is very proud to continue its associations and contributions to the Internet.   &#13;&#10;&#13;&#10;      Sean C. Rush, general manager of IBM Global Education, agrees.  He said,  Internet2 is being developed with the needs of higher education inmind.  Internet2 capabilities include high speed, dependability, and networking power.  For example, data base analysis that took hours or days will take minutes.  Researchers worldwide will be able to share large amounts of data without interruptions or slow downs.  And finally, Internet2 will serve as an important repository for a wealth of materials, and researchers will now have high quality, high speed access to books, art work, films, and music.   &#13;&#10;&#13;&#10;      Don Haile, vice president of IBM's Networking Hardware Development, has worked closely with several Internet2 universities over the past year.  The recent revolutions in 
 networking technology, including the advent of ATM, switched LANs and route-switching, are allowing today's university faculty to consider network-based applications that they previously only dreamed about,  said Don.    Professors can transmit voice and video in real time over a network, enriching research collaborations and distance learning classroom experiences.   By providing high speed communication links,  Internet2 is supporting research that will benefit students and local communities, across the country.   &#13;&#10;&#13;&#10;  Internet2   &#13;&#10;&#13;&#10;      Since its recent inception, Internet2 has grown from 34 to over 100 research universities.  With Internet2, network applications are better served by new network points-of-presence (PoPs) capable of transmitting gigabits (billions of bits) of information per second.  Internet2 participants broaden their research and development expenditures to help create these GigaPoPs. Member universities, working with
  private member companies and non-profit organizations are developing tools for scientific research and higher education in the 21st century.  The Internet2 homepage is located at   http://www.internet2.edu/ &#13;&#10;&#13;&#10;  IBM Global Education Industry   &#13;&#10;&#13;&#10;      The Global Education Industry is a unit of IBM, the largest information technology company.  The Global Education Industry provides targeted products, consulting, and services to K-12 education and institutions of higher education throughout North America, Latin America, Europe and Asia.  IBM's Higher Education homepage is located at   http://www.hied.ibm.com &#13;&#10;&#13;&#10;  IBM Internet Division   &#13;&#10;&#13;&#10;      IBM is a leader in the development of the Internet and is dedicated to helping customers and developers exploit the potential of network computing,  drawing on the resources of over 24 information technology products and services, including computer systems, software
 , networking systems, storage devices and microelectronics.  Developers and customers can find out more about IBM's many initiatives relating to Internet technologies, products and services on the Web at   http://www.internet.ibm.com &#13;&#10;&#13;&#10;  IBM Networking Hardware Division   &#13;&#10;&#13;&#10;      IBM's Networking Hardware Division (NHD) develops and manufactures industry-leading networking technologies and products, providing global end-to-end solutions for Token-Ring, Ethernet, Gigabit Ethernet, ATM, IP and SNA networks.  IBM NHD also provides consulting, education, service and support worldwide to help customers achieve their business objectives.  For additional information on IBM's networking solutions, visit our Web site at  www.networking.ibm.com or call 800-IBM-3333 or outside the U.S. 770-644-5997.    # # #      The following term is a trademark of the IBM Corporation in the United States or other countries or both: IBM   &#13;&#10;"/>
+  <tcas:DocumentAnnotation xmi:id="2" sofa="1" begin="0" end="2930" language="en"/>
+  <testTypeSystem:Person xmi:id="3" sofa="1" begin="2077" end="2089" confidence="0.0" componentId="ACE"
+    mentionType="NAME"/>
+  <testTypeSystem:Person xmi:id="4" sofa="1" begin="1571" end="1577" confidence="0.0" componentId="ACE"
+    mentionType="NOMINAL"/>
+  <testTypeSystem:Person xmi:id="5">
+    <sofa href="#1"/>
+    <begin>2685</begin>
+    <end>2694</end>
+    <componentId>ACE</componentId>
+    <confidence>0.0</confidence>
+    <mentionType>NAME</mentionType>
+  </testTypeSystem:Person>  
+  <testTypeSystem:Organization xmi:id="6" sofa="1" begin="4165" end="4199"
+    confidence="0.0" componentId="ACE"
+    mentionType="NAME"/>  
+  <testTypeSystem:Owner xmi:id="7" sofa="1" begin="1162" end="1173"
+    confidence="0.0" componentId="ACE" relationArgs="8"/>
+  <testTypeSystem:BinaryRelationArgs xmi:id="8" domainValue="3"
+    rangeValue="6"/>
+  <testTypeSystem:Owner xmi:id="9" sofa="1" begin="1162" end="1173"
+    confidence="0.0" componentId="ACE" relationArgs="10"/>
+  <testTypeSystem:BinaryRelationArgs xmi:id="10">
+    <domainValue href="#3"/>
+    <rangeValue href="#6"/>
+  </testTypeSystem:BinaryRelationArgs>
+  <testTypeSystem:Entity xmi:id="11"    
+    componentId="CrossAnnotatorCoreference"
+    canonicalForm="University of South Carolina"
+    id="uid-pr00010_15Jan1998.txt-554">
+    <classes>org.apache.uima.testTypeSystem.College</classes>
+    <classes>org.apache.uima.testTypeSystem.Organization</classes>
+    <variantForms>USC</variantForms>
+    <variantForms>U of SC</variantForms>
+  </testTypeSystem:Entity>
+  
+  <cas:View sofa="1" members="2 3 4 5 6 7 9 11"/>
+</xmi:XMI>
\ No newline at end of file