blob: 804b1cb8c6308efe9b1646ff4000a0b1e80755a3 [file] [log] [blame]
/** \file fsindex.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.
-----------------------------------------------------------------------------
Description:
-----------------------------------------------------------------------------
-------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------- */
/* Include dependencies */
/* ----------------------------------------------------------------------- */
#include "uima/fsindex.hpp"
#include "uima/msg.h"
#include "uima/internal_fspromoter.hpp"
#include "uima/lowlevel_fsfilter.hpp"
#include "uima/lowlevel_index.hpp"
#include "uima/lowlevel_indexrepository.hpp"
#include "uima/fsfilterbuilder.hpp"
using namespace std;
using namespace uima::internal;
/* ----------------------------------------------------------------------- */
/* Constants */
/* ----------------------------------------------------------------------- */
/* ----------------------------------------------------------------------- */
/* Forward declarations */
/* ----------------------------------------------------------------------- */
/* ----------------------------------------------------------------------- */
/* Types / Classes */
/* ----------------------------------------------------------------------- */
/* ----------------------------------------------------------------------- */
/* Implementation */
/* ----------------------------------------------------------------------- */
/*
Those implementations are thin wrappers on top of the lowlevel API.
*/
namespace uima {
UIMA_EXC_CLASSIMPLEMENT(InvalidIndexObjectException, CASException);
UIMA_EXC_CLASSIMPLEMENT(WrongFSTypeForIndexException, CASException);
void FSIndex::checkValidity() const {
if (!isValid()) {
UIMA_EXC_THROW_NEW(InvalidIndexObjectException,
UIMA_ERR_INVALID_INDEX_OBJECT,
UIMA_MSG_ID_EXC_INVALID_INDEX_OBJECT,
ErrorMessage(UIMA_MSG_ID_EXCON_UNKNOWN_CONTEXT),
ErrorInfo::recoverable
);
}
}
FSIndex::FSIndex(lowlevel::IndexABase const * anIndex, lowlevel::IndexRepository const & rFSSystem)
: iv_pIndex(anIndex),
iv_indexRepository(& CONST_CAST(uima::lowlevel::IndexRepository &, rFSSystem) ) {}
FSIndex::FSIndex(lowlevel::IndexABase const * anIndex, lowlevel::IndexRepository & rFSSystem)
: iv_pIndex(anIndex),
iv_indexRepository(& rFSSystem) {}
FSIndex::FSIndex()
: iv_pIndex(NULL),
iv_indexRepository(NULL) {}
bool FSIndex::isValid() const {
return(iv_pIndex != NULL) && (iv_indexRepository != NULL);
}
size_t FSIndex::getSize() const {
checkValidity();
return iv_pIndex->getSize();
}
FeatureStructure FSIndex::find(FeatureStructure const & anFS) const {
checkValidity();
if (!anFS.isValid()) {
UIMA_EXC_THROW_NEW(InvalidFSObjectException,
UIMA_ERR_INVALID_FS_OBJECT,
UIMA_MSG_ID_EXC_INVALID_FS_OBJECT,
ErrorMessage(UIMA_MSG_ID_EXCON_FINDING_FS_IN_INDEX),
ErrorInfo::recoverable
);
}
lowlevel::TyFS result = iv_pIndex->find( internal::FSPromoter::demoteFS( anFS ) );
return internal::FSPromoter::promoteFS( result, iv_indexRepository->getCas() );
}
FSIterator FSIndex::iterator() const {
checkValidity();
lowlevel::IndexIterator* it = iv_pIndex->createIterator();
return FSIterator( it, &iv_indexRepository->getCas() );
}
FSIterator FSIndex::typeSetIterator(set<uima::Type> const & crTypes) const {
checkValidity();
uima::lowlevel::TyFSType tyIndexType = iv_pIndex->getType();
set<uima::lowlevel::TyFSType> setLowlevelTypes;
set<uima::Type>::const_iterator cit;
for (cit = crTypes.begin(); cit != crTypes.end(); ++cit) {
uima::lowlevel::TyFSType tyType = uima::internal::FSPromoter::demoteType(*cit);
if ( ! iv_indexRepository->getFSHeap().getTypeSystem().subsumes(tyIndexType, tyType) ) {
UIMA_EXC_THROW_NEW(WrongFSTypeForIndexException,
UIMA_ERR_WRONG_FSTYPE_FOR_INDEX,
UIMA_MSG_ID_EXC_WRONG_FSTYPE_FOR_INDEX,
ErrorMessage(UIMA_MSG_ID_EXCON_CREATING_ITERATOR),
ErrorInfo::recoverable
);
}
setLowlevelTypes.insert(tyType);
}
uima::lowlevel::IndexIterator * it = iv_pIndex->createTypeSetIterator( setLowlevelTypes );
return FSIterator( it, &iv_indexRepository->getCas() );
}
///////////////////////////////////////////////////////////////
/**
* This class wraps an OO API filter to obey the lowlevel::FSFilter interface.
*/
namespace internal {
class FSFilterWrapper : public lowlevel::FSFilter {
private:
uima::FSFilter const * iv_cpFilter;
uima::CAS const * iv_cas;
public:
FSFilterWrapper(uima::FSFilter const * cpFilter, uima::CAS const * cas)
: iv_cpFilter(cpFilter),
iv_cas(cas) {
assert(EXISTS(iv_cpFilter));
assert(EXISTS(iv_cas));
}
bool isFiltered(lowlevel::TyFS anFS) const {
assert(EXISTS(iv_cpFilter));
assert(EXISTS(iv_cas));
// const cast is OK here since anFS will not be changed
// since it is passed as const parameters to isFiltered
FeatureStructure fs = internal::FSPromoter::promoteFS(anFS, *iv_cas);
return iv_cpFilter->isFiltered(fs);
}
};
}
FSIterator FSIndex::filteredIterator(uima::FSFilter const * cpFilter) const {
checkValidity();
internal::FSFilterWrapper* pFilterWrapper = new internal::FSFilterWrapper( cpFilter, & iv_indexRepository->getCas() );
lowlevel::IndexIterator* it = iv_pIndex->createFilteredIterator(pFilterWrapper);
return FSIterator(it, & iv_indexRepository->getCas() );
}
}