| /** \file sofatest.cpp . |
| |
| * 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. |
| |
| -------------------------------------------------------------------------- */ |
| |
| /* ----------------------------------------------------------------------- */ |
| /* Include dependencies */ |
| /* ----------------------------------------------------------------------- */ |
| #include "uima/api.hpp" |
| #include "uima/xmlwriter.hpp" |
| #include "uima/xcasdeserializer.hpp" |
| #include "uima/internal_casserializer.hpp" |
| #include "uima/internal_casdeserializer.hpp" |
| |
| #include <fstream> |
| |
| #ifndef NDEBUG |
| #define ASSERT_OR_THROWEXCEPTION(x) assert(x) |
| #else |
| #define ASSERT_OR_THROWEXCEPTION(x) if (!(x)) { cerr << __FILE__ << ": Error in line " << __LINE__ << endl; exit(1); } |
| #endif |
| |
| #define LOG(x) cout << __FILE__ << __LINE__ << ": " << x << endl |
| |
| using namespace uima; |
| using namespace std; |
| |
| /* ----------------------------------------------------------------------- */ |
| /* Main routine */ |
| /* ----------------------------------------------------------------------- */ |
| |
| int main(int argc, char * argv[]) /* |
| ---------------------------------- */ |
| { |
| LOG("UIMATEST_SOFATEST started"); |
| int iRetVal = 0; |
| //iRetVal = _CrtSetBreakAlloc(824); |
| try { |
| char const * config = |
| "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" |
| "<typeSystemDescription xmlns=\"http://uima.apache.org/resourceSpecifier\">" |
| " <types>" |
| " <typeDescription>" |
| " <name>sofa.test.CrossAnnotation</name>" |
| " <description></description>" |
| " <supertypeName>uima.tcas.Annotation</supertypeName>" |
| " <features>" |
| " <featureDescription>" |
| " <name>otherAnnotation</name>" |
| " <description></description>" |
| " <rangeTypeName>uima.tcas.Annotation</rangeTypeName>" |
| " </featureDescription>" |
| " </features>" |
| " </typeDescription>" |
| " </types>" |
| "</typeSystemDescription>"; |
| |
| ResourceManager::createInstance("test"); |
| |
| ErrorInfo errorInfo; |
| ofstream outputStream; |
| |
| static TypeSystem *ts = Framework::createTypeSystemFromXMLBuffer(config, errorInfo ); |
| CAS* cas = Framework::createCAS(*ts, errorInfo); |
| ASSERT_OR_THROWEXCEPTION( EXISTS(cas) ); |
| |
| Type annotationType = ts->getType(CAS::TYPE_NAME_ANNOTATION); |
| Type docAnnotationType = ts->getType(CAS::TYPE_NAME_DOCUMENT_ANNOTATION); |
| Type crossType = ts->getType("sofa.test.CrossAnnotation"); |
| Feature otherFeat = crossType.getFeatureByBaseName("otherAnnotation"); |
| |
| // Create a Sofa (using old APIs for now) |
| SofaID * id = new SofaID; |
| id->setSofaId("EnglishDocument"); |
| SofaFS es = cas->createSofa(*id, "text"); |
| ASSERT_OR_THROWEXCEPTION(es.isValid()); |
| // Initial View is #1!!! |
| ASSERT_OR_THROWEXCEPTION(2 == es.getSofaRef()); |
| delete id; |
| // Set the document text |
| //TODO? es.setLocalSofaData("this beer is good"); |
| es.setLocalSofaData(UnicodeString("this beer is good")); |
| |
| // Test Multiple Sofas across XCAS serialization |
| outputStream.open("temp.xcas"); |
| if ( !outputStream ) { |
| cerr << "Error opening output stream" << endl; |
| return 1; |
| } |
| // Serialize XCAS |
| XCASWriter writer(*cas, false); |
| writer.write(outputStream); |
| outputStream.close(); |
| |
| // Deserialize XCAS |
| cas->reset(); |
| XCASDeserializer::deserialize("temp.xcas", *cas); |
| |
| // Add a new Sofa |
| CAS* gerTcas = cas->createView("GermanDocument"); |
| ASSERT_OR_THROWEXCEPTION(0 == gerTcas->getViewName().compare("GermanDocument")); |
| SofaFS gs = gerTcas->getSofa(); |
| |
| ASSERT_OR_THROWEXCEPTION(gs.isValid()); |
| ASSERT_OR_THROWEXCEPTION(3 == gs.getSofaRef()); |
| |
| // Set the document text |
| //TODO? gerTcas->setDocumentText("das bier ist gut"); |
| gerTcas->setDocumentText(UnicodeString("das bier ist gut")); |
| |
| // test getView()->getDocumentAnnotation()->getCoveredText() |
| AnnotationFS gerDocAnn = cas->getView("GermanDocument")->getDocumentAnnotation(); |
| ASSERT_OR_THROWEXCEPTION(0==gerDocAnn.getCoveredText().compare("das bier ist gut")); |
| |
| |
| // Test Multiple Sofas across XCAS serialization |
| outputStream.open("temp.xcas"); |
| if ( !outputStream ) { |
| cerr << "Error opening output stream" << endl; |
| return 1; |
| } |
| // Serialize XCAS |
| // XCASWriter writer2(*cas, false); |
| writer.write(outputStream); |
| outputStream.close(); |
| |
| // Deserialize XCAS |
| cas->reset(); |
| XCASDeserializer::deserialize("temp.xcas", *cas); |
| |
| |
| // Test multiple Sofas across binary serialization |
| internal::CASSerializer serializer(false); |
| internal::CASDeserializer deserializer; |
| size_t blobsz = serializer.getBlobSize(*cas); |
| char* blob = new char[blobsz]; |
| size_t blobsz2 = serializer.getBlob(*cas, blob, blobsz); |
| ASSERT_OR_THROWEXCEPTION(blobsz == blobsz2); |
| cas->reset(); |
| deserializer.deserializeBlob(blob, *cas); |
| delete[] blob; |
| |
| // Add a new Sofa |
| CAS* frT = cas->createView("FrenchDocument"); |
| ASSERT_OR_THROWEXCEPTION(0 == frT->getViewName().compare("FrenchDocument")); |
| SofaFS fs = frT->getSofa(); |
| ASSERT_OR_THROWEXCEPTION(fs.isValid()); |
| ASSERT_OR_THROWEXCEPTION(4 == fs.getSofaRef()); |
| |
| // Test multiple Sofas across blob serialization |
| blobsz = serializer.getBlobSize(*cas); |
| blob = new char[blobsz]; |
| blobsz2 = serializer.getBlob(*cas, blob, blobsz); |
| ASSERT_OR_THROWEXCEPTION(blobsz == blobsz2); |
| cas->reset(); |
| deserializer.deserializeBlob(blob, *cas); |
| delete[] blob; |
| |
| // Open Cas views of some Sofas |
| CAS* engTcas = cas->getView(es); |
| ASSERT_OR_THROWEXCEPTION(0 == engTcas->getViewName().compare("EnglishDocument")); |
| CAS* frTcas = cas->getView("FrenchDocument"); |
| |
| // Set the document text off SofaFS after the CAS view exists |
| // frTcas->setSofaDataString("cette biere est bonne", "text"); |
| frTcas->setSofaDataString(UnicodeString("cette biere est bonne"), "text"); |
| |
| // Create standard annotations against one and cross annotations against the other |
| AnnotationFS engAnnot = engTcas->createAnnotation(annotationType, 0, 4); |
| engTcas->getIndexRepository().addFS(engAnnot); |
| |
| AnnotationFS frAnnot = frTcas->createAnnotation(annotationType, 0, 5); |
| frTcas->getIndexRepository().addFS(frAnnot); |
| |
| AnnotationFS gerAnnot = gerTcas->createAnnotation(crossType, 0, 3); |
| gerAnnot.setFeatureValue(otherFeat, engAnnot); |
| gerTcas->getIndexRepository().addFS(gerAnnot); |
| |
| // test getView()->getDocumentAnnotation()->getCoveredText() |
| gerDocAnn = cas->getView("GermanDocument")->getDocumentAnnotation(); |
| ASSERT_OR_THROWEXCEPTION(0==gerDocAnn.getCoveredText().compare("das bier ist gut")); |
| |
| // Test that the annotations are in separate index spaces, and that Sofas are indexed |
| FSIterator sofaIter = cas->getSofaIterator(); |
| int numSofas = 0; |
| while (sofaIter.isValid()) { |
| numSofas++; |
| sofaIter.moveToNext(); |
| } |
| |
| FSIndex engIndex = engTcas->getAnnotationIndex(); |
| FSIndex gerIndex = gerTcas->getAnnotationIndex(); |
| FSIndex frIndex = frTcas->getAnnotationIndex(); |
| ASSERT_OR_THROWEXCEPTION(numSofas == 3); |
| |
| ASSERT_OR_THROWEXCEPTION(engIndex.getSize() == 2); // 1 annots plus documentAnnotation |
| ASSERT_OR_THROWEXCEPTION(gerIndex.getSize() == 2); // 1 annots plus documentAnnotation |
| ASSERT_OR_THROWEXCEPTION(frIndex.getSize() == 2); // 1 annots plus documentAnnotation |
| |
| // Test that the annotations are of the correct types |
| FSIterator engIt = engIndex.iterator(); |
| FSIterator gerIt = gerIndex.iterator(); |
| FSIterator frIt = frIndex.iterator(); |
| engAnnot = (AnnotationFS)engIt.get(); |
| gerAnnot = (AnnotationFS)gerIt.get(); |
| frAnnot = (AnnotationFS)frIt.get(); |
| ASSERT_OR_THROWEXCEPTION(0==docAnnotationType.getName().compare(engAnnot.getType().getName())); |
| ASSERT_OR_THROWEXCEPTION(0==docAnnotationType.getName().compare(gerAnnot.getType().getName())); |
| ASSERT_OR_THROWEXCEPTION(0==docAnnotationType.getName().compare(frAnnot.getType().getName())); |
| |
| engIt.moveToNext(); |
| gerIt.moveToNext(); |
| frIt.moveToNext(); |
| engAnnot = (AnnotationFS)engIt.get(); |
| gerAnnot = (AnnotationFS)gerIt.get(); |
| frAnnot = (AnnotationFS)frIt.get(); |
| ASSERT_OR_THROWEXCEPTION(0==annotationType.getName().compare(engAnnot.getType().getName())); |
| ASSERT_OR_THROWEXCEPTION(0==engAnnot.getCoveredText().compare("this")); |
| ASSERT_OR_THROWEXCEPTION(0==annotationType.getName().compare(frAnnot.getType().getName())); |
| ASSERT_OR_THROWEXCEPTION(0==frAnnot.getCoveredText().compare("cette")); |
| ASSERT_OR_THROWEXCEPTION(0==crossType.getName().compare(gerAnnot.getType().getName())); |
| ASSERT_OR_THROWEXCEPTION(0==gerAnnot.getCoveredText().compare("das")); |
| |
| // Test that the other annotation feature of cross annotations works |
| AnnotationFS crossAnnot = (AnnotationFS) gerAnnot.getFeatureValue(otherFeat); |
| ASSERT_OR_THROWEXCEPTION(0==annotationType.getName().compare(crossAnnot.getType().getName())); |
| ASSERT_OR_THROWEXCEPTION(0==crossAnnot.getCoveredText().compare("this")); |
| |
| |
| |
| // -------------------------------------------------------- |
| // Test that annotations accessed from a reference in the base CAS work correctly |
| // -------------------------------------------------------- |
| |
| ArrayFS anArray = cas->createArrayFS(3); |
| anArray.set(0, engAnnot); |
| anArray.set(1, frAnnot); |
| anArray.set(2, gerAnnot); |
| AnnotationFS tstAnnot = (AnnotationFS)anArray.get(0); |
| ASSERT_OR_THROWEXCEPTION(0==tstAnnot.getCoveredText().compare("this")); |
| tstAnnot = (AnnotationFS)anArray.get(1); |
| ASSERT_OR_THROWEXCEPTION(0==tstAnnot.getCoveredText().compare("cette")); |
| tstAnnot = (AnnotationFS)anArray.get(2); |
| ASSERT_OR_THROWEXCEPTION(0==tstAnnot.getCoveredText().compare("das")); |
| |
| |
| // -------------------------------------------------------- |
| // Test that a FS can be indexed in multiple Views |
| // -------------------------------------------------------- |
| |
| CAS* marView = cas->createView("MartinView"); |
| marView->getIndexRepository().addFS(engAnnot); |
| |
| // Serialize XCAS |
| outputStream.open("temp.xcas"); |
| if ( !outputStream ) { |
| cerr << "Error opening output stream" << endl; |
| return 1; |
| } |
| writer.write(outputStream); |
| outputStream.close(); |
| // Deserialize XCAS |
| cas->reset(); |
| XCASDeserializer::deserialize("temp.xcas", *cas); |
| |
| marView = cas->getView("MartinView"); |
| FSIndex mrIndex = marView->getAnnotationIndex(annotationType); |
| FSIterator mrIt = mrIndex.iterator(); |
| ASSERT_OR_THROWEXCEPTION(mrIt.isValid()); |
| engAnnot = (AnnotationFS)mrIt.get(); |
| ASSERT_OR_THROWEXCEPTION(0==engAnnot.getCoveredText().compare("this")); |
| |
| // -------------------------------------------------------- |
| // Test reuse of views with createSofa |
| // -------------------------------------------------------- |
| |
| cas->reset(); |
| cas->setDocumentText(UnicodeString("setDocumentText creates the _InitialView Sofa")); |
| CAS* testView = cas->createView("anotherView"); |
| ASSERT_OR_THROWEXCEPTION(0 == testView->getViewName().compare("anotherView")); |
| ASSERT_OR_THROWEXCEPTION(0 == cas->getViewName().compare("_InitialView")); |
| |
| cas->reset(); |
| SofaID * nuid = new SofaID; |
| nuid->setSofaId("testView"); |
| SofaFS tv = cas->createSofa(*nuid, "text"); |
| testView = cas->getView(tv); |
| ASSERT_OR_THROWEXCEPTION(0 == testView->getViewName().compare("testView")); |
| delete nuid; |
| |
| // -------------------------------------------------------- |
| // Test sofa data stream |
| // -------------------------------------------------------- |
| |
| char dest[100]; |
| //Test reading sofa data set as String feature. |
| cas->reset(); |
| CAS * stringView = cas->createView("StringSofaData"); |
| UnicodeString ustrText("this beer is good"); |
| stringView->setDocumentText(ustrText); |
| SofaDataStream * pStream = stringView->getSofaDataStream(); |
| ASSERT_OR_THROWEXCEPTION(pStream != NULL); |
| ASSERT_OR_THROWEXCEPTION( pStream->open()== 0); |
| int totsize = pStream->getTotalStreamSizeInBytes(); |
| ASSERT_OR_THROWEXCEPTION(totsize > 0); |
| ASSERT_OR_THROWEXCEPTION(pStream->read(dest,1,totsize) == totsize); |
| ASSERT_OR_THROWEXCEPTION(strncmp(dest, "this beer is good", totsize) == 0); |
| delete pStream; |
| |
| //read sofa data from SofaURI. |
| CAS * remoteView = cas->createView("remoteSofaData"); |
| ustrText = "text"; |
| std::string fn = "file://"; |
| fn.append(UnicodeStringRef(ResourceManager::resolveFilename("example.txt", ".")).asUTF8()); |
| remoteView->setSofaDataURI(fn.c_str(), "text"); |
| pStream = remoteView->getSofaDataStream(); |
| ASSERT_OR_THROWEXCEPTION(pStream != NULL); |
| ASSERT_OR_THROWEXCEPTION( pStream->open()== 0); |
| totsize = pStream->getTotalStreamSizeInBytes(); |
| ASSERT_OR_THROWEXCEPTION(totsize > 0); |
| ASSERT_OR_THROWEXCEPTION(pStream->read(dest,1,totsize) == totsize); |
| ASSERT_OR_THROWEXCEPTION(strncmp(dest, "This is a text document with a Dave for analysis.", totsize) == 0); |
| delete pStream; |
| |
| |
| //read sofa data set as int array FS. |
| IntArrayFS intArrayFS = cas->createIntArrayFS(5); |
| intArrayFS.set(0,1); |
| intArrayFS.set(1,2); |
| intArrayFS.set(2,3); |
| intArrayFS.set(3,4); |
| intArrayFS.set(4,5); |
| CAS * intArrayView = cas->createView("intArraySofaData"); |
| intArrayView->setSofaDataArray(intArrayFS, "integers"); |
| pStream = intArrayView->getSofaDataStream(); |
| ASSERT_OR_THROWEXCEPTION(pStream != NULL); |
| ASSERT_OR_THROWEXCEPTION( pStream->open()== 0); |
| int value; |
| int i=0; |
| while (pStream->read(&value, sizeof(int), 1) != -1) { |
| ASSERT_OR_THROWEXCEPTION(value == intArrayFS.get(i++)); |
| } |
| delete pStream; |
| |
| //read sofa data set as float array FS. |
| FloatArrayFS floatArrayFS = cas->createFloatArrayFS(5); |
| floatArrayFS.set(0,(float) 0.1); |
| floatArrayFS.set(1,(float) 0.2); |
| floatArrayFS.set(2,(float) 0.3); |
| floatArrayFS.set(3,(float) 0.4); |
| floatArrayFS.set(4,(float) 0.5); |
| CAS * floatArrayView = cas->createView("floatArraySofaData"); |
| floatArrayView->setSofaDataArray(floatArrayFS,"floats"); |
| pStream = floatArrayView->getSofaDataStream(); |
| ASSERT_OR_THROWEXCEPTION(pStream != NULL); |
| ASSERT_OR_THROWEXCEPTION( pStream->open()== 0); |
| float floatvalue; |
| i=0; |
| while (pStream->read(&floatvalue, sizeof(float), 1) != -1) { |
| ASSERT_OR_THROWEXCEPTION(floatvalue == floatArrayFS.get(i++)); |
| } |
| delete pStream; |
| |
| //create a Sofa and set the SofaArray feature to a short array FS. |
| ShortArrayFS shortArrayFS = cas->createShortArrayFS(5); |
| shortArrayFS.set(0,(short)128); |
| shortArrayFS.set(1,(short)127); |
| shortArrayFS.set(2,(short)126); |
| shortArrayFS.set(3,(short)125); |
| shortArrayFS.set(4,(short)124); |
| CAS * shortArrayView = cas->createView("shortArraySofaData"); |
| shortArrayView->setSofaDataArray(shortArrayFS, "shorts"); |
| pStream = shortArrayView->getSofaDataStream(); |
| ASSERT_OR_THROWEXCEPTION(pStream != NULL); |
| ASSERT_OR_THROWEXCEPTION( pStream->open()== 0); |
| short shortvalue; |
| i=0; |
| while (pStream->read(&shortvalue, sizeof(short), 1) != -1) { |
| //cout << shortvalue << " " << shortArrayFS.get(i << endl; |
| ASSERT_OR_THROWEXCEPTION(shortvalue == shortArrayFS.get(i++)); |
| } |
| delete pStream; |
| |
| //create a Sofa and set the SofaArray feature to a byte array FS. |
| ByteArrayFS byteArrayFS = cas->createByteArrayFS(4); |
| byteArrayFS.set(0, 'a' ); |
| byteArrayFS.set(1, 'b'); |
| byteArrayFS.set(2, 'c'); |
| byteArrayFS.set(3, 'd'); |
| CAS * byteArrayView = cas->createView("byteArraySofaData"); |
| byteArrayView->setSofaDataArray(byteArrayFS, "bytes"); |
| pStream = byteArrayView->getSofaDataStream(); |
| ASSERT_OR_THROWEXCEPTION(pStream != NULL); |
| ASSERT_OR_THROWEXCEPTION( pStream->open()== 0); |
| char bytevalue; |
| i=0; |
| while (pStream->read(&bytevalue, 1, 1) != -1) { |
| ASSERT_OR_THROWEXCEPTION(bytevalue == byteArrayFS.get(i++)); |
| } |
| delete pStream; |
| |
| //create a Sofa and set the SofaArray feature to a long array FS. |
| LongArrayFS longArrayFS = cas->createLongArrayFS(5); |
| longArrayFS.set(0,11); |
| longArrayFS.set(1,21); |
| longArrayFS.set(2,31); |
| longArrayFS.set(3,41); |
| longArrayFS.set(4,51); |
| CAS * longArrayView = cas->createView("longArraySofaData"); |
| longArrayView->setSofaDataArray(longArrayFS, "longs"); |
| pStream = longArrayView->getSofaDataStream(); |
| ASSERT_OR_THROWEXCEPTION(pStream != NULL); |
| ASSERT_OR_THROWEXCEPTION( pStream->open()== 0); |
| INT64 longvalue; |
| i=0; |
| while (pStream->read(&longvalue, sizeof(INT64), 1) != -1) { |
| ASSERT_OR_THROWEXCEPTION(longvalue == longArrayFS.get(i++)); |
| } |
| delete pStream; |
| |
| //create a Sofa and set the SofaArray feature to a Double Array FS. |
| DoubleArrayFS doubleArrayFS = cas->createDoubleArrayFS(5); |
| doubleArrayFS.set(0,21E10); |
| doubleArrayFS.set(1,31E10); |
| doubleArrayFS.set(2,41E10); |
| doubleArrayFS.set(3,51E10); |
| doubleArrayFS.set(4,61E10); |
| CAS * doubleArrayView = cas->createView("doubleArraySofaData"); |
| doubleArrayView->setSofaDataArray(doubleArrayFS, "doubles"); |
| pStream = doubleArrayView->getSofaDataStream(); |
| ASSERT_OR_THROWEXCEPTION(pStream != NULL); |
| ASSERT_OR_THROWEXCEPTION( pStream->open()== 0); |
| i=0; |
| double doubleValue; |
| while (pStream->read(&doubleValue, sizeof(double), 1) != -1) { |
| ASSERT_OR_THROWEXCEPTION( doubleArrayFS.get(i++) == doubleValue); |
| } |
| delete pStream; |
| |
| delete ts; |
| delete cas; |
| |
| LOG("UIMATEST_SOFATEST finished"); |
| } catch (Exception & exc) { |
| cerr << exc.asString() << endl; |
| iRetVal = 1; |
| } |
| #ifdef NDEBUG |
| catch (...) { |
| cerr << "Unexpected exception " << endl; |
| iRetVal = 1; |
| } |
| #else |
| ResourceManager::deleteInstance(); |
| #endif |
| return iRetVal; |
| } |
| |
| /* <EOF> */ |