src/cas/fsfilterbuilder.cpp (232 lines of code) (raw):

/** \file filterbuilder.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/fsfilterbuilder.hpp" #include "uima/fsindex.hpp" #include "uima/internal_fspromoter.hpp" /* ----------------------------------------------------------------------- */ /* Constants */ /* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */ /* Forward declarations */ /* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */ /* Types / Classes */ /* ----------------------------------------------------------------------- */ /* Here are straightforward implementations of FSFilters. Nothing exciting. */ using namespace std; namespace uima { namespace internal { ////////////////////////////////////////////////////// class NOTFilter : public FSFilter { private: FSFilter * iv_pFilter; public: NOTFilter(FSFilter* pFilter) : iv_pFilter(pFilter) { assert(EXISTS(iv_pFilter)); } bool isFiltered(FeatureStructure const & fs) const { assert(EXISTS(iv_pFilter)); return ! iv_pFilter->isFiltered(fs); } void deInit() { assert(EXISTS(iv_pFilter)); iv_pFilter->deInit(); delete iv_pFilter; } }; ////////////////////////////////////////////////////// class BoolBinaryOperationFilter : public FSFilter { protected: FSFilter * iv_pFilter1; FSFilter * iv_pFilter2; BoolBinaryOperationFilter(FSFilter * pFilter1, FSFilter * pFilter2) : iv_pFilter1(pFilter1), iv_pFilter2(pFilter2) { assert(EXISTS(iv_pFilter1)); assert(EXISTS(iv_pFilter2)); } public: void deInit() { assert(EXISTS(iv_pFilter1)); iv_pFilter1->deInit(); delete iv_pFilter1; assert(EXISTS(iv_pFilter2)); iv_pFilter2->deInit(); delete iv_pFilter2; } }; ////////////////////////////////////////////////////// class ANDFilter : public BoolBinaryOperationFilter { public: ANDFilter(FSFilter * pFilter1, FSFilter * pFilter2) : BoolBinaryOperationFilter(pFilter1, pFilter2) {} bool isFiltered(FeatureStructure const & fs) const { assert(EXISTS(iv_pFilter1)); assert(EXISTS(iv_pFilter2)); // ensure that filter 2 is not used when filter 1 already returns false bool bResult1 = iv_pFilter1->isFiltered(fs); if (!bResult1) { return false; } // cerr << __FILE__ << ", " << __LINE__ << ": value of filter1: " << iv_pFilter1->isFiltered(fs) << ", value of filter2: " << iv_pFilter2->isFiltered(fs) << endl; return iv_pFilter2->isFiltered(fs); } }; ////////////////////////////////////////////////////// class ORFilter : public BoolBinaryOperationFilter { public: ORFilter(FSFilter * pFilter1, FSFilter * pFilter2) : BoolBinaryOperationFilter(pFilter1, pFilter2) {} bool isFiltered(FeatureStructure const & fs) const { assert(EXISTS(iv_pFilter1)); assert(EXISTS(iv_pFilter2)); bool bResult1 = iv_pFilter1->isFiltered(fs); if (bResult1) { return true; } return iv_pFilter2->isFiltered(fs); } }; ////////////////////////////////////////////////////// class TypeFilter : public FSFilter { private: Type iv_type; bool iv_bUseSusumption; public: TypeFilter(Type const & crType, bool bUseSubsumption) : iv_type(crType), iv_bUseSusumption(bUseSubsumption) {} bool isFiltered(FeatureStructure const & fs) const { if (iv_bUseSusumption) { return iv_type.subsumes(fs.getType()); } return iv_type == fs.getType(); } }; ////////////////////////////////////////////////////// FeatureStructure getPath(FeatureStructure const & crFS, vector<Feature> const & crFeatures, size_t uiStep) { FeatureStructure result = crFS; size_t i; for (i=0; i<uiStep; ++i) { result = result.getFSValue(crFeatures[i]); } return result; } ////////////////////////////////////////////////////// template<class T> class BuiltinFeatureValueFilter : public FSFilter { private: vector<Feature> iv_features; FSFilterBuilder::EnComparisonOperator iv_enOp; T iv_val; bool compare(FSFilterBuilder::EnComparisonOperator enOp, T val1, T val2) const { switch (enOp) { case FSFilterBuilder::EQUALS: return val1 == val2; case FSFilterBuilder::GREATER: return val1 > val2; case FSFilterBuilder::LESS: return val1 < val2; }; assert(false); return false; } protected: virtual T getFeature(FeatureStructure const &, Feature const &) const = 0; public: BuiltinFeatureValueFilter(vector<Feature> const & crFeatures, FSFilterBuilder::EnComparisonOperator enOp, T val) : iv_features(crFeatures), iv_enOp(enOp), iv_val(val) {} bool isFiltered(FeatureStructure const & crFS) const { size_t uiLast = iv_features.size() - 1; FeatureStructure fs = getPath(crFS, iv_features, uiLast); T val = getFeature(fs, iv_features[uiLast]); return compare(iv_enOp, val, iv_val); } }; ////////////////////////////////////////////////////// class IntFeatureFilter : public BuiltinFeatureValueFilter<int> { protected: int getFeature(FeatureStructure const & crFS, Feature const & crFeat) const { return crFS.getIntValue(crFeat); } public: IntFeatureFilter(vector<Feature> const & crFeatures, FSFilterBuilder::EnComparisonOperator enOp, int val) : BuiltinFeatureValueFilter<int>(crFeatures, enOp, val) {} }; ////////////////////////////////////////////////////// class FloatFeatureFilter : public BuiltinFeatureValueFilter<float> { protected: float getFeature(FeatureStructure const & crFS, Feature const & crFeat) const { return crFS.getFloatValue(crFeat); } public: FloatFeatureFilter(vector<Feature> const & crFeatures, FSFilterBuilder::EnComparisonOperator enOp, float val) : BuiltinFeatureValueFilter<float>(crFeatures, enOp, val) {} }; ///////////////////////////////////////////////////////////// class UnicodeStringRefFeatureFilter : public BuiltinFeatureValueFilter<UnicodeStringRef> { protected: UnicodeStringRef getFeature(FeatureStructure const & crFS, Feature const & crFeat) const { return crFS.getStringValue(crFeat); } public: UnicodeStringRefFeatureFilter(vector<Feature> const & crFeaturePath, UnicodeStringRef const & crUStr) : BuiltinFeatureValueFilter<UnicodeStringRef>(crFeaturePath, FSFilterBuilder::EQUALS, crUStr ) {} }; class StringFeatureFilter : public FSFilter { private: UnicodeStringRefFeatureFilter * iv_pUnicodeStringRefFeatureFilter; icu::UnicodeString iv_string; public: StringFeatureFilter(vector<Feature> const & crFeaturePath, UChar const * cpUTFBuffer, size_t uiLength) : iv_pUnicodeStringRefFeatureFilter(NULL) { iv_string = icu::UnicodeString( cpUTFBuffer, uiLength ); UnicodeStringRef up(iv_string.getBuffer(), iv_string.length() ); iv_pUnicodeStringRefFeatureFilter = new UnicodeStringRefFeatureFilter(crFeaturePath, up); assert( EXISTS( iv_pUnicodeStringRefFeatureFilter ) ); } ~StringFeatureFilter() { if (iv_pUnicodeStringRefFeatureFilter != NULL) { delete iv_pUnicodeStringRefFeatureFilter; iv_pUnicodeStringRefFeatureFilter = NULL; } } virtual bool isFiltered(FeatureStructure const &crFS) const { assert( EXISTS( iv_pUnicodeStringRefFeatureFilter ) ); return iv_pUnicodeStringRefFeatureFilter->isFiltered(crFS); } virtual void deInit() { assert( EXISTS( iv_pUnicodeStringRefFeatureFilter ) ); iv_pUnicodeStringRefFeatureFilter->deInit(); } }; ////////////////////////////////////////////////////// class MatchFilter : public FSFilter { private: vector<Feature> iv_features; FSFilter * iv_pFilter; public: MatchFilter(vector<Feature> const & crFeaturePath, FSFilter * pFilter) : iv_features(crFeaturePath), iv_pFilter(pFilter) { assert(EXISTS(iv_pFilter)); } bool isFiltered(FeatureStructure const & crFS) const { FeatureStructure fs = getPath(crFS, iv_features, iv_features.size()); assert(EXISTS(iv_pFilter)); return iv_pFilter->isFiltered(fs); } void deInit() { assert(EXISTS(iv_pFilter)); iv_pFilter->deInit(); delete iv_pFilter; } }; } } // namespace uima /* ----------------------------------------------------------------------- */ /* Implementation */ /* ----------------------------------------------------------------------- */ namespace uima { FSFilterBuilder::FSFilterBuilder() {} FSFilterBuilder::~FSFilterBuilder() {} FSFilter * FSFilterBuilder::createNOTFilter(FSFilter * pFilter) const { return new internal::NOTFilter(pFilter); } FSFilter * FSFilterBuilder::createANDFilter(FSFilter * pFilter1, FSFilter * pFilter2) const { return new internal::ANDFilter(pFilter1, pFilter2); } FSFilter * FSFilterBuilder::createORFilter(FSFilter * pFilter1, FSFilter * pFilter2) const { return new internal::ORFilter(pFilter1, pFilter2); } FSFilter * FSFilterBuilder::createTypeFilter(Type const & crType, bool bUseSubsumption) const { return new internal::TypeFilter(crType, bUseSubsumption); } FSFilter * FSFilterBuilder::createIntFeatureFilter(vector<Feature> const & crFeatures, EnComparisonOperator enOp, int iVal) const { return new internal::IntFeatureFilter(crFeatures, enOp, iVal); } FSFilter * FSFilterBuilder::createFloatFeatureFilter(vector<Feature> const & crFeatures, EnComparisonOperator enOp, float fVal) const { return new internal::FloatFeatureFilter(crFeatures, enOp, fVal); } FSFilter * FSFilterBuilder::createMatchFilter(vector<Feature> const & crFeaturePath, FSFilter * pFilter) const { return new internal::MatchFilter(crFeaturePath, pFilter); } FSFilter * FSFilterBuilder::createStringFeatureFilter(vector<Feature> const & crFeaturePath, UChar const * cpUTFBuffer, size_t uiLength) const { return new internal::StringFeatureFilter(crFeaturePath, cpUTFBuffer, uiLength); } } // namespace uima /* ----------------------------------------------------------------------- */