blob: 2b94e3b698e3f87e4843517f8856d33ef9bbf51e [file] [log] [blame]
/** \file test_engine_basic.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/pragmas.hpp"
#include "uima/macros.h"
#include "uima/engine.hpp"
#include "uima/resmgr.hpp"
#include <iostream>
#include "uima/lowlevel_indexiterator.hpp"
#include "uima/lowlevel_fsheap.hpp"
#include "uima/lowlevel_typesystem.hpp"
#include "uima/fsfilterbuilder.hpp"
#include "uima/cas.hpp"
#include "uima/listfs.hpp"
#include "uima/arrayfs.hpp"
#include "uima/lowlevel_indexrepository.hpp"
#include "uima/lowlevel_fsfilter.hpp"
#include "uima/xmltypesystemreader.hpp"
#include "xercesc/util/PlatformUtils.hpp"
#include "xercesc/sax/SAXParseException.hpp"
#include "uima/internal_casimpl.hpp"
#include "uima/internal_fspromoter.hpp"
#include "uima/fsindexrepository.hpp"
#include "uima/typenamespace.hpp"
#include "uima/tt_types.hpp"
#include "uima/internal_aggregate_engine.hpp"
#include "uima/casdefinition.hpp"
#include "uima/taespecifierbuilder.hpp"
#include "xercesc/parsers/XercesDOMParser.hpp"
#include "xercesc/parsers/SAXParser.hpp"
#include "xercesc/dom/DOMException.hpp"
#include "xercesc/dom/DOMNamedNodeMap.hpp"
#include "xercesc/dom/DOMDocument.hpp"
#include "xercesc/dom/DOMElement.hpp"
#include "xercesc/dom/DOMNodeList.hpp"
#include "xercesc/framework/MemBufInputSource.hpp"
#include "uima/xmlerror_handler.hpp"
using namespace uima;
using namespace uima::internal;
/* ----------------------------------------------------------------------- */
/* Constants */
/* ----------------------------------------------------------------------- */
#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
/* ----------------------------------------------------------------------- */
/* Forward declarations */
/* ----------------------------------------------------------------------- */
/* ----------------------------------------------------------------------- */
/* Types / Classes */
/* ----------------------------------------------------------------------- */
/* ----------------------------------------------------------------------- */
/* Implementation */
/* ----------------------------------------------------------------------- */
static icu::UnicodeString ustrCreatorID("test");
namespace uima {
namespace internal {
class TTDefinition : public CASDefinition {
public:
void createTTTAESpecifier(TextAnalysisEngineSpecifier & result) {
/* insert lines to match original code so LOG msgs have same line numbers!
*/
const util::Location & crDataDir = ResourceManager::getInstance().getLocationData();
std::string nameInDataDir(crDataDir.getAsCString() );
nameInDataDir += "descriptors";
util::Filename typesystemFile(nameInDataDir.c_str(),"tt_typesystem.xml");
typesystemFile.normalize();
util::Filename indexesFile(nameInDataDir.c_str(),"tt_indexes.xml");
indexesFile.normalize();
icu::UnicodeString typesystemFileUnicode( typesystemFile.getAsCString() );
icu::UnicodeString indexesFileUnicode( indexesFile.getAsCString() );
// add the typesystem from an xml file
std::string tt_types("<?xml version=\"1.0\"?> <taeDescription><analysisEngineMetaData> <typeSystemDescription> <imports> <import location=\"");
tt_types.append( typesystemFile.getAsCString() );
tt_types.append("\"/> </imports> </typeSystemDescription> <fsIndexCollection> <imports> <import location=\"");
tt_types.append(indexesFile.getAsCString() );
tt_types.append("\"/> </imports> </fsIndexCollection> </analysisEngineMetaData> </taeDescription>");
uima::TextAnalysisEngineSpecifierBuilder builder;
XercesDOMParser parser;
uima::XMLErrorHandler errorHandler;
parser.setErrorHandler(& errorHandler);
MemBufInputSource memSource((XMLByte const *) tt_types.c_str(), tt_types.length(), "TT typesystem" );
///XIncluder includer;
///InputSource const & is = includer.resolveXIncludes(memSource);
///parser.parse( is );
parser.parse(memSource);
DOMDocument* doc = parser.getDocument();
assert(EXISTS(doc));
// get top node
DOMElement * rootElem = doc->getDocumentElement();
assert(EXISTS(rootElem));
// icu::UnicodeString fileLoc( typesystemFile.getAsCString() );
builder.buildTae(result, rootElem, ".");
}
void createPredefinedTTTypes() {
TextAnalysisEngineSpecifier specifier;
createTTTAESpecifier(specifier);
mergeTypeSystem(specifier);
addTypePriorities(specifier);
}
void createPredefinedTTIndexes() {
TextAnalysisEngineSpecifier specifier;
createTTTAESpecifier(specifier);
uima::AnnotatorContext anc(& specifier);
createIndexesFromANC(anc);
}
void createTypes() {
CASDefinition::createTypes();
createPredefinedTTTypes();
}
void createIndexes() {
CASDefinition::createIndexes();
createPredefinedTTIndexes();
}
TTDefinition()
: CASDefinition(NULL) {}
~TTDefinition() { }
void commitTypeSystem() {
CASDefinition::commitTypeSystem();
}
void commitIndexDefinition() {
CASDefinition::commitIndexDefinition();
}
};
}
}
uima::internal::CASImpl * getCASImpl(uima::internal::CASDefinition & casDef) {
ErrorInfo errorInfo;
return (uima::internal::CASImpl*) Framework::createCAS(casDef, errorInfo);
}
class TestCAS {
uima::internal::TTDefinition * iv_casDef;
uima::internal::CASImpl * iv_cas;
public:
TestCAS()
: iv_casDef() {
iv_casDef = new uima::internal::TTDefinition();
iv_casDef->init();
iv_casDef->commit();
// iv_cas = new uima::internal::TCASImpl(*iv_casDef, 5000, 5000, 5000);
ErrorInfo errorInfo;
iv_cas = (uima::internal::CASImpl*)Framework::createCAS(*iv_casDef, errorInfo);
}
~TestCAS() {
delete iv_cas;
delete iv_casDef;
}
uima::internal::TTDefinition & getCASDef() {
return *iv_casDef;
}
uima::internal::CASImpl & getCAS() {
return * iv_cas;
}
};
/*
void prepareCAS(CAS & cas) {
uima::internal::TCASImpl & tcas = uima::internal::TCASImpl::promoteCAS(cas);
tcas.createPredefinedTTTypes();
tcas.commitTypeSystem();
tcas.createPredefinedTTIndexes();
}
*/
void testLowLevelTypeSystem() {
LOG("testLowlevelTypeSystem() started");
ASSERT_OR_THROWEXCEPTION( uima::TypeSystem::NAMESPACE_SEPARATOR == UIMA_NAMESPACE_SEPARATOR_CHAR );
ASSERT_OR_THROWEXCEPTION( uima::TypeSystem::FEATURE_SEPARATOR == UIMA_TYPE_FEATURE_SEPARATOR_CHAR);
/*
top
t1 [f1: t3, g1:t4]
t11 [f11: t21]
t111
t12 [f12: t211]
t13 [f13: t14]
t131 [f131: t132, g131: top]
t132
t14 [f14: t2]
t2 [f2:t2]
t21 [f21:t2, g21: t211]
t211
t2111
t3
t31 [f31: t32, g31: t321]
t32
t321 [f321: t4]
t4
*/
TTDefinition ttdef;
ttdef.init();
lowlevel::TypeSystem& ts = ttdef.getTypeSystem();
lowlevel::TyFSType top = ts.getTopType();
ASSERT_OR_THROWEXCEPTION( ts.isValidType(top) );
lowlevel::TyFSType t1 = ts.createType(top, "t1", ustrCreatorID);
ASSERT_OR_THROWEXCEPTION( ts.isValidType(t1) );
lowlevel::TyFSType t2 = ts.createType(top, "t2", ustrCreatorID);
ASSERT_OR_THROWEXCEPTION( ts.isValidType(t2) );
lowlevel::TyFSType t3 = ts.createType(top, "t3", ustrCreatorID);
ASSERT_OR_THROWEXCEPTION( ts.isValidType(t3) );
lowlevel::TyFSType t31 = ts.createType(t3, "t31", ustrCreatorID);
ASSERT_OR_THROWEXCEPTION( ts.isValidType(t31) );
lowlevel::TyFSType t32 = ts.createType(t3, "t32", ustrCreatorID);
ASSERT_OR_THROWEXCEPTION( ts.isValidType(t32) );
lowlevel::TyFSType t321 = ts.createType(t32, "t321", ustrCreatorID);
ASSERT_OR_THROWEXCEPTION( ts.isValidType(t321) );
lowlevel::TyFSType t4 = ts.createType(top, "t4", ustrCreatorID);
ASSERT_OR_THROWEXCEPTION( ts.isValidType(t4) );
lowlevel::TyFSType t21 = ts.createType(t2, "t21", ustrCreatorID);
ASSERT_OR_THROWEXCEPTION( ts.isValidType(t21) );
lowlevel::TyFSType t211 = ts.createType(t21, "t211", ustrCreatorID);
ASSERT_OR_THROWEXCEPTION( ts.isValidType(t211) );
lowlevel::TyFSType t2111 = ts.createType(t211, "t2111", ustrCreatorID);
ASSERT_OR_THROWEXCEPTION( ts.isValidType(t2111) );
lowlevel::TyFSType t11 = ts.createType(t1, "t11", ustrCreatorID);
ASSERT_OR_THROWEXCEPTION( ts.isValidType(t11) );
lowlevel::TyFSType t111 = ts.createType(t11, "t111", ustrCreatorID);
ASSERT_OR_THROWEXCEPTION( ts.isValidType(t111) );
lowlevel::TyFSType t12 = ts.createType(t1, "t12", ustrCreatorID);
ASSERT_OR_THROWEXCEPTION( ts.isValidType(t12) );
lowlevel::TyFSType t13 = ts.createType(t1, "t13", ustrCreatorID);
ASSERT_OR_THROWEXCEPTION( ts.isValidType(t13) );
lowlevel::TyFSType t14 = ts.createType(t1, "t14", ustrCreatorID);
ASSERT_OR_THROWEXCEPTION( ts.isValidType(t14) );
lowlevel::TyFSType t131 = ts.createType(t13, "t131", ustrCreatorID);
ASSERT_OR_THROWEXCEPTION( ts.isValidType(t131) );
lowlevel::TyFSType t132 = ts.createType(t13, "t132", ustrCreatorID);
ASSERT_OR_THROWEXCEPTION( ts.isValidType(t132) );
lowlevel::TyFSFeature f1 = ts.createFeature(t1, t3, false, "f1", ustrCreatorID);
ASSERT_OR_THROWEXCEPTION( ts.isValidFeature(f1) );
lowlevel::TyFSFeature g1 = ts.createFeature(t1, t4, false, "g1", ustrCreatorID);
ASSERT_OR_THROWEXCEPTION( ts.isValidFeature(g1) );
lowlevel::TyFSFeature f11 = ts.createFeature(t11, t21, false, "f11", ustrCreatorID);
ASSERT_OR_THROWEXCEPTION( ts.isValidFeature(f11) );
lowlevel::TyFSFeature f12 = ts.createFeature(t12, t211, false, "f12", ustrCreatorID);
ASSERT_OR_THROWEXCEPTION( ts.isValidFeature(f12) );
lowlevel::TyFSFeature f13 = ts.createFeature(t13, t14, false, "f13", ustrCreatorID);
ASSERT_OR_THROWEXCEPTION( ts.isValidFeature(f13) );
lowlevel::TyFSFeature f131 = ts.createFeature(t131, t132, false, "f131", ustrCreatorID);
ASSERT_OR_THROWEXCEPTION( ts.isValidFeature(f131) );
lowlevel::TyFSFeature g131 = ts.createFeature(t131, top, false, "g131", ustrCreatorID);
ASSERT_OR_THROWEXCEPTION( ts.isValidFeature(g131) );
lowlevel::TyFSFeature f14 = ts.createFeature(t14, t2, false, "f14", ustrCreatorID);
ASSERT_OR_THROWEXCEPTION( ts.isValidFeature(f14) );
lowlevel::TyFSFeature f2 = ts.createFeature(t2, t2, false, "f2", ustrCreatorID);
ASSERT_OR_THROWEXCEPTION( ts.isValidFeature(f2) );
lowlevel::TyFSFeature f21 = ts.createFeature(t21, t2, false, "f21", ustrCreatorID);
ASSERT_OR_THROWEXCEPTION( ts.isValidFeature(f21) );
lowlevel::TyFSFeature g21 = ts.createFeature(t21, t211, false, "g21", ustrCreatorID);
ASSERT_OR_THROWEXCEPTION( ts.isValidFeature(g21) );
lowlevel::TyFSFeature f31 = ts.createFeature(t31, t32, false, "f31", ustrCreatorID);
ASSERT_OR_THROWEXCEPTION( ts.isValidFeature(f31) );
lowlevel::TyFSFeature g31 = ts.createFeature(t31, t321, false, "g31", ustrCreatorID);
ASSERT_OR_THROWEXCEPTION( ts.isValidFeature(g31) );
lowlevel::TyFSFeature f321 = ts.createFeature(t321, t4, false, "f321", ustrCreatorID);
ASSERT_OR_THROWEXCEPTION( ts.isValidFeature(f321) );
ttdef.commit();
assert( ts.debugIsConsistent() );
#ifndef NDEBUG
ts.print(cout);
#endif
// check subsumption
#define SUBSCHECK_N 17
lowlevel::TyFSType subscheck[SUBSCHECK_N][2] = {
{top, t1}, // 1
{top, top}, // 2
{t11, t111}, // 3
{t13, t131}, // 4
{t13, t132}, // 5
{t2, t21}, // 6
{t21, t211}, // 7
{t211, t2111}, // 8
{t3, t31}, // 9
{t3, t32}, // 10
{t4, t4}, // 11
{top, t2111}, // 12
{t1, t111}, // 13
{t2, t2111}, // 14
{t3, t321}, // 15
{top, t321}, // 16
{top, top} // 17
};
int i;
for (i=0; i<SUBSCHECK_N; ++i) {
lowlevel::TyFSType st1 = subscheck[i][0];
lowlevel::TyFSType st2 = subscheck[i][1];
ASSERT_OR_THROWEXCEPTION( ts.subsumes(st1, st2) );
if (st1 == st2) {
ASSERT_OR_THROWEXCEPTION( ts.subsumes(st2, st1) );
} else {
ASSERT_OR_THROWEXCEPTION( ! ts.subsumes(st2, st1) );
}
}
// check appropriateness
#define APPROPCHECK 14
int appropcheck[APPROPCHECK][2] = {
{
t1, f1
}
, // 0
{t1, g1}, // 1
{t111, f1}, //2
{t12, g1}, //3
{t131, g1}, //4
{t131, f131}, //5
{t131, g131}, //6
{t14, f14}, //7
{t21, f21}, //8
{t211, f21}, //9
{t2111, f21}, //10
{t31, f31}, //11
{t31, f31}, //12
{t321, f321} //13
};
for (i=0; i< APPROPCHECK; ++i) {
lowlevel::TyFSType act = appropcheck[i][0];
lowlevel::TyFSFeature acf = appropcheck[i][1];
UIMA_TPRINT(" Checking approp: feature " << acf << ", type " << act);
ASSERT_OR_THROWEXCEPTION( ts.isAppropriateFeature(act, acf) );
ASSERT_OR_THROWEXCEPTION( acf == ts.getFeatureFromOffset(act, ts.getFeatureOffset( acf) ) );
}
LOG(" Testing OO API TypeSystem calls");
Type oot1 = ts.getType("t1");
ASSERT_OR_THROWEXCEPTION( oot1.isValid() );
Type oot11 = ts.getType("t11");
ASSERT_OR_THROWEXCEPTION( oot11.isValid() );
ASSERT_OR_THROWEXCEPTION( oot1.subsumes(oot11) );
ASSERT_OR_THROWEXCEPTION( ! oot11.subsumes(oot1) );
// FeatureStructure oofs11 = cas.createFS(oot11);
LOG(" Finished Testing OO API TypeSystem calls");
LOG("testLowlevelTypeSystem() finished");
}
void testLowLevelTypeSystemExceptions() {
LOG("testLowlevelTypeSystenExceptions() started");
TTDefinition ttdef;
ttdef.init();
uima::lowlevel::TypeSystem & rTypeSystem = ttdef.getTypeSystem();
uima::lowlevel::TyFSType intType = rTypeSystem.getTypeByName(CAS::TYPE_NAME_INTEGER);
bool bExceptionThrown = false;
LOG("Creating feature on top");
try {
rTypeSystem.createFeature( rTypeSystem.getTopType(), intType, false, "bla", "test");
} catch (uima::lowlevel::FeatureIntroductionFailedException & exc) {
LOG("Exception thrown correctly: " << exc.asString());
bExceptionThrown = true;
}
ASSERT_OR_THROWEXCEPTION( bExceptionThrown );
LOG("Creating subtype of integer");
bExceptionThrown = false;
try {
rTypeSystem.createType( intType, "bla", "test");
} catch (uima::lowlevel::TypeCreationFailedException & exc) {
LOG("Exception thrown correctly: " << exc.asString());
bExceptionThrown = true;
}
ASSERT_OR_THROWEXCEPTION( bExceptionThrown );
LOG("Creating feature on integer");
bExceptionThrown = false;
try {
rTypeSystem.createFeature( intType, intType, false, "bla", "test");
} catch (uima::lowlevel::FeatureIntroductionFailedException & exc) {
LOG("Exception thrown correctly: " << exc.asString());
bExceptionThrown = true;
}
ASSERT_OR_THROWEXCEPTION( bExceptionThrown );
LOG("testLowlevelTypeSystenExceptions() finished");
}
/************************************************************************************/
/*
void testOOTypeSystem() {
LOG("testOOTypeSystem() started");
/ *
top
t1 [f1: t3, g1:t4]
t11 [f11: t21]
t111
t12 [f12: t211]
t13 [f13: t14]
t131 [f131: t132, g131: top]
t132
t14 [f14: t2]
t2 [f2:t2]
t21 [f21:t2, g21: t211]
t211
t2111
t3
t31 [f31: t32, g31: t321]
t32
t321 [f321: t4]
t4
* /
Type someType;
ASSERT_OR_THROWEXCEPTION( ! someType.isValid() );
Feature someFeature;
ASSERT_OR_THROWEXCEPTION( ! someFeature.isValid() );
uima::internal::TCASImpl cas(50000);
FSSystem & fsSystem = cas.getFSSystem();
Type top = fsSystem.getTopType();
Type t1 = top.addSubType("t1");
ASSERT_OR_THROWEXCEPTION( t1.isValid() );
Type t2 = top.addSubType("t2");
ASSERT_OR_THROWEXCEPTION( t2.isValid() );
Type t21 = t2.addSubType("t21");
ASSERT_OR_THROWEXCEPTION( t21.isValid() );
Type t3 = top.addSubType("t3");
ASSERT_OR_THROWEXCEPTION( t3.isValid() );
Type t4 = top.addSubType("t4");
ASSERT_OR_THROWEXCEPTION( t4.isValid() );
Feature f1 = t1.introduceFeature("f1", t3);
ASSERT_OR_THROWEXCEPTION( f1.isValid() );
Feature g1 = t1.introduceFeature("g1", t4);
ASSERT_OR_THROWEXCEPTION( g1.isValid() );
Type t11 = t1.addSubType("t11");
ASSERT_OR_THROWEXCEPTION( t11.isValid() );
Feature f11 = t11.introduceFeature("f11", t21);
ASSERT_OR_THROWEXCEPTION( f11.isValid() );
Type t11prime = fsSystem.findTypeByName("t11");
ASSERT_OR_THROWEXCEPTION( t11 == t11prime );
cas.commitTypeSystem();
ASSERT_OR_THROWEXCEPTION( t1.subsumes(t11) );
ASSERT_OR_THROWEXCEPTION( ! t11.subsumes(t1) );
FeatureStructure fs11 = fsSystem.createFS(t11);
LOG("testOOTypeSystem() finished");
}
*/
/************************************************************************************/
void testLowLevelFSHeap() {
LOG("testLowlevelFSHeap started");
TestCAS testcas;
lowlevel::TypeSystem& ts = testcas.getCASDef().getTypeSystem();
assert( ts.debugIsConsistent() );
LOG("Type system commited");
lowlevel::FSHeap & heap = testcas.getCAS().getHeap();
// FSHeap heap(ts, 50000);
LOG("Creating annotation name string");
icu::UnicodeString usAnnotationTypeName(CAS::TYPE_NAME_ANNOTATION);
LOG(" annotation name string created");
lowlevel::TyFSType annotationType = ts.getTypeByName( usAnnotationTypeName );
ASSERT_OR_THROWEXCEPTION( ts.isValidType(annotationType) );
lowlevel::TyFSFeature beginPosFeat = ts.getFeatureByBaseName(annotationType, CAS::FEATURE_BASE_NAME_BEGIN );
ASSERT_OR_THROWEXCEPTION( ts.isValidFeature(beginPosFeat) );
lowlevel::TyFSFeature endPosFeat = ts.getFeatureByBaseName( annotationType, CAS::FEATURE_BASE_NAME_END );
ASSERT_OR_THROWEXCEPTION( ts.isValidFeature(endPosFeat) );
lowlevel::TyFSType tokenAnnotationType = ts.getTypeByName( TT::TYPE_NAME_TOKEN_ANNOTATION );
ASSERT_OR_THROWEXCEPTION( ts.isValidType( tokenAnnotationType ) );
lowlevel::TyFSFeature lemmaEntryFeat = ts.getFeatureByBaseName( tokenAnnotationType, TT::FEATURE_BASE_NAME_LEMMA_ENTRIES );
ASSERT_OR_THROWEXCEPTION( ts.isValidFeature( lemmaEntryFeat ) );
lowlevel::TyFSType lemmaType = ts.getTypeByName( TT::TYPE_NAME_LEMMA );
ASSERT_OR_THROWEXCEPTION( ts.isValidType( lemmaType ) );
lowlevel::TyFSType keyFeature = ts.getFeatureByBaseName( lemmaType, TT::FEATURE_BASE_NAME_KEY );
ASSERT_OR_THROWEXCEPTION( ts.isValidFeature( keyFeature ) );
lowlevel::TyFSType listType = ts.getTypeByName(CAS::TYPE_NAME_FS_LIST );
ASSERT_OR_THROWEXCEPTION( ts.isValidType( listType ) );
lowlevel::TyFSType ne_listType = ts.getTypeByName(CAS::TYPE_NAME_NON_EMPTY_FS_LIST );
ASSERT_OR_THROWEXCEPTION( ts.isValidType( ne_listType ) );
lowlevel::TyFSType e_listType = ts.getTypeByName(CAS::TYPE_NAME_EMPTY_FS_LIST );
ASSERT_OR_THROWEXCEPTION( ts.isValidType( e_listType ) );
lowlevel::TyFSFeature headFeature = ts.getFeatureByBaseName(ne_listType, CAS::FEATURE_BASE_NAME_HEAD );
ASSERT_OR_THROWEXCEPTION( ts.isValidFeature( headFeature ) );
lowlevel::TyFSFeature tailFeature = ts.getFeatureByBaseName(ne_listType, CAS::FEATURE_BASE_NAME_TAIL );
ASSERT_OR_THROWEXCEPTION( ts.isValidFeature( tailFeature ) );
lowlevel::TyFS annot1 = heap.createFS(annotationType);
ASSERT_OR_THROWEXCEPTION( heap.getType(annot1) == annotationType );
heap.setIntValue(annot1, beginPosFeat, 42);
ASSERT_OR_THROWEXCEPTION( heap.getIntValue(annot1, beginPosFeat) == 42 );
heap.setIntValue(annot1, endPosFeat, 37);
ASSERT_OR_THROWEXCEPTION( heap.getIntValue(annot1, endPosFeat) == 37 );
lowlevel::TyFS lemma1 = heap.createFS(lemmaType);
icu::UnicodeString uskey("lemmaKey");
UnicodeStringRef ulsKey(uskey.getBuffer(), uskey.length());
// lowlevel::TyFS stringFS = heap.createStringFeatureStructure(ulsKey);
int ulsOff = heap.addString(ulsKey);
heap.setStringValue(lemma1, keyFeature, ulsOff);
UnicodeStringRef ulsKey1 = heap.getFSAsString( heap.getFSValue(lemma1, keyFeature) );
ASSERT_OR_THROWEXCEPTION( ulsKey1 == ulsKey );
lowlevel::TyFS lemmaList = heap.createFS( heap.getTypeSystem().getTypeByName(CAS::TYPE_NAME_FS_LIST) );
lowlevel::TyFS tokenAnnot1 = heap.createFS(tokenAnnotationType);
ASSERT_OR_THROWEXCEPTION( heap.getType(tokenAnnot1) == tokenAnnotationType );
heap.setIntValue(tokenAnnot1, beginPosFeat, 43);
ASSERT_OR_THROWEXCEPTION( heap.getIntValue(tokenAnnot1, beginPosFeat) == 43 );
heap.setIntValue(tokenAnnot1, endPosFeat, -37);
ASSERT_OR_THROWEXCEPTION( heap.getIntValue(tokenAnnot1, endPosFeat) == -37 );
heap.setFSValue(tokenAnnot1, lemmaEntryFeat, lemmaList);
ASSERT_OR_THROWEXCEPTION( heap.getFSValue(tokenAnnot1, lemmaEntryFeat) == lemmaList );
lowlevel::TyFS tokenAnnot2 = heap.createFS(tokenAnnotationType);
ASSERT_OR_THROWEXCEPTION( heap.getType(tokenAnnot2) == tokenAnnotationType );
heap.setIntValue(tokenAnnot2, beginPosFeat, 0);
ASSERT_OR_THROWEXCEPTION( heap.getIntValue(tokenAnnot2, beginPosFeat) == 0 );
heap.setIntValue(tokenAnnot2, endPosFeat, 5);
ASSERT_OR_THROWEXCEPTION( heap.getIntValue(tokenAnnot2, endPosFeat) == 5 );
heap.setFSValue(tokenAnnot2, lemmaEntryFeat, lemmaList);
ASSERT_OR_THROWEXCEPTION( heap.getFSValue(tokenAnnot2, lemmaEntryFeat) == lemmaList );
LOG("testLowlevelFSHeap finished");
}
/************************************************************************************/
struct StrAnnotation {
lowlevel::TyFSType type;
int begin;
int end;
};
struct StrToken {
StrAnnotation annot;
size_t lemma;
};
struct StrSentence {
StrAnnotation annot;
};
struct StrLemma {
lowlevel::TyFSType type;
int keyIndex;
// icu::UnicodeString* key;
int pos;
};
void checkForwardOrder(lowlevel::FSHeap const & heap, auto_ptr<uima::lowlevel::IndexIterator> & it, uima::lowlevel::IndexComparator const * cpComp, vector<lowlevel::TyFS> const & fsVec) {
size_t i=0;
vector<lowlevel::TyFS> retrievedFSs;
for (it->moveToFirst(); it->isValid(); it->moveToNext()) {
LOG(" Found FS");
retrievedFSs.push_back(it->get());
}
// check that FSs were retrieved in correct order
LOG("retrieved FSs: " << retrievedFSs.size() << ", expected FSs: " << fsVec.size());
ASSERT_OR_THROWEXCEPTION(retrievedFSs.size() == fsVec.size());
for (i=0; i<retrievedFSs.size(); ++i) {
if (retrievedFSs[i] != fsVec[i]) {
// if the FSs are not token identical, they must be equal w.r.t. the comparator of the index
// ASSERT_OR_THROWEXCEPTION( ix.getComparator()->compare( retrievedFSs[i], fsVec[i] ) == 0 );
ASSERT_OR_THROWEXCEPTION( cpComp->compare(heap, retrievedFSs[i], fsVec[i] ) == 0 );
}
}
}
void checkReverseOrder(lowlevel::FSHeap const & heap,auto_ptr<uima::lowlevel::IndexIterator> & it, uima::lowlevel::IndexComparator const * cpComp, vector<lowlevel::TyFS> const & fsVec) {
size_t i=0;
vector<lowlevel::TyFS> retrievedFSs;
for (it->moveToLast(); it->isValid(); it->moveToPrevious()) {
LOG(" found FS");
retrievedFSs.push_back(it->get());
}
LOG("retrieved FSs: " << retrievedFSs.size() << ", expected FSs: " << fsVec.size());
ASSERT_OR_THROWEXCEPTION(retrievedFSs.size() == fsVec.size());
for (i=0; i<retrievedFSs.size(); ++i) {
size_t revi = fsVec.size() - i - 1;
if (retrievedFSs[i] != fsVec[revi] ) {
// if the FSs are not token identical, they must be equal w.r.t. the comparator of the index
ASSERT_OR_THROWEXCEPTION( cpComp->compare(heap, retrievedFSs[i], fsVec[revi] ) == 0 );
}
}
}
void checkPreviousNextMovements(auto_ptr<uima::lowlevel::IndexIterator> & it, uima::lowlevel::IndexComparator const * cpComp, vector<lowlevel::TyFS> const & fsVec) {
size_t i=0;
vector<lowlevel::TyFS> retrievedFSs;
for (it->moveToLast(); it->isValid(); it->moveToPrevious()) {
LOG(" found FS");
retrievedFSs.push_back(it->get());
}
LOG("retrieved FSs: " << retrievedFSs.size() << ", expected FSs: " << fsVec.size());
ASSERT_OR_THROWEXCEPTION(retrievedFSs.size() == fsVec.size());
size_t n = retrievedFSs.size();
it->moveToFirst();
for (i=0; i<n-1; ++i) {
ASSERT_OR_THROWEXCEPTION(it->isValid());
uima::lowlevel::TyFS current = it->get();
LOG("move forward");
it->moveToNext();
ASSERT_OR_THROWEXCEPTION(it->isValid());
//uima::lowlevel::TyFS next = it->get();
LOG("move back again");
it->moveToPrevious();
ASSERT_OR_THROWEXCEPTION(it->isValid());
LOG("checking");
ASSERT_OR_THROWEXCEPTION( it->get() == current );
}
}
void checkOrderedIndex(uima::lowlevel::IndexABase const & ixBase, vector<lowlevel::TyFS> const & fsVec) {
lowlevel::FSHeap const & heap = ixBase.getFSHeap();
bool bIsMaximalType = ixBase.getFSHeap().getTypeSystem().isMaximalType( ixBase.getType() );
uima::lowlevel::IndexComparator const * cpComp = NULL;
if (bIsMaximalType) {
uima::lowlevel::internal::OrderedSingleIndex const * cpIXSingle = (uima::lowlevel::internal::OrderedSingleIndex const *) & ixBase;
cpComp = cpIXSingle->getComparator();
} else {
uima::lowlevel::internal::OrderedCompositeIndex const * cpIXComposite = (uima::lowlevel::internal::OrderedCompositeIndex const *) & ixBase;
cpComp = cpIXComposite->getComparator();
}
ASSERT_OR_THROWEXCEPTION( EXISTS(cpComp) );
auto_ptr<lowlevel::IndexIterator> it(ixBase.createIterator());
LOG("checking forward order");
checkForwardOrder(heap, it, cpComp, fsVec);
LOG("checking reverse order");
checkReverseOrder(heap, it, cpComp, fsVec);
LOG("checking forward order again");
checkForwardOrder(heap, it, cpComp, fsVec);
LOG("checking forward order again");
checkForwardOrder(heap, it, cpComp, fsVec);
LOG("checking reverse order again");
checkReverseOrder(heap, it, cpComp, fsVec);
LOG("checking moveToPrevious/moveToNext pairs");
checkPreviousNextMovements(it, cpComp, fsVec);
}
void checkSetIndex(lowlevel::IndexABase const & ix, size_t num) {
LOG("Checking set index");
LOG("Index size: " << ix.getSize() );
vector<lowlevel::TyFS> retrievedFSs;
auto_ptr<lowlevel::IndexIterator> it(ix.createIterator());
for (it->moveToFirst(); it->isValid(); it->moveToNext()) {
retrievedFSs.push_back(it->get());
}
size_t i;
for (i=0; i<retrievedFSs.size(); ++i) {
LOG("FS retrieved: " << (int) retrievedFSs[i]);
}
LOG("Retrieved FSs: " << retrievedFSs.size() << ", expected FS: " << num);
ASSERT_OR_THROWEXCEPTION( retrievedFSs.size() == num );
}
void testLowLevelIndex() {
LOG("testLowlevelIndex started");
TTDefinition ttdef;
ttdef.init();
ttdef.commitTypeSystem();
lowlevel::TypeSystem & ts = ttdef.getTypeSystem();
int i = 0;
assert( ts.debugIsConsistent() );
uima::lowlevel::IndexDefinition & ixDef = ttdef.getIndexDefinition();
// get some types and features
lowlevel::TyFSType annotType = ts.getTypeByName( CAS::TYPE_NAME_ANNOTATION );
ASSERT_OR_THROWEXCEPTION( ts.isValidType(annotType) );
lowlevel::TyFSType lemmaType = ts.getTypeByName( TT::TYPE_NAME_LEMMA );
ASSERT_OR_THROWEXCEPTION( ts.isValidType(lemmaType) );
lowlevel::TyFSType tokenAnnotType = ts.getTypeByName( TT::TYPE_NAME_TOKEN_ANNOTATION );
ASSERT_OR_THROWEXCEPTION( ts.isValidType(tokenAnnotType) );
lowlevel::TyFSType sentAnnotType = ts.getTypeByName( TT::TYPE_NAME_SENTENCE_ANNOTATION );
ASSERT_OR_THROWEXCEPTION( ts.isValidType(sentAnnotType) );
lowlevel::TyFSFeature beginPosFeat = ts.getFeatureByBaseName( annotType, CAS::FEATURE_BASE_NAME_BEGIN );
ASSERT_OR_THROWEXCEPTION( ts.isValidFeature(beginPosFeat) );
lowlevel::TyFSFeature endPosFeat = ts.getFeatureByBaseName( annotType, CAS::FEATURE_BASE_NAME_END );
ASSERT_OR_THROWEXCEPTION( ts.isValidFeature(endPosFeat) );
lowlevel::TyFSFeature keyFeat = ts.getFeatureByBaseName( lemmaType, TT::FEATURE_BASE_NAME_KEY );
ASSERT_OR_THROWEXCEPTION( ts.isValidFeature(keyFeat) );
lowlevel::TyFSFeature posFeat = ts.getFeatureByBaseName( lemmaType, TT::FEATURE_BASE_NAME_PART_OF_SPEECH );
ASSERT_OR_THROWEXCEPTION( ts.isValidFeature(posFeat) );
lowlevel::TyFSFeature lemmaEntryFeat = ts.getFeatureByBaseName( tokenAnnotType, TT::FEATURE_BASE_NAME_LEMMA_ENTRIES );
ASSERT_OR_THROWEXCEPTION( ts.isValidFeature(lemmaEntryFeat) );
// prepare comparators
vector<lowlevel::TyFSFeature> tokenKeyFeatures;
vector<uima::lowlevel::IndexComparator::EnKeyFeatureComp> tokenComparators;
tokenKeyFeatures.push_back(beginPosFeat);
tokenKeyFeatures.push_back(endPosFeat);
tokenComparators.resize(2, uima::lowlevel::IndexComparator::STANDARD_COMPARE );
// lowlevel::IndexComparator annotComp(heap, annotType, keyFeatures);
vector<lowlevel::TyFSFeature> lemmaKeyFeatures;
vector<uima::lowlevel::IndexComparator::EnKeyFeatureComp> lemmaComparators;
lemmaKeyFeatures.push_back( keyFeat );
lemmaKeyFeatures.push_back( posFeat );
lemmaComparators.resize(2, uima::lowlevel::IndexComparator::STANDARD_COMPARE );
// lowlevel::IndexComparator lemmaComp(heap, lemmaType, keyFeatures);
// create indexes
const icu::UnicodeString ORDEREDIX = "42";
const icu::UnicodeString SETIX = "37";
const icu::UnicodeString FIFOIX = "4711";
ixDef.defineIndex(lowlevel::IndexDefinition::enOrdered, annotType, tokenKeyFeatures, tokenComparators, ORDEREDIX);
ASSERT_OR_THROWEXCEPTION( ixDef.getIndexKind(ORDEREDIX) == lowlevel::IndexDefinition::enOrdered );
// ASSERT_OR_THROWEXCEPTION( ixStore.getComparator(ORDEREDIX) == & annotComp );
ixDef.defineIndex(lowlevel::IndexDefinition::enSet, lemmaType, lemmaKeyFeatures, lemmaComparators, SETIX);
ASSERT_OR_THROWEXCEPTION( ixDef.getIndexKind(SETIX) == lowlevel::IndexDefinition::enSet );
// ASSERT_OR_THROWEXCEPTION( ixStore.getComparator(SETIX) == & lemmaComp );
// ixStore.createFIFOIndex(annotType, FIFOIX);
ttdef.commitIndexDefinition();
// create some feature structures
//#define LEMMA_NUM 5
const size_t DUPLICATE_LEMMAS = 1;
vector<icu::UnicodeString> lemmaStrings;
lemmaStrings.push_back("s1");
lemmaStrings.push_back("s2");
lemmaStrings.push_back("s3");
struct StrLemma lemmasTobeCreated[] = {
{
lemmaType, 0, 1
}
, // 0
{ lemmaType, 0, 1}, // 1
{ lemmaType, 1, 1}, // 2
{ lemmaType, 0, 2}, // 3
{ lemmaType, 2, 3}, // 4
/*
{ lemmaType, & lemmaStrings[0], 1}, // 0
{ lemmaType, & lemmaStrings[0], 1}, // 1
{ lemmaType, & lemmaStrings[1], 1}, // 2
{ lemmaType, & lemmaStrings[0], 2}, // 3
{ lemmaType, & lemmaStrings[2], 3}, // 4
*/
};
size_t LEMMA_NUM = NUMBEROF(lemmasTobeCreated);
struct StrToken tokensToBeCreated[] = {
{
tokenAnnotType, 0, 5, 0
}
, // 0
{ tokenAnnotType, 5, 8, 1}, // 1
{ tokenAnnotType, 5, 8, 1}, // 2
};
//#define TOKEN_NUM 3
size_t TOKEN_NUM = NUMBEROF(tokensToBeCreated);
assert( TOKEN_NUM == 3);
struct StrSentence sentencesToBeCreated[] = {
{
sentAnnotType, 0, 8
}
, //0
};
size_t SENTENCE_NUM = NUMBEROF(sentencesToBeCreated);
// define the orders of all annotations
int annotationOrder[] = {
// int annotationOrder[TOKEN_NUM + SENTENCE_NUM] = {
// sentence 0, token 0, token 1, token 2
0, SENTENCE_NUM + 0, SENTENCE_NUM + 1, SENTENCE_NUM + 2
};
assert( NUMBEROF(annotationOrder) == SENTENCE_NUM + TOKEN_NUM );
LOG("Token number: " << TOKEN_NUM);
LOG("Lemma number: " << LEMMA_NUM);
// uima::internal::TCASImpl tcasimpl(ttdef, 5000, 5000, 5000);
uima::internal::CASImpl * pCas = getCASImpl(ttdef);
uima::internal::CASImpl & tcasimpl = *pCas;
uima::lowlevel::FSHeap & heap = tcasimpl.getHeap();
uima::lowlevel::IndexRepository & ixStore = tcasimpl.getIndexRepository();
vector<lowlevel::TyFS> tokens;
vector<lowlevel::TyFS> sentences;
vector<lowlevel::TyFS> lemmas;
for (i=0; i<(int)LEMMA_NUM; ++i) {
lowlevel::TyFS fs = heap.createFS( lemmasTobeCreated[i].type );
icu::UnicodeString const & lemmaKey = lemmaStrings[ lemmasTobeCreated[i].keyIndex ];
UnicodeStringRef key(lemmaKey );
int keyOff = heap.addString(key);
heap.setStringValue(fs, keyFeat, keyOff);
heap.setIntValue(fs, posFeat, lemmasTobeCreated[i].pos);
lowlevel::TyFS lemmaList = heap.createFS( heap.getTypeSystem().getTypeByName(CAS::TYPE_NAME_NON_EMPTY_FS_LIST) );
lowlevel::TyFS eList = heap.createFS( heap.getTypeSystem().getTypeByName(CAS::TYPE_NAME_EMPTY_FS_LIST) );
heap.setFSValue( lemmaList, heap.getTypeSystem().getFeatureByBaseName(CAS::TYPE_NAME_NON_EMPTY_FS_LIST, CAS::FEATURE_BASE_NAME_TAIL), eList );
heap.setFSValue( lemmaList, heap.getTypeSystem().getFeatureByBaseName(CAS::TYPE_NAME_NON_EMPTY_FS_LIST, CAS::FEATURE_BASE_NAME_HEAD), fs );
lemmas.push_back(lemmaList);
}
ASSERT_OR_THROWEXCEPTION( lemmas.size() == LEMMA_NUM );
for (i=0; i<(int)TOKEN_NUM; ++i) {
ASSERT_OR_THROWEXCEPTION( tokensToBeCreated[i].annot.type == tokenAnnotType );
lowlevel::TyFS fs = heap.createFS( tokensToBeCreated[i].annot.type );
heap.setIntValue(fs, beginPosFeat, tokensToBeCreated[i].annot.begin );
heap.setIntValue(fs, endPosFeat, tokensToBeCreated[i].annot.end );
heap.setFSValue(fs, lemmaEntryFeat, lemmas[ tokensToBeCreated[i].lemma ] );
tokens.push_back(fs);
}
ASSERT_OR_THROWEXCEPTION( tokens.size() == TOKEN_NUM );
for (i=0; i<(int)SENTENCE_NUM; ++i) {
ASSERT_OR_THROWEXCEPTION( sentencesToBeCreated[i].annot.type == sentAnnotType );
lowlevel::TyFS fs = heap.createFS( sentencesToBeCreated[i].annot.type );
heap.setIntValue(fs, beginPosFeat, sentencesToBeCreated[i].annot.begin );
heap.setIntValue(fs, endPosFeat, sentencesToBeCreated[i].annot.end );
sentences.push_back(fs);
}
vector<lowlevel::TyFS> annotations;
for (i=0; i<(int)(TOKEN_NUM + SENTENCE_NUM); ++i) {
int fsix = annotationOrder[i];
/*
if (fsix < TOKEN_NUM) {
annotations.push_back(tokens[fsix]);
}
else if (fsix < (TOKEN_NUM + SENTENCE_NUM) ) {
annotations.push_back( sentences[fsix - TOKEN_NUM] );
}
*/
if (fsix < (int)SENTENCE_NUM) {
annotations.push_back( sentences[fsix] );
} else if (fsix < (int)(TOKEN_NUM + SENTENCE_NUM) ) {
annotations.push_back(tokens[fsix - SENTENCE_NUM]);
} else {
ASSERT_OR_THROWEXCEPTION(false);
}
}
#ifndef NDEBUG
heap.print(cout);
#endif
// off we go...
//Tests:
// 1. add tokens/lemmas to all indexes
// ensure that tokens are returned in the right order
// ensure that duplicates of lemmas are not inserted
//
// 1. add to all indexes
LOG("Adding FSs in right order...");
for (i=0; i<(int)tokens.size(); ++i) {
LOG("Adding token " << (size_t) tokens[i]);
LOG(" type of token: " << ts.getTypeName( heap.getType(tokens[i]) ) );
ixStore.add(tokens[i]);
}
LOG(" tokens added");
LOG(" Adding lemmas....");
for (i=0; i<(int)lemmas.size(); ++i) {
lowlevel::TyFS lemma = heap.getFSValue(lemmas[i], heap.getTypeSystem().getFeatureByBaseName(CAS::TYPE_NAME_NON_EMPTY_FS_LIST, CAS::FEATURE_BASE_NAME_HEAD) );
ASSERT_OR_THROWEXCEPTION( heap.getType( lemma ) == heap.getTypeSystem().getTypeByName(TT::TYPE_NAME_LEMMA) );
ixStore.add( lemma );
}
LOG(" " << lemmas.size() << " lemmas added");
LOG("Lemmas in index:");
{
i=0;
auto_ptr<uima::lowlevel::IndexIterator> it( ixStore.getLowlevelIndex(SETIX, lemmaType).createIterator() );
for (it->moveToFirst(); it->isValid(); it->moveToNext() ) {
LOG(" lemma number: " << i);
uima::lowlevel::TyFS lemma = it->get();
LOG(" key: " << heap.getStringValue(lemma, keyFeat));
LOG(" pos: " << heap.getIntValue(lemma, posFeat) );
++i;
}
}
LOG("FSs added");
LOG("Check indexes...");
// check ordered index
checkOrderedIndex(ixStore.getLowlevelIndex(ORDEREDIX, tokenAnnotType), tokens);
// check built-in annotation index
checkOrderedIndex(ixStore.getLowlevelIndex( tcasimpl.getAnnotationIndexID(), tokenAnnotType), tokens);
// check set index
checkSetIndex(ixStore.getLowlevelIndex(SETIX, lemmaType), (LEMMA_NUM - DUPLICATE_LEMMAS) );
LOG(" Indexes checked");
ixStore.reset();
// add in reverse order
LOG("Adding FSs in reverse order...");
for (i=tokens.size() - 1; i>=0; i--) {
LOG("i: " << i );
assert( heap.debugIsValidHeapCell(tokens[i]) );
ixStore.add(tokens[i]);
}
for (i=lemmas.size() - 1; i>=0; --i) {
lowlevel::TyFS lemma = heap.getFSValue(lemmas[i], heap.getTypeSystem().getFeatureByBaseName(CAS::TYPE_NAME_NON_EMPTY_FS_LIST, CAS::FEATURE_BASE_NAME_HEAD) );
ASSERT_OR_THROWEXCEPTION( heap.getType( lemma ) == heap.getTypeSystem().getTypeByName(TT::TYPE_NAME_LEMMA) );
ixStore.add( lemma );
}
LOG("Checking indexes");
// check ordered index
checkOrderedIndex(ixStore.getLowlevelIndex(ORDEREDIX, tokenAnnotType), tokens);
// check built-in annotation index
checkOrderedIndex(ixStore.getLowlevelIndex(tcasimpl.getAnnotationIndexID(),tokenAnnotType), tokens);
// check set index
checkSetIndex(ixStore.getLowlevelIndex(SETIX, lemmaType), (LEMMA_NUM - DUPLICATE_LEMMAS) );
LOG("Indexes checked");
// 2. add to a single index with id
ixStore.reset();
LOG("Add to single index with ID");
for (i=0; i<(int)tokens.size(); ++i) {
ixStore.add(tokens[i], ORDEREDIX);
}
LOG("Checking index");
checkOrderedIndex(ixStore.getLowlevelIndex(ORDEREDIX, tokenAnnotType), tokens);
ASSERT_OR_THROWEXCEPTION( ixStore.getLowlevelIndex( tcasimpl.getAnnotationIndexID(), tokenAnnotType).getSize() == 0 );
LOG("Index checked");
// 3. test composite indexes
ixStore.reset();
LOG("Add to composite index");
for (i=0; i<(int)tokens.size(); ++i) {
ixStore.add(tokens[i]);
}
for (i=0; i<(int)sentences.size(); ++i) {
ixStore.add(sentences[i]);
}
lowlevel::IndexABase const & ix = ixStore.getLowlevelIndex( tcasimpl.getAnnotationIndexID(), annotType);
LOG("Checking index");
checkOrderedIndex(ix, annotations);
LOG("Index checked");
// 4. test delete index
icu::UnicodeString anIxID = tcasimpl.getAnnotationIndexID();
ixStore.remove(tokens[0]);
auto_ptr<lowlevel::IndexIterator> it( ixStore.getLowlevelIndex( anIxID, tokenAnnotType).createIterator() );
it->moveToFirst();
ASSERT_OR_THROWEXCEPTION( it->get() != tokens[0]);
ASSERT_OR_THROWEXCEPTION( it->get() == tokens[1]);
i=1;
while (it->isValid()) {
ASSERT_OR_THROWEXCEPTION( it->get() == tokens[i] );
it->moveToNext();
++i;
}
delete pCas;
LOG("testLowlevelIndex finished");
}
/************************************************************************************/
void testEmptyStrings() {
LOG("testEmptyStrings() started");
TTDefinition ttdef;
ttdef.init();
lowlevel::TypeSystem& ts = ttdef.getTypeSystem();
lowlevel::TyFSType t = ts.createType(ts.getTopType(), "t", ustrCreatorID);
lowlevel::TyFSType floatType = ts.getTypeByName(CAS::TYPE_NAME_STRING);
lowlevel::TyFSFeature f = ts.createFeature(t, floatType, false, "f", ustrCreatorID);
ttdef.commit();
// uima::internal::TCASImpl tcas(ttdef, 300, 300, 300);
uima::internal::CASImpl * pCas = getCASImpl(ttdef);
uima::internal::CASImpl & tcas = *pCas;
uima::lowlevel::FSHeap& heap = tcas.getHeap();
lowlevel::TyFS fs = heap.createFS(t);
UnicodeStringRef uref = heap.getStringValue(fs, f);
delete pCas;
ASSERT_OR_THROWEXCEPTION( uref.getBuffer() == NULL );
LOG("testEmptyStrings() finished");
}
/************************************************************************************/
void testFloatFeatures() {
LOG("testFloatFeatures started");
TTDefinition ttdef;
ttdef.init();
lowlevel::TypeSystem& ts = ttdef.getTypeSystem();
lowlevel::TyFSType t = ts.createType(ts.getTopType(), "t", ustrCreatorID);
lowlevel::TyFSType floatType = ts.getTypeByName(CAS::TYPE_NAME_FLOAT);
lowlevel::TyFSFeature f = ts.createFeature(t, floatType, false, "f", ustrCreatorID);
ttdef.commit();
// uima::internal::TCASImpl tcas(ttdef, 30, 30, 30);
// uima::internal::CASImpl tcas(ttdef, 30, 30, 30);
// uima::internal::CASImpl & tcas = *uima::internal::CASImpl::createCASImpl(ttdef, false);
// ErrorInfo errorInfo;
// uima::internal::CASImpl & tcas = *(uima::internal::CASImpl*) Framework::createCAS(ttdef, errorInfo);
uima::internal::CASImpl * pCas = getCASImpl(ttdef);
uima::internal::CASImpl & tcas = *pCas;
lowlevel::FSHeap& heap = tcas.getHeap();
lowlevel::TyFS fs = heap.createFS(t);
float x = 0.4237f;
heap.setFloatValue(fs, f, x);
float y = heap.getFloatValue(fs, f);
ASSERT_OR_THROWEXCEPTION(x == y);
delete pCas;
LOG("testFloatFeatures finished");
}
/************************************************************************************/
void testNestedStructures() {
LOG("testNestedStructures started");
TTDefinition ttdef;
ttdef.init();
lowlevel::TypeSystem& ts = ttdef.getTypeSystem();
lowlevel::TyFSType top = ts.getTopType();
lowlevel::TyFSType t1 = ts.createType(top, "t1", ustrCreatorID);
lowlevel::TyFSType t2 = ts.createType(top, "t2", ustrCreatorID);
lowlevel::TyFSType t3 = ts.createType(top, "t3", ustrCreatorID);
lowlevel::TyFSType t4 = ts.createType(top, "t4", ustrCreatorID);
lowlevel::TyFSType t5 = ts.createType(top, "t5", ustrCreatorID);
lowlevel::TyFSFeature f11 = ts.createFeature(t1, t2, false, "f11", ustrCreatorID);
lowlevel::TyFSFeature f12 = ts.createFeature(t1, t3, false, "f12", ustrCreatorID);
lowlevel::TyFSFeature f2 = ts.createFeature(t2, t4, false, "f2", ustrCreatorID);
lowlevel::TyFSFeature f3 = ts.createFeature(t3, t5, false, "f3", ustrCreatorID);
ttdef.commit();
// uima::internal::TCASImpl tcas(ttdef, 400, 400, 400);
uima::internal::CASImpl * pCas = getCASImpl(ttdef);
uima::internal::CASImpl & tcas = *pCas;
//#ifndef NDEBUG
// ts.print(cout);
//#endif
lowlevel::FSHeap & heap = tcas.getHeap();
lowlevel::TyFS fs_t1 = heap.createFS( t1 );
lowlevel::TyFS fs_t2 = heap.createFS( t2 );
lowlevel::TyFS fs_t3 = heap.createFS( t3 );
lowlevel::TyFS fs_t4 = heap.createFS( t4 );
lowlevel::TyFS fs_t5 = heap.createFS( t5 );
ASSERT_OR_THROWEXCEPTION( heap.isUntouchedFSValue( fs_t1, f11 ) );
heap.setFSValue(fs_t1, f11, fs_t2);
ASSERT_OR_THROWEXCEPTION( ! heap.isUntouchedFSValue( fs_t1, f11 ) );
heap.setFSValue(fs_t1, f12, fs_t3);
heap.setFSValue(fs_t2, f2, fs_t4);
heap.setFSValue(fs_t3, f3, fs_t5);
//#ifndef NDEBUG
// heap.print(cout);
//#endif
ASSERT_OR_THROWEXCEPTION( heap.getType( heap.getFSValue(fs_t1, f11) ) == t2 );
ASSERT_OR_THROWEXCEPTION( heap.getType( heap.getFSValue(fs_t1, f12) ) == t3 );
ASSERT_OR_THROWEXCEPTION( heap.getType( heap.getFSValue(fs_t2, f2) ) == t4 );
ASSERT_OR_THROWEXCEPTION( heap.getType( heap.getFSValue(fs_t3, f3) ) == t5 );
ASSERT_OR_THROWEXCEPTION( heap.getFSValue(fs_t1, f11) == fs_t2 );
ASSERT_OR_THROWEXCEPTION( heap.getFSValue(fs_t1, f12) == fs_t3 );
ASSERT_OR_THROWEXCEPTION( heap.getFSValue(fs_t2, f2) == fs_t4 );
ASSERT_OR_THROWEXCEPTION( heap.getFSValue(fs_t3, f3) == fs_t5 );
delete pCas;
LOG("testNestedStructures finished");
}
/************************************************************************************/
void testOOIndex() {
LOG("testOOIndex() started");
TestCAS testcas;
uima::internal::CASImpl & tcas = testcas.getCAS();
uima::FSIndexRepository & indexRep = tcas.getIndexRepository();
TypeSystem const & typeSys = tcas.getTypeSystem();
Type annotType = typeSys.getType(TT::TYPE_NAME_TOKEN_ANNOTATION);
Feature beginPosFeature = annotType.getFeatureByBaseName( CAS::FEATURE_BASE_NAME_BEGIN);
Feature endPosFeature = annotType.getFeatureByBaseName(CAS::FEATURE_BASE_NAME_END);
LOG("Creating FSs");
FeatureStructure fs1 = tcas.createFS(annotType);
ASSERT_OR_THROWEXCEPTION( fs1.isUntouchedFSValue(beginPosFeature) );
fs1.setIntValue( beginPosFeature, 1 );
ASSERT_OR_THROWEXCEPTION( ! fs1.isUntouchedFSValue(beginPosFeature) );
fs1.setIntValue( endPosFeature, 2 );
FeatureStructure fs2 = tcas.createFS(annotType);
fs2.setIntValue( beginPosFeature, 2 );
fs2.setIntValue( endPosFeature, 3 );
FeatureStructure fs3 = tcas.createFS(annotType);
fs3.setIntValue( beginPosFeature, 3 );
fs3.setIntValue( endPosFeature, 4 );
FeatureStructure fs4 = tcas.createFS(annotType);
fs4.setIntValue( beginPosFeature, 4 );
fs4.setIntValue( endPosFeature, 5 );
FeatureStructure fs41 = tcas.createFS(annotType);
fs41.setIntValue( beginPosFeature, 4 );
fs41.setIntValue( endPosFeature, 5 );
LOG("...FSs created");
FeatureStructure fsArray[] = {
fs1, fs2, fs3, fs4, fs41
};
size_t fsArraySize = NUMBEROF(fsArray);
LOG("Adding FSs to index");
indexRep.addFS(fs1);
indexRep.addFS(fs3);
indexRep.addFS(fs41);
indexRep.addFS(fs4);
indexRep.addFS(fs2);
LOG("...FSs Added");
FSIndex ordIx = tcas.getAnnotationIndex(annotType);
ASSERT_OR_THROWEXCEPTION( ordIx.getSize() == fsArraySize );
LOG("Checking ordered index...");
FSIterator ordIt = ordIx.iterator();
size_t i=0;
for (ordIt.moveToFirst(); ordIt.isValid(); ordIt.moveToNext()) {
LOG("Checking " << i << "th FS");
FeatureStructure fs1 = ordIt.get();
FeatureStructure fs2 = fsArray[i];
// ASSERT_OR_THROWEXCEPTION( ordIt.get() == fsArray[i] );
ASSERT_OR_THROWEXCEPTION( fs1.getIntValue( beginPosFeature ) == fs2.getIntValue( beginPosFeature ) );
ASSERT_OR_THROWEXCEPTION( fs1.getIntValue( endPosFeature ) == fs2.getIntValue( endPosFeature ) );
++i;
}
LOG("...Ordered index checked");
LOG("Checking deletion");
indexRep.removeFS(fsArray[0]);
FSIterator ordIt2 = ordIx.iterator();
ordIt2.moveToFirst();
ASSERT_OR_THROWEXCEPTION( ! (ordIt2.get() == fsArray[0]) );
ASSERT_OR_THROWEXCEPTION( ordIt2.get() == fsArray[1] );
i=1;
while (ordIt2.isValid()) {
ASSERT_OR_THROWEXCEPTION( ordIt2.get() != fsArray[0] );
ordIt2.moveToNext();
++i;
}
LOG("Deletion checked");
LOG("testOOIndex() finished");
}
/************************************************************************************/
void testOOExceptions() {
LOG("testOOExceptions() started");
bool bExceptionThrown = false;
Type t;
try {
UnicodeStringRef name = t.getName();
} catch (InvalidFSTypeObjectException & exc) {
LOG("Exception thrown correctly: " << exc.asString());
bExceptionThrown = true;
}
ASSERT_OR_THROWEXCEPTION(bExceptionThrown);
TTDefinition ttdef;
ttdef.init();
Type lemmaType = ttdef.getTypeSystem().getType(TT::TYPE_NAME_LEMMA);
Type annotType = ttdef.getTypeSystem().getType(CAS::TYPE_NAME_ANNOTATION);
Feature beginPosFeat = annotType.getFeatureByBaseName(CAS::FEATURE_BASE_NAME_BEGIN);
Feature endPosFeat = annotType.getFeatureByBaseName(CAS::FEATURE_BASE_NAME_END);
Type invalidType;
Feature invalidFeat;
ttdef.commit();
// tcas.createPredefinedTTIndexes();
// uima::internal::TCASImpl tcas(ttdef, 50000, 50000, 50000);
uima::internal::CASImpl * pCas = getCASImpl(ttdef);
uima::internal::CASImpl & tcas = *pCas;
// check invalid fs
FeatureStructure invalidFS;
bExceptionThrown = false;
try {
(void)invalidFS.getIntValue(beginPosFeat);
} catch (InvalidFSObjectException & exc) {
LOG("Exception thrown correctly: " << exc.asString());
bExceptionThrown = true;
}
ASSERT_OR_THROWEXCEPTION(bExceptionThrown);
// check fs creation with invalid type
bExceptionThrown = false;
try {
FeatureStructure fs1 = tcas.createFS(invalidType);
} catch (InvalidFSTypeObjectException & exc) {
LOG("Exception thrown correctly: " << exc.asString());
bExceptionThrown = true;
}
ASSERT_OR_THROWEXCEPTION(bExceptionThrown);
FeatureStructure annotFS = tcas.createFS(annotType);
// check getting invalid feature
// check getting inappropriate feature
bExceptionThrown = false;
try {
FeatureStructure fs = annotFS.getFSValue(invalidFeat);
} catch (InvalidFSFeatureObjectException & exc) {
LOG("Exception thrown correctly: " << exc.asString());
bExceptionThrown = true;
}
ASSERT_OR_THROWEXCEPTION(bExceptionThrown);
// check getting inappropriate feature
bExceptionThrown = false;
try {
FeatureStructure lemmaFS = tcas.createFS(lemmaType);
FeatureStructure fs = lemmaFS.getFSValue(beginPosFeat);
} catch (FeatureNotAppropriateException & exc) {
LOG("Exception thrown correctly: " << exc.asString());
bExceptionThrown = true;
}
ASSERT_OR_THROWEXCEPTION(bExceptionThrown);
// getting an approproate feature with non builtin range type
bExceptionThrown = false;
try {
FeatureStructure fs = annotFS.getFSValue(beginPosFeat);
} catch (FeatureNotAppropriateException & exc) {
LOG("Exception thrown correctly: " << exc.asString());
bExceptionThrown = true;
}
ASSERT_OR_THROWEXCEPTION(bExceptionThrown);
// setting incompatible value
bExceptionThrown = false;
try {
annotFS.setFSValue(beginPosFeat, annotFS);
} catch (IncompatibleValueTypeException & exc) {
LOG("Exception thrown correctly: " << exc.asString());
bExceptionThrown = true;
}
ASSERT_OR_THROWEXCEPTION(bExceptionThrown);
/*
// getting string/array value from fs
bExceptionThrown = false;
try {
internal::StringFS strFS(annotFS);
UnicodeStringRef p = strFS.getStringValue();
}
catch (FSIsNotStringException & exc) {
LOG("Exception thrown correctly: " << exc.asString());
bExceptionThrown = true;
}
ASSERT_OR_THROWEXCEPTION(bExceptionThrown);
*/
// invalid arrays
ArrayFS invalidArrayFS(invalidFS);
bExceptionThrown = false;
try {
size_t i = invalidArrayFS.size();
} catch (InvalidFSObjectException & exc) {
LOG("Exception thrown correctly: " << exc.asString());
bExceptionThrown = true;
}
ASSERT_OR_THROWEXCEPTION(bExceptionThrown);
// array size
bExceptionThrown = false;
try {
ArrayFS arrFS(annotFS);
(void)arrFS.size();
} catch (FSIsNotArrayException & exc) {
LOG("Exception thrown correctly: " << exc.asString());
bExceptionThrown = true;
}
ASSERT_OR_THROWEXCEPTION(bExceptionThrown);
bExceptionThrown = false;
LOG("Testing InvalidIndexIDException");
try {
tcas.getIndexRepository().getIndex("bla", annotType);
} catch (InvalidIndexIDException & exc) {
LOG("Exception thrown correctly: " << exc.asString());
bExceptionThrown = true;
}
ASSERT_OR_THROWEXCEPTION(bExceptionThrown);
bExceptionThrown = false;
LOG("Testing WrongFSTypeForIndexException");
icu::UnicodeString const & crIndexID = tcas.getAnnotationIndexID();
try {
tcas.getIndexRepository().getIndex(crIndexID, lemmaType);
} catch (WrongFSTypeForIndexException & exc) {
LOG("Exception thrown correctly: " << exc.asString());
bExceptionThrown = true;
}
ASSERT_OR_THROWEXCEPTION(bExceptionThrown);
bExceptionThrown = false;
LOG("Testing CouldNotCreateFSOfFinalTypeException");
try {
tcas.createFS( tcas.getTypeSystem().getType( uima::CAS::TYPE_NAME_INTEGER ) );
} catch ( CouldNotCreateFSOfFinalTypeException & exc) {
LOG("Exception thrown correctly: " << exc.asString());
bExceptionThrown = true;
}
delete pCas;
LOG("testOOExceptions() finished");
}
/************************************************************************************/
void testOOFilterBuilder() {
LOG("testOOFilterBuilder() started");
TTDefinition ttdef;
ttdef.init();
TypeSystem const & typeSystem = ttdef.getTypeSystem();
Type tokenType = typeSystem.getType(TT::TYPE_NAME_TOKEN_ANNOTATION);
Feature beginFeat = tokenType.getFeatureByBaseName( CAS::FEATURE_BASE_NAME_BEGIN);
Feature endFeat = tokenType.getFeatureByBaseName( CAS::FEATURE_BASE_NAME_END);
Type stringType = typeSystem.getType(CAS::TYPE_NAME_STRING);
uima::lowlevel::TypeSystem & lolTS = ttdef.getTypeSystem();
lowlevel::TyFSType lolTokenType = uima::internal::FSPromoter::demoteType( tokenType );
lowlevel::TyFSType lolMyTokenType = lolTS.createType(lolTokenType, "MyToken", ustrCreatorID);
lolTS.createFeature(lolMyTokenType, lolTokenType, false, "MyRecursiveFeature", ustrCreatorID);
lolTS.createFeature(lolMyTokenType, uima::internal::FSPromoter::demoteType(stringType), false, "MyStringFeature", ustrCreatorID);
Type myTokenType = typeSystem.getType("MyToken");
Feature myRecursiveFeature = myTokenType.getFeatureByBaseName("MyRecursiveFeature");
Feature myStringFeature = myTokenType.getFeatureByBaseName("MyStringFeature");
// lowlevel::TypeSystem const & typeSystem = tcas.getFSSystem().getLowlevelTypeSystem();
// lowlevel::TyFSType lolTokenType = typeSystem.getType(CAS::TYPE_NAME_TOKEN_ANNOTATION);
// lowlevel::TyFSType lolMyTokenType = typeSystem.getType("MyToken");
ttdef.commit();
// uima::internal::TCASImpl tcas(ttdef, 4000, 4000, 4000);
uima::internal::CASImpl * pCas = getCASImpl(ttdef);
uima::internal::CASImpl & tcas = *pCas;
uima::FSIndexRepository & indexRep = tcas.getIndexRepository();
StrToken tokens[] = {
{
lolTokenType, 0, 3, 0
}
, // 0
{ lolMyTokenType, 3, 5, 0}, // 1
{ lolTokenType, 5, 8, 0}, // 2
{ lolMyTokenType, 9, 11, 0}, // 3
{ lolMyTokenType, 15, 16, 0} // 4
};
size_t tokenNum = NUMBEROF(tokens);
size_t myTokenNum = 3;
FeatureStructure oldFS;
size_t i;
for (i=0; i<tokenNum; ++i) {
icu::UnicodeString typeName = lolTS.getTypeName( tokens[i].annot.type );
Type type = typeSystem.getType(typeName);
FeatureStructure fs = tcas.createFS(type);
fs.setIntValue(beginFeat, tokens[i].annot.begin);
fs.setIntValue(endFeat, tokens[i].annot.end);
if (type == myTokenType) {
ASSERT_OR_THROWEXCEPTION(oldFS.isValid() );
fs.setFSValue(myRecursiveFeature, oldFS);
char c[32];
sprintf(c,"%d",i); //cosItoa(i, c);
icu::UnicodeString us("string");
us.append(icu::UnicodeString(c));
// icu::UnicodeString icuus( (UChar*) us.data(), us.length() );
// UnicodeStringRef p = fsSystem.addString(icuus);
// UnicodeStringRef lstr( (UniChar const *) p.first, p.second);
// LOG("Adding string '" << lstr << "'");
// FeatureStructure stringFS = fsSystem.createStringFS(p.first, p.second);
fs.setStringValue(myStringFeature, us);
}
oldFS = fs;
indexRep.addFS(fs);
}
LOG("Annotations created");
FSIterator ixit;
ANIndex ix = tcas.getAnnotationIndex(tokenType);
vector<Feature> vFeaturePath;
FSFilterBuilder const & builder = tcas.getFSFilterBuilder();
//////////////////////////////////////////
LOG("Checking type filter");
//TODO: the filter passed to ix.filteredIterator is wrapped in another object,
// added to ixit, and never deleted.
// LEAK!!!
FSFilter * typeFilter = builder.createTypeFilter(tokenType, false);
ixit = ix.filteredIterator(typeFilter);
i=0;
for (ixit.moveToFirst(); ixit.isValid(); ixit.moveToNext()) {
ASSERT_OR_THROWEXCEPTION( ixit.get().getType() == myTokenType );
++i;
}
ASSERT_OR_THROWEXCEPTION(i == myTokenNum);
delete typeFilter;
typeFilter = NULL;
LOG("...type filter checked");
//////////////////////////////////////////
LOG("Checking AND/int feature value filter");
vFeaturePath.clear();
vFeaturePath.push_back(beginFeat);
FSFilter * intFeatureFilter1 = builder.createIntFeatureFilter(vFeaturePath, FSFilterBuilder::EQUALS, 5);
vFeaturePath.clear();
vFeaturePath.push_back(endFeat);
FSFilter * intFeatureFilter2 = builder.createIntFeatureFilter(vFeaturePath, FSFilterBuilder::LESS, 10);
FSFilter * conjFeatureFilter = builder.createANDFilter(intFeatureFilter1, intFeatureFilter2);
ixit = ix.filteredIterator(conjFeatureFilter);
i=0;
for (ixit.moveToFirst(); ixit.isValid(); ixit.moveToNext()) {
FeatureStructure fs = ixit.get();
ASSERT_OR_THROWEXCEPTION( !( (fs.getIntValue(beginFeat) == 5) && (fs.getIntValue(endFeat) < 10) ) );
++i;
}
LOG(" Found " << i << " filtered FSs");
ASSERT_OR_THROWEXCEPTION( i == 4 );
LOG("... AND/int feature value filter checked");
/////////////////////////////////////////////
LOG("Checking NOT filter");
FSFilter * notFilter = builder.createNOTFilter(conjFeatureFilter);
ixit = ix.filteredIterator(notFilter);
i=0;
for (ixit.moveToFirst(); ixit.isValid(); ixit.moveToNext()) {
FeatureStructure fs = ixit.get();
ASSERT_OR_THROWEXCEPTION( ( (fs.getIntValue(beginFeat) == 5) && (fs.getIntValue(endFeat) < 10) ) );
++i;
}
LOG(" Found " << i << " filtered FSs");
ASSERT_OR_THROWEXCEPTION( i == 1 );
notFilter->deInit();
delete notFilter;
notFilter = NULL;
LOG("... NOT filter checked");
////////////////////////////////////////////////////
LOG("Checking match filter");
FSFilter * myTokenTypeFilter1 = builder.createTypeFilter(myTokenType, true);
FSFilter * myTokenTypeFilter2 = builder.createTypeFilter(myTokenType, true);
vFeaturePath.clear();
vFeaturePath.push_back(myRecursiveFeature);
FSFilter * matchFilter = builder.createMatchFilter(vFeaturePath, myTokenTypeFilter2);
FSFilter * andFilter = builder.createANDFilter(myTokenTypeFilter1, matchFilter);
LOG("Creating iterator");
ixit = ix.filteredIterator(andFilter);
LOG("... Iterator created");
i=0;
for (ixit.moveToFirst(); ixit.isValid(); ixit.moveToNext()) {
FeatureStructure fs = ixit.get();
ASSERT_OR_THROWEXCEPTION( tokenType.subsumes( fs.getType() ));
++i;
}
LOG("Found " << i << " FSs");
ASSERT_OR_THROWEXCEPTION(i==4);
andFilter->deInit();
delete andFilter;
LOG("... match filter checked");
//////////////////////////////////////////////////////
LOG("Checking string filter");
FSFilter * myTokenTypeFilter3 = builder.createTypeFilter(myTokenType, true);
vFeaturePath.clear();
vFeaturePath.push_back(myStringFeature);
icu::UnicodeString usMatch("string3");
FSFilter * stringFilter = builder.createStringFeatureFilter(vFeaturePath, usMatch.getBuffer(), usMatch.length() );
// FSFilter * matchFilter2 = builder.createMatchFilter(vFeaturePath, stringFilter);
FSFilter * andFilter2 = builder.createANDFilter(myTokenTypeFilter3, stringFilter);
LOG("Creating iterator");
ixit = ix.filteredIterator(andFilter2);
LOG("... Iterator created");
i=0;
for (ixit.moveToFirst(); ixit.isValid(); ixit.moveToNext()) {
FeatureStructure fs = ixit.get();
if (fs.getType() == myTokenType) {
UnicodeStringRef p = fs.getStringValue(myStringFeature);
icu::UnicodeString str( p.getBuffer(), p.length() );
LOG(" found string: " << str);
ASSERT_OR_THROWEXCEPTION( ! (str == usMatch ));
}
++i;
}
LOG("Found " << i << " FSs");
ASSERT_OR_THROWEXCEPTION(i == (tokenNum - 1));
andFilter2->deInit();
delete andFilter2;
delete pCas;
LOG("... string filter checked");
LOG("testOOFilterBuilder() finished");
}
/************************************************************************************/
void testIteratorSetToPosition() {
LOG("testIteratorSetToPosition() started");
TestCAS testcas;
uima::internal::CASImpl & tcas = testcas.getCAS();
lowlevel::TypeSystem const & typeSystem = testcas.getCASDef().getTypeSystem();
lowlevel::TyFSType tokenType = typeSystem.getTypeByName(TT::TYPE_NAME_TOKEN_ANNOTATION);
lowlevel::TyFSFeature beginFeature = typeSystem.getFeatureByBaseName(tokenType, CAS::FEATURE_BASE_NAME_BEGIN);
lowlevel::TyFSFeature endFeature = typeSystem.getFeatureByBaseName(tokenType, CAS::FEATURE_BASE_NAME_END);
lowlevel::FSHeap & fsHeap = tcas.getHeap();
StrToken tokens[] = {
{
tokenType, 0, 3, 0
}
, // 0
{ tokenType, 3, 5, 0}, // 1
{ tokenType, 5, 8, 0}, // 2
{ tokenType, 9, 11, 0}, // 3
{ tokenType, 15, 16, 0}, // 4
{ tokenType, 17, 20, 0} // 5
};
size_t tokenNum = NUMBEROF(tokens);
lowlevel::IndexRepository & indexRep = tcas.getIndexRepository();
size_t i;
for (i=0; i<tokenNum; ++i) {
lowlevel::TyFS token = fsHeap.createFS(tokens[i].annot.type);
fsHeap.setIntValue(token, beginFeature, tokens[i].annot.begin);
fsHeap.setIntValue(token, endFeature, tokens[i].annot.end);
indexRep.add(token);
}
icu::UnicodeString const & ixID = tcas.getAnnotationIndexID();
lowlevel::IndexABase const & ix = indexRep.getLowlevelIndex(ixID, tokenType);
auto_ptr<lowlevel::IndexIterator> it1(ix.createIterator() );
auto_ptr<lowlevel::IndexIterator> it2(ix.createIterator());
const size_t numberOfAdvances = 2;
it1->moveToFirst();
for (i=0; i<numberOfAdvances; ++i) {
ASSERT_OR_THROWEXCEPTION( it1->isValid() );
it1->moveToNext();
}
ASSERT_OR_THROWEXCEPTION( it1->isValid() );
LOG("Setting it2 to point to token from " << fsHeap.getIntValue(it1->get(), beginFeature) << " to " << fsHeap.getIntValue(it1->get(), endFeature) );
bool bCouldBeSet = it2->moveTo(it1->get());
ASSERT_OR_THROWEXCEPTION(bCouldBeSet);
ASSERT_OR_THROWEXCEPTION( it2->isValid() );
ASSERT_OR_THROWEXCEPTION( it2->get() == it1->get() );
// check that rest tokens are also found
for (i=numberOfAdvances; i<tokenNum; ++i) {
ASSERT_OR_THROWEXCEPTION( it1->isValid() );
ASSERT_OR_THROWEXCEPTION( it2->isValid() );
LOG("Checking token from " << fsHeap.getIntValue(it1->get(), beginFeature) << " to " << fsHeap.getIntValue(it1->get(), endFeature) );
ASSERT_OR_THROWEXCEPTION( it1->get() == it2->get() );
it1->moveToNext();
it2->moveToNext();
}
ASSERT_OR_THROWEXCEPTION( ! it1->isValid() );
ASSERT_OR_THROWEXCEPTION( ! it2->isValid() );
LOG("testIteratorSetToPosition() finished");
}
/************************************************************************************/
class MyLowlevelFilter : public lowlevel::FSFilter {
private:
uima::internal::CASImpl const & iv_tcas;
lowlevel::TyFSType annotType;
lowlevel::TyFSFeature beginFeat;
public:
MyLowlevelFilter(uima::internal::CASImpl const & tcas)
: iv_tcas(tcas) {
annotType = tcas.getHeap().getTypeSystem().getTypeByName(CAS::TYPE_NAME_ANNOTATION);
beginFeat = tcas.getHeap().getTypeSystem().getFeatureByBaseName( annotType, CAS::FEATURE_BASE_NAME_BEGIN);
}
// filter those annotations whose begin position is less than 10
bool isFiltered(lowlevel::TyFS fs) const {
lowlevel::FSHeap const & crFSHeap = iv_tcas.getHeap();
lowlevel::TypeSystem const & crTypeSystem = crFSHeap.getTypeSystem();
// filter only annotations
if (! crTypeSystem.subsumes( annotType, crFSHeap.getType(fs)) ) {
return false;
}
int iBegin = crFSHeap.getIntValue(fs, beginFeat);
return(iBegin < 10);
}
};
void testFilters() {
LOG("testFilters() started");
TestCAS testcas;
uima::internal::CASImpl & tcas = testcas.getCAS();
lowlevel::TypeSystem const & typeSystem = testcas.getCASDef().getTypeSystem();
lowlevel::TyFSType tokenType = typeSystem.getTypeByName(TT::TYPE_NAME_TOKEN_ANNOTATION);
lowlevel::TyFSFeature beginFeature = typeSystem.getFeatureByBaseName(tokenType, CAS::FEATURE_BASE_NAME_BEGIN);
lowlevel::TyFSFeature endFeature = typeSystem.getFeatureByBaseName(tokenType, CAS::FEATURE_BASE_NAME_END);
lowlevel::FSHeap & fsHeap = tcas.getHeap();
StrToken tokens[] = {
{
tokenType, 0, 3, 0
}
, // 0
{ tokenType, 3, 5, 0}, // 1
{ tokenType, 5, 8, 0}, // 2
{ tokenType, 9, 11, 0}, // 3
{ tokenType, 15, 16, 0}, // 4
{ tokenType, 17, 20, 0} // 5
};
size_t tokenNum = NUMBEROF(tokens);
lowlevel::IndexRepository & indexRep = tcas.getIndexRepository();
size_t i;
for (i=0; i<tokenNum; ++i) {
lowlevel::TyFS token = fsHeap.createFS(tokens[i].annot.type);
fsHeap.setIntValue(token, beginFeature, tokens[i].annot.begin);
fsHeap.setIntValue(token, endFeature, tokens[i].annot.end);
indexRep.add(token);
}
icu::UnicodeString const & ixID = tcas.getAnnotationIndexID();
lowlevel::IndexABase const & ix = indexRep.getLowlevelIndex(ixID, tokenType);
LOG("Annotations created");
MyLowlevelFilter* myFilter = new MyLowlevelFilter(tcas);
lowlevel::IndexIterator* it = ix.createFilteredIterator(myFilter);
LOG("filtered iterator created");
it->moveToFirst();
LOG("Checking first annotation");
ASSERT_OR_THROWEXCEPTION( it->isValid() );
lowlevel::TyFS fs = it->get();
ASSERT_OR_THROWEXCEPTION( fsHeap.getIntValue(fs, beginFeature) == 15 );
it->moveToNext();
ASSERT_OR_THROWEXCEPTION( it->isValid() );
fs = it->get();
ASSERT_OR_THROWEXCEPTION( fsHeap.getIntValue(fs, beginFeature) == 17 );
it->moveToNext();
ASSERT_OR_THROWEXCEPTION( ! it->isValid() );
delete it;
delete myFilter;
LOG("testFilters() finished");
}
/************************************************************************************/
/*
class PermanentComparator : public lowlevel::IndexComparator {
public:
PermanentComparator(lowlevel::FSHeap const & heap, lowlevel::TyFSType type)
: lowlevel::IndexComparator(heap, type) {
}
int compare(lowlevel::TyFS, lowlevel::TyFS) const {
return 1;
}
};
*/
void testPermanentStructures() {
LOG("testPermanentStructures() skipped!!!");
#ifdef BYEBYEPERM
LOG("testPermanentStructures() started");
TTDefinition ttdef;
ttdef.init();
ttdef.commitTypeSystem();
uima::lowlevel::IndexDefinition & indexDef = ttdef.getIndexDefinition();
lowlevel::TypeSystem const & typeSystem = ttdef.getTypeSystem();
lowlevel::TyFSType tokenType = typeSystem.getTypeByName(TT::TYPE_NAME_TOKEN_ANNOTATION);
lowlevel::TyFSFeature beginFeature = typeSystem.getFeatureByBaseName(tokenType, CAS::FEATURE_BASE_NAME_BEGIN);
lowlevel::TyFSFeature endFeature = typeSystem.getFeatureByBaseName(tokenType, CAS::FEATURE_BASE_NAME_END);
lowlevel::TyFeatureOffset beginFeatOffset = typeSystem.getFeatureOffset(beginFeature);
lowlevel::TyFeatureOffset endFeatOffset = typeSystem.getFeatureOffset(endFeature);
vector<lowlevel::TyFSFeature> tokenKeyFeatures;
vector<uima::lowlevel::IndexComparator::EnKeyFeatureComp> tokenComparators;
tokenKeyFeatures.push_back(beginFeature);
tokenKeyFeatures.push_back(endFeature);
tokenComparators.resize(2, uima::lowlevel::IndexComparator::STANDARD_COMPARE );
// PermanentComparator* permComp = new PermanentComparator(heap, tokenType);
indexDef.defineIndex(uima::lowlevel::IndexDefinition::enSet,
tokenType,
tokenKeyFeatures,
tokenComparators,
"2001",
true );
ASSERT_OR_THROWEXCEPTION( indexDef.getIndexKind("2001") == uima::lowlevel::IndexDefinition::enSet );
ttdef.commitIndexDefinition();
// uima::internal::TCASImpl tcas(ttdef, 4000, 4000, 4000);
uima::internal::CASImpl & tcas = getCASImpl(ttdef);
icu::UnicodeString const & annotationIndexID = tcas.getAnnotationIndexID();
lowlevel::FSHeap & heap = tcas.getHeap();
lowlevel::IndexRepository & indexRep = tcas.getIndexRepository();
lowlevel::TyFS permFS = heap.createFS( lowlevel::FSHeap::PERMANENT, tokenType );
heap.setIntValue(permFS, beginFeature, 1);
heap.setIntValue(permFS, endFeature, 2);
lowlevel::TyFS tempFS1 = heap.createFS( lowlevel::FSHeap::TEMPORARY, tokenType );
heap.setIntValue(tempFS1, beginFeature, 3);
heap.setIntValue(tempFS1, endFeature, 4);
ASSERT_OR_THROWEXCEPTION( permFS != lowlevel::FSHeap::INVALID_FS );
ASSERT_OR_THROWEXCEPTION( tempFS1 != lowlevel::FSHeap::INVALID_FS );
indexRep.add(tempFS1);
lowlevel::IndexABase const & index = indexRep.getLowlevelIndex( annotationIndexID, tokenType );
lowlevel::IndexABase const & permIndex = indexRep.getLowlevelIndex( "2001", tokenType);
ASSERT_OR_THROWEXCEPTION( index.getSize() == 1 );
ASSERT_OR_THROWEXCEPTION( permIndex.getSize() == 1 );
LOG("FSs created");
tcas.resetWithoutCreatingDocAnnotation();
LOG("TCAS reset'd");
ASSERT_OR_THROWEXCEPTION( index.getSize() == 0 );
ASSERT_OR_THROWEXCEPTION( permIndex.getSize() == 1 );
ASSERT_OR_THROWEXCEPTION( *tempFS1 == 0 );
ASSERT_OR_THROWEXCEPTION( *(tempFS1 + beginFeatOffset) == 0 );
ASSERT_OR_THROWEXCEPTION( *(tempFS1 + endFeatOffset) == 0 );
LOG("temp fs checked");
ASSERT_OR_THROWEXCEPTION( heap.getType(permFS) == tokenType );
ASSERT_OR_THROWEXCEPTION( (size_t) heap.getFeatureWithOffset(permFS, beginFeatOffset) == 1 );
ASSERT_OR_THROWEXCEPTION( (size_t) heap.getFeatureWithOffset(permFS, endFeatOffset) == 2 );
LOG("perm fs checked");
// delete permComp;
LOG("testPermanentStructures() finished");
#endif
}
/************************************************************************************/
/*
// obsolete since IDs are now strings.
void testNewIndexID() {
LOG("testNewIndexID() started");
uima::internal::TCASImpl tcas(4000);
tcas.commitTypeSystem();
uima::lowlevel::TypeSystem & ts = tcas.getFSSystem().getLowlevelTypeSystem();
// get some types and features
lowlevel::TyFSType annotType = ts.getTypeByName( CAS::TYPE_NAME_ANNOTATION );
ASSERT_OR_THROWEXCEPTION( ts.isValidType(annotType) );
lowlevel::TyFSFeature beginPosFeat = ts.getFeatureByBaseName( CAS::FEATURE_BASE_NAME_BEGIN );
ASSERT_OR_THROWEXCEPTION( ts.isValidFeature(beginPosFeat) );
lowlevel::TyFSFeature endPosFeat = ts.getFeatureByBaseName( CAS::FEATURE_BASE_NAME_END );
ASSERT_OR_THROWEXCEPTION( ts.isValidFeature(endPosFeat) );
vector<lowlevel::TyFSFeature> keyFeatures;
keyFeatures.push_back(beginPosFeat);
keyFeatures.push_back(endPosFeat);
lowlevel::KeyFeatureComparator annotComp(tcas.getFSSystem().getLowlevelFSHeap(), annotType, keyFeatures);
uima::lowlevel::IndexRepository & ixRep = tcas.getFSSystem().getLowlevelIndexRepository();
int id1 = ixRep.getNewIndexID();
LOG("New index ID: " << id1);
ASSERT_OR_THROWEXCEPTION( ! ixRep.isValidIndexId(id1) );
ixRep.createOrderedIndex(annotType, & annotComp, id1);
int id2 = ixRep.getNewIndexID();
ASSERT_OR_THROWEXCEPTION( ! ixRep.isValidIndexId(id2) );
ASSERT_OR_THROWEXCEPTION( id1 != id2 );
LOG("testNewIndexID() finished");
}
*/
/************************************************************************************/
void testOOArrayFS() {
LOG("testOOArrayFS() started");
TestCAS testcas;
uima::internal::CASImpl & tcas = testcas.getCAS();
FeatureStructure strFS1 = tcas.createListFS();
FeatureStructure strFS2 = tcas.createListFS();
FeatureStructure strFS3 = tcas.createListFS();
FeatureStructure strFS4 = tcas.createListFS();
FeatureStructure strFS5 = tcas.createListFS();
FeatureStructure strings[] = {
strFS1, strFS3, strFS2, strFS5, strFS4
};
const size_t length = NUMBEROF(strings);
size_t i=0;
ArrayFS fs = tcas.createArrayFS(length);
ASSERT_OR_THROWEXCEPTION( fs.size() == length );
for (i=0; i<length; ++i) {
fs.set(i, strings[i]);
}
for (i=0; i<length; ++i) {
ASSERT_OR_THROWEXCEPTION( fs.get(i) == strings[i] );
}
LOG("testOOArrayFS() finished");
}
/************************************************************************************/
void testOOStringArrayFS() {
LOG("testOOStringArray() started");
TestCAS testcas;
uima::internal::CASImpl & tcas = testcas.getCAS();
icu::UnicodeString str1("string1");
icu::UnicodeString str2("string2");
icu::UnicodeString str3("string3");
icu::UnicodeString str4("string4");
icu::UnicodeString str5("string5");
UnicodeStringRef strings[] = {
str1, str3, str2, str5, str4
};
const size_t length = NUMBEROF(strings);
size_t i=0;
StringArrayFS fs = tcas.createStringArrayFS(length);
ASSERT_OR_THROWEXCEPTION( fs.size() == length );
for (i=0; i<length; ++i) {
fs.set(i, strings[i]);
}
for (i=0; i<length; ++i) {
ASSERT_OR_THROWEXCEPTION( fs.get(i) == strings[i] );
}
LOG("testOOStringArrayFS() finished");
}
/************************************************************************************/
void testOOListFunctionsOld() {
LOG("testOOListFunctions() started");
TestCAS testcas;
uima::internal::CASImpl & tcas = testcas.getCAS();
TypeSystem const & typeSystem = tcas.getTypeSystem();
Type tokenAnnType = typeSystem.getType(TT::TYPE_NAME_TOKEN_ANNOTATION);
Feature tokenNbrFeat = tokenAnnType.getFeatureByBaseName(TT::FEATURE_BASE_NAME_TOKEN_NUMBER);
// create tokens
FeatureStructure tok0 = tcas.createFS(tokenAnnType);
tok0.setIntValue(tokenNbrFeat, 0);
FeatureStructure tok1 = tcas.createFS(tokenAnnType);
tok1.setIntValue(tokenNbrFeat, 1);
FeatureStructure tok2 = tcas.createFS(tokenAnnType);
tok2.setIntValue(tokenNbrFeat, 2);
FeatureStructure tok3 = tcas.createFS(tokenAnnType);
tok3.setIntValue(tokenNbrFeat, 3);
FeatureStructure tok4 = tcas.createFS(tokenAnnType);
tok4.setIntValue(tokenNbrFeat, 4);
FeatureStructure tok5 = tcas.createFS(tokenAnnType);
tok5.setIntValue(tokenNbrFeat, 5);
FeatureStructure tok6 = tcas.createFS(tokenAnnType);
tok6.setIntValue(tokenNbrFeat, 6);
FeatureStructure tokens[] = {
tok0, tok1, tok2, tok3, tok4, tok5, tok6
};
size_t tokNum = NUMBEROF(tokens);
ASSERT_OR_THROWEXCEPTION( tokNum == 7);
ListFS tokList = tcas.createListFS();
ASSERT_OR_THROWEXCEPTION( tokList.isEmpty() );
ASSERT_OR_THROWEXCEPTION( tokList.getLength() == 0 );
tokList.addFirst(tok3);
ASSERT_OR_THROWEXCEPTION( tokList.getLength() == 1 );
tokList.addLast(tok4);
tokList.addFirst(tok2);
tokList.addLast(tok5);
tokList.addFirst(tok1);
tokList.addLast(tok6);
tokList.addFirst(tok0);
ListFS fs(tokList);
ASSERT_OR_THROWEXCEPTION( tokList.getLength() == tokNum );
size_t i;
for (i=0; i<tokNum; ++i) {
LOG("Examining list element " << i);
assert(!fs.isEmpty());
FeatureStructure element = fs.getHead();
int j = element.getIntValue(tokenNbrFeat);
ASSERT_OR_THROWEXCEPTION(i == j);
fs.moveToNext();
}
ASSERT_OR_THROWEXCEPTION( fs.isEmpty() );
ASSERT_OR_THROWEXCEPTION( tokList.getHead() == tok0 );
tokList.setHead(tok6);
ASSERT_OR_THROWEXCEPTION( tokList.getHead() == tok6);
{
// test appending of lists
ListFS eList1 = tcas.createListFS();
ASSERT_OR_THROWEXCEPTION( eList1.isEmpty() );
ListFS neList1 = tcas.createListFS();
neList1.addFirst(tok1);
ASSERT_OR_THROWEXCEPTION( neList1.getLength() == 1 );
eList1.append(neList1); // append a non-empty list to an empty list
ASSERT_OR_THROWEXCEPTION( eList1.getLength() == 1 );
ASSERT_OR_THROWEXCEPTION( neList1.getLength() == eList1.getLength() );
ListFS eList2 = tcas.createListFS();
ASSERT_OR_THROWEXCEPTION( eList2.isEmpty() );
ListFS neList2 = tcas.createListFS();
neList2.addFirst(tok1);
ASSERT_OR_THROWEXCEPTION( neList2.getLength() == 1 );
neList2.append(eList2); // append an empty list to a non-empty list
ASSERT_OR_THROWEXCEPTION( neList2.getLength() == 1 );
ASSERT_OR_THROWEXCEPTION( eList2.getLength() == 0 );
ListFS neList3 = tcas.createListFS();
neList3.addFirst(tok1);
ASSERT_OR_THROWEXCEPTION( neList3.getLength() == 1 );
ListFS neList4 = tcas.createListFS();
neList4.addFirst(tok2);
ASSERT_OR_THROWEXCEPTION( neList4.getLength() == 1 );
neList3.append(neList4); // append a non-empty list to a non-empty list
ASSERT_OR_THROWEXCEPTION( neList3.getLength() == 2 );
ASSERT_OR_THROWEXCEPTION( neList4.getLength() == 1 );
bool bExcCaught = false;
ListFS neList5 = tcas.createListFS();
neList5.addFirst(tok1);
ASSERT_OR_THROWEXCEPTION( neList5.getLength() == 1 );
try {
neList5.append(neList5); // append a non-empty list to itself
} catch (ListIsCircularException e) {
bExcCaught = true;
}
ASSERT_OR_THROWEXCEPTION( bExcCaught );
ListFS eList6 = tcas.createListFS();
ASSERT_OR_THROWEXCEPTION( eList6.getLength() == 0 );
eList6.append(eList6); // append an empty list to itself
ASSERT_OR_THROWEXCEPTION( eList6.getLength() == 0 );
ListFS eList7 = tcas.createListFS();
ASSERT_OR_THROWEXCEPTION( eList7.getLength() == 0 );
ListFS eList8 = tcas.createListFS();
ASSERT_OR_THROWEXCEPTION( eList8.getLength() == 0 );
eList7.append(eList8); // append an empty list to an empty list
ASSERT_OR_THROWEXCEPTION( eList7.getLength() == 0 );
ASSERT_OR_THROWEXCEPTION( eList8.getLength() == 0 );
}
{
// test prepending of lists
ListFS eList1 = tcas.createListFS();
ASSERT_OR_THROWEXCEPTION( eList1.isEmpty() );
ListFS neList1 = tcas.createListFS();
neList1.addFirst(tok1);
ASSERT_OR_THROWEXCEPTION( neList1.getLength() == 1 );
eList1.prepend(neList1); // prepend a non-empty list to an empty list
ASSERT_OR_THROWEXCEPTION( eList1.getLength() == 1 );
ASSERT_OR_THROWEXCEPTION( neList1.getLength() == eList1.getLength() );
ListFS eList2 = tcas.createListFS();
ASSERT_OR_THROWEXCEPTION( eList2.isEmpty() );
ListFS neList2 = tcas.createListFS();
neList2.addFirst(tok1);
ASSERT_OR_THROWEXCEPTION( neList2.getLength() == 1 );
neList2.prepend(eList2); // prepend an empty list to a non-empty list
ASSERT_OR_THROWEXCEPTION( neList2.getLength() == 1 );
ASSERT_OR_THROWEXCEPTION( eList2.getLength() == 0 );
ListFS neList3 = tcas.createListFS();
neList3.addFirst(tok1);
ASSERT_OR_THROWEXCEPTION( neList3.getLength() == 1 );
ListFS neList4 = tcas.createListFS();
neList4.addFirst(tok2);
ASSERT_OR_THROWEXCEPTION( neList4.getLength() == 1 );
neList3.prepend(neList4); // prepend a non-empty list to a non-empty list
ASSERT_OR_THROWEXCEPTION( neList3.getLength() == 2 );
ASSERT_OR_THROWEXCEPTION( neList4.getLength() == 2 );
bool bExcCaught = false;
ListFS neList5 = tcas.createListFS();
neList5.addFirst(tok1);
ASSERT_OR_THROWEXCEPTION( neList5.getLength() == 1 );
try {
neList5.prepend(neList5); // prepend a non-empty list to itself
} catch (ListIsCircularException e) {
bExcCaught = true;
}
ASSERT_OR_THROWEXCEPTION( bExcCaught );
ListFS eList6 = tcas.createListFS();
ASSERT_OR_THROWEXCEPTION( eList6.getLength() == 0 );
eList6.prepend(eList6); // prepend an empty list to itself
ASSERT_OR_THROWEXCEPTION( eList6.getLength() == 0 );
ListFS eList7 = tcas.createListFS();
ASSERT_OR_THROWEXCEPTION( eList7.getLength() == 0 );
ListFS eList8 = tcas.createListFS();
ASSERT_OR_THROWEXCEPTION( eList8.getLength() == 0 );
eList7.prepend(eList8); // prepend an empty list to an empty list
ASSERT_OR_THROWEXCEPTION( eList7.getLength() == 0 );
ASSERT_OR_THROWEXCEPTION( eList8.getLength() == 0 );
}
;
// test nested addFirst/addLast
ListFS list = tcas.createListFS();
list.addFirst(tok0);
ListFS list0 = list;
ASSERT_OR_THROWEXCEPTION( list.getLength() == 1 );
ASSERT_OR_THROWEXCEPTION( list0.getLength() == 1 );
list = list.addLast(tok1).addLast(tok2).addLast(tok3);
ASSERT_OR_THROWEXCEPTION( list.getLength() == 1 );
ASSERT_OR_THROWEXCEPTION( list0.getLength() == 4);
list = list.addFirst(tok1).addFirst(tok2).addFirst(tok3);
ASSERT_OR_THROWEXCEPTION( list.getLength() == 4 );
ASSERT_OR_THROWEXCEPTION( list0.getLength() == 4 );
list = list.addLast(tok1).addFirst(tok2).addLast(tok3);
ASSERT_OR_THROWEXCEPTION( list.getLength() == 1 );
ASSERT_OR_THROWEXCEPTION( list0.getLength() == 6 );
// test nested append/prepend
ListFS list1, list2, list3;
list1 = tcas.createListFS();
list1.addFirst(tok1);
ASSERT_OR_THROWEXCEPTION( list1.getLength() == 1 );
list2 = tcas.createListFS();
list2.addFirst(tok2);
ASSERT_OR_THROWEXCEPTION( list2.getLength() == 1 );
list3 = tcas.createListFS();
list3.addFirst(tok3);
ASSERT_OR_THROWEXCEPTION( list3.getLength() == 1 );
list1 = list1.append(list2).append(list3);
ASSERT_OR_THROWEXCEPTION( list1.getLength() == 3 );
list1 = tcas.createListFS();
list1.addFirst(tok1);
ASSERT_OR_THROWEXCEPTION( list1.getLength() == 1 );
list2 = tcas.createListFS();
list2.addFirst(tok2);
ASSERT_OR_THROWEXCEPTION( list2.getLength() == 1 );
list3 = tcas.createListFS();
list3.addFirst(tok3);
ASSERT_OR_THROWEXCEPTION( list3.getLength() == 1 );
list1 = list1.prepend(list2).prepend(list3);
ASSERT_OR_THROWEXCEPTION( list1.getLength() == 3 );
list1 = tcas.createListFS();
list1.addFirst(tok1);
ASSERT_OR_THROWEXCEPTION( list1.getLength() == 1 );
list2 = tcas.createListFS();
list2.addFirst(tok2);
ASSERT_OR_THROWEXCEPTION( list2.getLength() == 1 );
list3 = tcas.createListFS();
list3.addFirst(tok3);
ASSERT_OR_THROWEXCEPTION( list3.getLength() == 1 );
list1 = list1.append(list2).prepend(list3);
ASSERT_OR_THROWEXCEPTION( list1.getLength() == 3 );
LOG("testOOListFunctions() finished");
}
template<class T>
class SimpleEquals {
public:
bool equals(T t1, T t2) const {
return t1 == t2;
}
};
class StringEquals {
public:
bool equals(UnicodeStringRef const & crp1,
UnicodeStringRef const & crp2) const {
LOG("Comparing: " << crp1 << " with " << crp2);
return((UnicodeStringRef) crp1) == ((UnicodeStringRef) crp2);
}
};
template< class LFS_TYPE, class COMP>
void testOOListFunctionsTempl(CAS & tcas, vector< typename LFS_TYPE::HeadType > & vec, COMP const & crComp) {
LOG("testOOListFunctionsTempl() started");
LFS_TYPE list = LFS_TYPE::createListFS(tcas);
ASSERT_OR_THROWEXCEPTION( list.isEmpty() );
ASSERT_OR_THROWEXCEPTION( list.getLength() == 0 );
list.addFirst(vec[3]);
ASSERT_OR_THROWEXCEPTION( list.getLength() == 1 );
list.addLast(vec[4]);
list.addFirst(vec[2]);
list.addLast(vec[5]);
list.addFirst(vec[1]);
list.addLast(vec[6]);
list.addFirst(vec[0]);
const size_t uiNUMBER_OF_ELEMENTS = 7;
LFS_TYPE fs(list);
ASSERT_OR_THROWEXCEPTION( list.getLength() == uiNUMBER_OF_ELEMENTS );
size_t i;
for (i=0; i<uiNUMBER_OF_ELEMENTS; ++i) {
LOG("Examining list element " << i);
assert(!fs.isEmpty());
typename LFS_TYPE::HeadType element = fs.getHead();
ASSERT_OR_THROWEXCEPTION( crComp.equals( element, vec[i]) );
fs.moveToNext();
}
ASSERT_OR_THROWEXCEPTION( fs.isEmpty() );
ASSERT_OR_THROWEXCEPTION( crComp.equals( list.getHead(), vec[0]) );
list.setHead(vec[6]);
ASSERT_OR_THROWEXCEPTION( crComp.equals( list.getHead(), vec[6]) );
{
// test appending of lists
LFS_TYPE eList1 = LFS_TYPE::createListFS(tcas);
ASSERT_OR_THROWEXCEPTION( eList1.isEmpty() );
LFS_TYPE neList1 = LFS_TYPE::createListFS(tcas, vec[1]);
ASSERT_OR_THROWEXCEPTION( neList1.getLength() == 1 );
eList1.append(neList1); // append a non-empty list to an empty list
ASSERT_OR_THROWEXCEPTION( eList1.getLength() == 1 );
ASSERT_OR_THROWEXCEPTION( neList1.getLength() == eList1.getLength() );
LFS_TYPE eList2 = LFS_TYPE::createListFS(tcas);
ASSERT_OR_THROWEXCEPTION( eList2.isEmpty() );
LFS_TYPE neList2 = LFS_TYPE::createListFS(tcas, vec[1]);
ASSERT_OR_THROWEXCEPTION( neList2.getLength() == 1 );
neList2.append(eList2); // append an empty list to a non-empty list
ASSERT_OR_THROWEXCEPTION( neList2.getLength() == 1 );
ASSERT_OR_THROWEXCEPTION( eList2.getLength() == 0 );
LFS_TYPE neList3 = LFS_TYPE::createListFS(tcas, vec[1]);
ASSERT_OR_THROWEXCEPTION( neList3.getLength() == 1 );
LFS_TYPE neList4 = LFS_TYPE::createListFS(tcas, vec[2]);
ASSERT_OR_THROWEXCEPTION( neList4.getLength() == 1 );
neList3.append(neList4); // append a non-empty list to a non-empty list
ASSERT_OR_THROWEXCEPTION( neList3.getLength() == 2 );
ASSERT_OR_THROWEXCEPTION( neList4.getLength() == 1 );
bool bExcCaught = false;
LFS_TYPE neList5 = LFS_TYPE::createListFS(tcas, vec[1]);
ASSERT_OR_THROWEXCEPTION( neList5.getLength() == 1 );
try {
neList5.append(neList5); // append a non-empty list to itself
} catch (ListIsCircularException e) {
bExcCaught = true;
}
ASSERT_OR_THROWEXCEPTION( bExcCaught );
LFS_TYPE eList6 = LFS_TYPE::createListFS(tcas);
ASSERT_OR_THROWEXCEPTION( eList6.getLength() == 0 );
eList6.append(eList6); // append an empty list to itself
ASSERT_OR_THROWEXCEPTION( eList6.getLength() == 0 );
LFS_TYPE eList7 = LFS_TYPE::createListFS(tcas);
ASSERT_OR_THROWEXCEPTION( eList7.getLength() == 0 );
LFS_TYPE eList8 = LFS_TYPE::createListFS(tcas);
ASSERT_OR_THROWEXCEPTION( eList8.getLength() == 0 );
eList7.append(eList8); // append an empty list to an empty list
ASSERT_OR_THROWEXCEPTION( eList7.getLength() == 0 );
ASSERT_OR_THROWEXCEPTION( eList8.getLength() == 0 );
}
{
// test prepending of lists
LFS_TYPE eList1 = LFS_TYPE::createListFS(tcas);
ASSERT_OR_THROWEXCEPTION( eList1.isEmpty() );
LFS_TYPE neList1 = LFS_TYPE::createListFS(tcas, vec[1]);
ASSERT_OR_THROWEXCEPTION( neList1.getLength() == 1 );
eList1.prepend(neList1); // prepend a non-empty list to an empty list
ASSERT_OR_THROWEXCEPTION( eList1.getLength() == 1 );
ASSERT_OR_THROWEXCEPTION( neList1.getLength() == eList1.getLength() );
LFS_TYPE eList2 = LFS_TYPE::createListFS(tcas);
ASSERT_OR_THROWEXCEPTION( eList2.isEmpty() );
LFS_TYPE neList2 = LFS_TYPE::createListFS(tcas, vec[1]);
ASSERT_OR_THROWEXCEPTION( neList2.getLength() == 1 );
neList2.prepend(eList2); // prepend an empty list to a non-empty list
ASSERT_OR_THROWEXCEPTION( neList2.getLength() == 1 );
ASSERT_OR_THROWEXCEPTION( eList2.getLength() == 0 );
LFS_TYPE neList3 = LFS_TYPE::createListFS(tcas, vec[1]);
ASSERT_OR_THROWEXCEPTION( neList3.getLength() == 1 );
LFS_TYPE neList4 = LFS_TYPE::createListFS(tcas, vec[2]);
ASSERT_OR_THROWEXCEPTION( neList4.getLength() == 1 );
neList3.prepend(neList4); // prepend a non-empty list to a non-empty list
ASSERT_OR_THROWEXCEPTION( neList3.getLength() == 2 );
ASSERT_OR_THROWEXCEPTION( neList4.getLength() == 2 );
bool bExcCaught = false;
LFS_TYPE neList5 = LFS_TYPE::createListFS(tcas, vec[1]);
ASSERT_OR_THROWEXCEPTION( neList5.getLength() == 1 );
try {
neList5.prepend(neList5); // prepend a non-empty list to itself
} catch (ListIsCircularException e) {
bExcCaught = true;
}
ASSERT_OR_THROWEXCEPTION( bExcCaught );
LFS_TYPE eList6 = LFS_TYPE::createListFS(tcas);
ASSERT_OR_THROWEXCEPTION( eList6.getLength() == 0 );
eList6.prepend(eList6); // prepend an empty list to itself
ASSERT_OR_THROWEXCEPTION( eList6.getLength() == 0 );
LFS_TYPE eList7 = LFS_TYPE::createListFS(tcas);
ASSERT_OR_THROWEXCEPTION( eList7.getLength() == 0 );
LFS_TYPE eList8 = LFS_TYPE::createListFS(tcas);
ASSERT_OR_THROWEXCEPTION( eList8.getLength() == 0 );