| /* |
| * 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.util; |
| |
| import java.io.File; |
| import java.io.FileInputStream; |
| import java.io.InputStream; |
| import java.util.ArrayList; |
| import java.util.Iterator; |
| |
| import org.apache.uima.UIMAFramework; |
| import org.apache.uima.UIMARuntimeException; |
| import org.apache.uima.cas.ArrayFS; |
| import org.apache.uima.cas.CAS; |
| import org.apache.uima.cas.CASRuntimeException; |
| import org.apache.uima.cas.FSIterator; |
| import org.apache.uima.cas.impl.CASImpl; |
| import org.apache.uima.cas.impl.XCASDeserializer; |
| import org.apache.uima.cas_data.impl.CasComparer; |
| import org.apache.uima.jcas.JCas; |
| import org.apache.uima.jcas.cas.TOP; |
| import org.apache.uima.jcas.tcas.Annotation; |
| 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 junit.framework.TestCase; |
| |
| |
| public class CasCopierTest extends TestCase { |
| private TypeSystemDescription typeSystem; |
| |
| private FsIndexDescription[] indexes; |
| |
| protected void setUp() throws Exception { |
| File typeSystemFile1 = JUnitExtension.getFile("ExampleCas/testTypeSystem.xml"); |
| File indexesFile = JUnitExtension.getFile("ExampleCas/testIndexes.xml"); |
| |
| typeSystem = UIMAFramework.getXMLParser().parseTypeSystemDescription( |
| new XMLInputSource(typeSystemFile1)); |
| indexes = UIMAFramework.getXMLParser().parseFsIndexCollection(new XMLInputSource(indexesFile)) |
| .getFsIndexes(); |
| } |
| |
| public void testCopyCas() throws Exception { |
| // create a source CAS by deserializing from XCAS |
| CAS srcCas = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); |
| InputStream serCasStream = new FileInputStream(JUnitExtension |
| .getFile("ExampleCas/multiSofaCas.xml")); |
| XCASDeserializer.deserialize(serCasStream, srcCas); |
| serCasStream.close(); |
| |
| // create a destination CAS |
| CAS destCas = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); |
| |
| // do the copy |
| CasCopier.copyCas(srcCas, destCas, true); |
| // XCASSerializer.serialize(destCas, System.out); |
| |
| // verify copy |
| CasComparer.assertEquals(srcCas, destCas); |
| |
| // try with type systems are not identical (dest. a superset of src.) |
| TypeSystemDescription additionalTypes = new TypeSystemDescription_impl(); |
| TypeDescription fooType = additionalTypes.addType("test.Foo", "Test Type", |
| "uima.tcas.Annotation"); |
| fooType.addFeature("bar", "Test Feature", "uima.cas.String"); |
| ArrayList<TypeSystemDescription> destTypeSystems = new ArrayList<TypeSystemDescription>(); |
| destTypeSystems.add(additionalTypes); |
| destTypeSystems.add(typeSystem); |
| CAS destCas2 = CasCreationUtils.createCas(destTypeSystems); |
| CasCopier.copyCas(srcCas, destCas2, true); |
| CasComparer.assertEquals(srcCas, destCas); |
| |
| // try with base CAS rather than initial view |
| CAS srcCasBase = ((CASImpl) srcCas).getBaseCAS(); |
| destCas.reset(); |
| CAS destCasBase = ((CASImpl) destCas).getBaseCAS(); |
| CasCopier.copyCas(srcCasBase, destCasBase, true); |
| CasComparer.assertEquals(srcCasBase, destCasBase); |
| |
| //try with source and dest cas the same |
| // |
| Exception ee = null; |
| try { |
| CasCopier.copyCas(srcCasBase, srcCasBase, false); |
| } catch (Exception e) { |
| ee = e; |
| } |
| assertTrue(ee instanceof UIMARuntimeException); |
| |
| ee = null; |
| CAS v2 = srcCas.createView("v2"); |
| CasCopier cc = new CasCopier(srcCas, v2); |
| try { |
| cc.copyCasView(srcCas, v2, false); |
| } catch (Exception e) { |
| e.printStackTrace(); |
| ee = e; |
| } |
| assertEquals(ee, null); |
| } |
| |
| public void testCopyCasWithDifferentTypeSystemObject() throws Exception { |
| // create a source CAS by deserializing from XCAS |
| CAS srcCas = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); |
| InputStream serCasStream = new FileInputStream(JUnitExtension |
| .getFile("ExampleCas/multiSofaCas.xml")); |
| XCASDeserializer.deserialize(serCasStream, srcCas); |
| serCasStream.close(); |
| |
| // create a destination CAS (do not share the same type system object) |
| File typeSystemFile = JUnitExtension.getFile("ExampleCas/testTypeSystem.xml"); |
| File indexesFile = JUnitExtension.getFile("ExampleCas/testIndexes.xml"); |
| |
| TypeSystemDescription newTsDesc = typeSystem = UIMAFramework.getXMLParser().parseTypeSystemDescription( |
| new XMLInputSource(typeSystemFile)); |
| FsIndexDescription[] newFsIndexes = indexes = UIMAFramework.getXMLParser().parseFsIndexCollection(new XMLInputSource(indexesFile)) |
| .getFsIndexes(); |
| CAS destCas = CasCreationUtils.createCas(newTsDesc, new TypePriorities_impl(), newFsIndexes); |
| |
| // do the copy |
| CasCopier.copyCas(srcCas, destCas, true); |
| // XCASSerializer.serialize(destCas, System.out); |
| |
| // verify copy |
| CasComparer.assertEquals(srcCas, destCas); |
| |
| // try with type systems are not identical (dest. a superset of src.) |
| TypeSystemDescription additionalTypes = new TypeSystemDescription_impl(); |
| TypeDescription fooType = additionalTypes.addType("test.Foo", "Test Type", |
| "uima.tcas.Annotation"); |
| fooType.addFeature("bar", "Test Feature", "uima.cas.String"); |
| ArrayList<TypeSystemDescription> destTypeSystems = new ArrayList<TypeSystemDescription>(); |
| destTypeSystems.add(additionalTypes); |
| destTypeSystems.add(typeSystem); |
| CAS destCas2 = CasCreationUtils.createCas(destTypeSystems); |
| CasCopier.copyCas(srcCas, destCas2, true); |
| CasComparer.assertEquals(srcCas, destCas2); |
| |
| // try with src type system having extra type (no instances) with |
| // incompatible ranges |
| additionalTypes = new TypeSystemDescription_impl(); |
| fooType = additionalTypes.addType("test.Foo", "Test Type", |
| "uima.tcas.Annotation"); |
| fooType.addFeature("bar", "Test Feature", "uima.cas.Float"); |
| |
| ArrayList<TypeSystemDescription> srcTypeSystems = new ArrayList<TypeSystemDescription>(); |
| srcTypeSystems.add(additionalTypes); |
| srcTypeSystems.add(typeSystem); |
| |
| srcCas = CasCreationUtils.createCas(srcTypeSystems); |
| serCasStream = new FileInputStream(JUnitExtension |
| .getFile("ExampleCas/multiSofaCas.xml")); |
| XCASDeserializer.deserialize(serCasStream, srcCas); |
| serCasStream.close(); |
| |
| destCas2.reset(); |
| |
| CasCopier.copyCas(srcCas, destCas2, true); |
| CasComparer.assertEquals(srcCas, destCas2); |
| |
| // try with base CAS rather than initial view |
| CAS srcCasBase = ((CASImpl) srcCas).getBaseCAS(); |
| destCas.reset(); |
| CAS destCasBase = ((CASImpl) destCas).getBaseCAS(); |
| CasCopier.copyCas(srcCasBase, destCasBase, true); |
| CasComparer.assertEquals(srcCasBase, destCasBase); |
| } |
| |
| public void testCopyCasView() throws Exception { |
| // create a source CAS by deserializing from XCAS |
| CAS srcCas = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); |
| InputStream serCasStream = new FileInputStream(JUnitExtension.getFile("ExampleCas/cas.xml")); |
| XCASDeserializer.deserialize(serCasStream, srcCas); |
| serCasStream.close(); |
| |
| // create a new view |
| CAS tgtCas = srcCas.createView("view2"); |
| CasCopier copierv = new CasCopier(srcCas, tgtCas); |
| |
| // copy a fs while in an iteration |
| FSIterator<TOP> itv = srcCas.getJCas().getFSIndexRepository().<TOP>getIndex("testEntityIndex").iterator(); |
| FSIterator<Annotation> ita = srcCas.getJCas().getAnnotationIndex().iterator(); |
| |
| while (ita.hasNext()) { |
| Annotation fs = ita.next(); |
| Annotation fsv2 = copierv.copyFs(fs); |
| fsv2.addToIndexes(); |
| } |
| |
| while (itv.hasNext()) { |
| TOP fs = itv.next(); |
| TOP fsv2 = (TOP) copierv.copyFs(fs); |
| fsv2.addToIndexes(); |
| } |
| |
| serCasStream = new FileInputStream(JUnitExtension.getFile("ExampleCas/cas.xml")); |
| XCASDeserializer.deserialize(serCasStream, srcCas); |
| serCasStream.close(); |
| |
| // create a destination CAS |
| CAS destCas = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); |
| |
| CasCopier copier; |
| // do the copy |
| long shortest = Long.MAX_VALUE; |
| int i = 0; |
| // for (; i < 60000; i++) { // uncomment for perf test. was more than 5x faster than version 2.6.0 |
| destCas.reset(); |
| long startTime = System.nanoTime(); |
| copier = new CasCopier(srcCas, destCas); |
| copier.copyCasView(srcCas, true); // true == copy the sofa too |
| long time = (System.nanoTime() - startTime)/ 1000; |
| if (time < shortest) { |
| shortest = time; |
| System.out.format("CasCopier speed for 400KB xcas is %,d microseconds on iteration %,d%n", shortest, i); |
| } |
| // } |
| |
| // verify copy |
| CasComparer.assertEquals(srcCas, destCas); |
| |
| // do the copy to a different view |
| // create a destination CAS |
| destCas = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); |
| |
| // do the copy |
| copier = new CasCopier(srcCas, destCas); |
| copier.copyCasView(srcCas, "aNewView", true); |
| |
| // verify copy |
| CasComparer.assertEqualViews(srcCas, destCas.getView("aNewView")); |
| |
| } |
| |
| public void testCopyCasViewsWithWrapper() throws Exception { |
| // create a source CAS by deserializing from XCAS |
| CAS srcCas = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); |
| InputStream serCasStream = new FileInputStream(JUnitExtension.getFile("ExampleCas/cas.xml")); |
| XCASDeserializer.deserialize(serCasStream, srcCas); |
| serCasStream.close(); |
| |
| // create a destination CAS |
| CAS tgtCas = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); |
| |
| // make wrappers |
| CAS wrappedSrcCas = new CasWrapperForTstng(srcCas); |
| CAS wrappedTgtCas = new CasWrapperForTstng(tgtCas); |
| |
| // do the copy |
| CasCopier copier = new CasCopier(wrappedSrcCas, wrappedTgtCas); |
| copier.copyCasView(wrappedSrcCas, true); |
| |
| // verify copy |
| CasComparer.assertEquals(wrappedSrcCas, wrappedTgtCas); |
| |
| // do the copy to a different view |
| // create a destination CAS |
| tgtCas = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); |
| |
| wrappedTgtCas = new CasWrapperForTstng(tgtCas); |
| // do the copy |
| copier = new CasCopier(wrappedSrcCas, wrappedTgtCas); |
| copier.copyCasView(wrappedSrcCas, "aNewView", true); |
| |
| // verify copy |
| CasComparer.assertEqualViews(wrappedSrcCas, wrappedTgtCas.getView("aNewView")); |
| |
| } |
| |
| public void testCopyFs() throws Exception { |
| // create a source CAS by deserializing from XCAS |
| CAS srcCas = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); |
| InputStream serCasStream = new FileInputStream(JUnitExtension.getFile("ExampleCas/cas.xml")); |
| XCASDeserializer.deserialize(serCasStream, srcCas); |
| serCasStream.close(); |
| |
| // create a destination CAS and the CasCopier instance |
| CAS destCas = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); |
| CasCopier copier = new CasCopier(srcCas, destCas); |
| |
| // set sofa data in destination CAS (this is not copied automatically) |
| destCas.setDocumentText(srcCas.getDocumentText()); |
| |
| CasComparer cci = new CasComparer(); |
| // copy all entities |
| Iterator<TOP> it = srcCas.getIndexRepository().getIndexedFSs(srcCas.getTypeSystem().getType("org.apache.uima.testTypeSystem.Entity")).iterator(); |
| // Iterator<TOP> it = srcCas.getIndexRepository().getAllIndexedFS(srcCas.getTypeSystem().getType("org.apache.uima.testTypeSystem.Entity")); |
| // while(it.hasNext()) { |
| TOP fs = it.next(); |
| TOP fsc = (TOP) copier.copyFs(fs); |
| // destCas.addFsToIndexes(fsc); |
| CasComparer.assertEquals(fs, fsc); |
| // } |
| // copy an Annotation |
| Iterator<Annotation> annotIter = srcCas.<Annotation>getAnnotationIndex().iterator(); |
| TOP annot = annotIter.next(); |
| TOP copy = (TOP) copier.copyFs(annot); |
| // verify copy |
| CasComparer.assertEquals(annot, copy); |
| |
| // copy a Relation (which will have references) |
| Iterator<TOP> relationIter = srcCas.getIndexRepository().<TOP>getIndex("testRelationIndex").iterator(); |
| TOP relFS = relationIter.next(); |
| TOP relCopy = (TOP) copier.copyFs(relFS); |
| // verify copy |
| CasComparer.assertEquals(relFS, relCopy); |
| |
| // test null array element |
| ArrayFS arrFS = srcCas.createArrayFS(3); |
| arrFS.set(0, annot); |
| arrFS.set(1, null); |
| arrFS.set(2, relFS); |
| TOP copyArrFS = (TOP) copier.copyFs(arrFS); |
| CasComparer.assertEquals((TOP)arrFS, copyArrFS); |
| |
| // test with using base cas |
| |
| destCas = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); |
| destCas.setDocumentText(srcCas.getDocumentText()); |
| copier = new CasCopier(((CASImpl)srcCas).getBaseCAS(), ((CASImpl)destCas).getBaseCAS()); |
| |
| annotIter = srcCas.<Annotation>getAnnotationIndex().iterator(); |
| annot = annotIter.next(); |
| boolean wascaught = false; |
| try { |
| copy = copier.copyFs(annot); |
| } catch (CASRuntimeException e) { |
| wascaught = true; |
| } |
| assertFalse(wascaught); |
| // verify copy |
| CasComparer.assertEquals(annot, copy); |
| |
| // test copyFS with two CASs, different views, annotations |
| // create a destination CAS and the CasCopier instance |
| CAS destCas2 = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); |
| CAS destCas2v = destCas2.createView("secondView"); |
| CasCopier copier2 = new CasCopier(srcCas, destCas2v); |
| |
| // copy an Annotation |
| annotIter = srcCas.<Annotation>getAnnotationIndex().iterator(); |
| annot = annotIter.next(); |
| copy = copier2.copyFs(annot); |
| destCas2v.addFsToIndexes(copy); |
| // verify copy |
| CasComparer.assertEquals(annot, copy); |
| |
| } |
| |
| public void testAnnotationWithNullSofaRef() throws Exception { |
| CAS srcCas = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); |
| CAS srcCasView = srcCas.createView("TestView"); |
| srcCasView.setDocumentText("This is a test"); |
| CAS destCas = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); |
| // LowLevelCAS lowLevelSrcCasView = srcCasView.getLowLevelCAS(); |
| // int typeCode = lowLevelSrcCasView.ll_getTypeSystem().ll_getCodeForType( |
| // srcCas.getAnnotationType()); |
| // switch method of creating Annotation to create one with valid sofa ref https://issues.apache.org/jira/browse/UIMA-4099 |
| // int destFsAddr = lowLevelSrcCasView.ll_createFS(typeCode); |
| // Annotation fs = (Annotation) lowLevelSrcCasView.ll_getFSForRef(destFsAddr); |
| // the above creates an invalid Annotation, because it doesn't set the sofa ref for the view |
| // replace with below that includes the proper sofa ref |
| JCas srcJCas = srcCasView.getJCas(); |
| Annotation fs = new Annotation(srcJCas, 0, 4); |
| // fs.setIntValue(srcCas.getBeginFeature(), 0); |
| // fs.setIntValue(srcCas.getEndFeature(), 4); |
| assertEquals("This", fs.getCoveredText()); |
| srcCasView.addFsToIndexes(fs); |
| CasCopier.copyCas(srcCas, destCas, true); |
| CAS destCasView = destCas.getView("TestView"); |
| Iterator<Annotation> annotIter = destCasView.<Annotation>getAnnotationIndex().iterator(); |
| annotIter.next(); // document annotation |
| Annotation copiedFs = annotIter.next(); |
| assertEquals("This", copiedFs.getCoveredText()); |
| } |
| } |