blob: fa40b1091088730eeb31eb995186662de65c9de9 [file] [log] [blame]
#ifndef UIMA_CONFIG_TOOLS_HPP
#define UIMA_CONFIG_TOOLS_HPP
/** \file config_tools.hpp .
-----------------------------------------------------------------------------
* 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.
-----------------------------------------------------------------------------
\brief Contains ConfigBase
Description:
-----------------------------------------------------------------------------
Initial creation:
-------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------- */
/* Include dependencies */
/* ----------------------------------------------------------------------- */
#include "uima/pragmas.hpp"
#include "uima/strconvert.hpp" // for string conversion functions
#include "uima/stltools.hpp"
#include "uima/strtools.hpp"
#include "uima/annotator_context.hpp"
/* ----------------------------------------------------------------------- */
/* Constants */
/* ----------------------------------------------------------------------- */
/* ----------------------------------------------------------------------- */
/* Forward declarations */
/* ----------------------------------------------------------------------- */
/* ----------------------------------------------------------------------- */
/* Types / Classes */
/* ----------------------------------------------------------------------- */
namespace uima {
/**
A little helper class to provide to tools you need to be able to
define "constants" in you source code for each config option an
application/annotator accesses.
*/
class UIMA_LINK_IMPORTSPEC ConfigOptionInfo {
public:
/// Enum to be used with struct <TT>StConfigOptionInfo</TT> below
enum EnValueType {
// Integral Number
enValueType_IntegralNumber,
// Real Number
enValueType_RealNumber,
// String
enValueType_String,
// Boolean
enValueType_Boolean
};
/**
This struct can be used by annotators and applications to keep track of
all the options they access in the configuration.
They can create a constant array as a table of of all config options.
Example:
\code
\endcode
*/
typedef struct StOptionInfo_ {
const TCHAR * cpszOptionName;
EnValueType enValueType;
bool bOptionIsMultiValued;
size_t uiNbrOfValuesRequired;
const TCHAR * cpszDefaultValueAsString;
const TCHAR * cpszComment;
}
StOptionInfo;
}
; // ConfigOptionInfo
/**
This function takes an <TT>ConfigOptionInfo::StOptionInfo</TT>
and uses the information in it to extract the value from the
config into the output parameter <TT>rclTargetVariable</TT>.
<TT>crclOptionInfo.bOptionIsMultiValued</TT> is required to be false.
This function should realy be a (template) member function of class
<TT>ConfigOptionInfo</TT> above, but our compiler can't do that right now.
*/
template < class T >
TyErrorId
extractConfigOption(
const AnnotatorContext & crclConfig,
const ConfigOptionInfo::StOptionInfo & crclOptionInfo,
T & rclTargetVariable
) {
return extractConfigOption(crclConfig, NULL, crclOptionInfo, rclTargetVariable);
/* assert(!crclOptionInfo.bOptionIsMultiValued); */
/* // assume the worst */
/* TyErrorId utErrId = UIMA_ERR_CONFIG_SECTION_NOT_FOUND; */
/* assert(crclOptionInfo.uiNbrOfValuesRequired <= 1); */
/* utErrId = crclConfig.extractValue(crclOptionInfo.cpszOptionName, rclTargetVariable); */
/* if (utErrId != UIMA_ERR_NONE) { // could not find option or value(s) */
/* if ( crclOptionInfo.uiNbrOfValuesRequired != 0 */
/* || crclOptionInfo.cpszDefaultValueAsString == NULL) { */
/* // required value not there: return error we got from config */
/* return utErrId; */
/* } */
/* convertFromString((string)crclOptionInfo.cpszDefaultValueAsString, rclTargetVariable); */
/* // we used the provided default: this is not an error so we return OK */
/* utErrId = UIMA_ERR_NONE; */
/* } */
/* return utErrId; */
}
/**
This function takes an <TT>ConfigOptionInfo::StOptionInfo</TT>
and uses the information in it to extract the value from the
config of group <code>crclConfigGroup</code> into the output parameter <TT>rclTargetVariable</TT>.
If <code>crclConfigGroup == NULL</code>, extracts the default value from the config.
<TT>crclOptionInfo.bOptionIsMultiValued</TT> is required to be false.
This function should really be a (template) member function of class
<TT>ConfigOptionInfo</TT> above, but our compiler can't do that right now.
*/
template < class T >
TyErrorId
extractConfigOption(
const AnnotatorContext & crclConfig,
const icu::UnicodeString * cpclConfigGroup,
const ConfigOptionInfo::StOptionInfo & crclOptionInfo,
T & rclTargetVariable
) {
assert(!crclOptionInfo.bOptionIsMultiValued);
// assume the worst
TyErrorId utErrId = UIMA_ERR_CONFIG_SECTION_NOT_FOUND;
assert(crclOptionInfo.uiNbrOfValuesRequired <= 1);
if (EXISTS(cpclConfigGroup)) {
//utErrId = crclConfig.extractValue(crclOptionInfo.cpszOptionName, rclTargetVariable);
utErrId = crclConfig.extractValue(*cpclConfigGroup, crclOptionInfo.cpszOptionName, rclTargetVariable);
} else {
utErrId = crclConfig.extractValue(crclOptionInfo.cpszOptionName, rclTargetVariable);
}
if (utErrId != UIMA_ERR_NONE) { // could not find option or value(s)
if ( crclOptionInfo.uiNbrOfValuesRequired != 0
|| crclOptionInfo.cpszDefaultValueAsString == NULL) {
// required value not there: return error we got from config
return utErrId;
}
convertFromString((std::string)crclOptionInfo.cpszDefaultValueAsString, rclTargetVariable);
// we used the provided default: this is not an error so we return OK
utErrId = UIMA_ERR_NONE;
}
return utErrId;
}
/**
Version of <TT>ExtractConfigOption</TT> for boolean values.
*/
inline TyErrorId
extractConfigOptionBoolean(
const AnnotatorContext & crclConfig,
const ConfigOptionInfo::StOptionInfo & crclOptionInfo,
bool & rclTargetVariable
) {
assert(crclOptionInfo.enValueType == ConfigOptionInfo::enValueType_Boolean);
// BoolValue clBool(rclTargetVariable);
TyErrorId utErrId = extractConfigOption(crclConfig, crclOptionInfo, rclTargetVariable);
// rclTargetVariable = clBool;
return utErrId;
}
/**
Version of <TT>ExtractConfigOption</TT> for boolean values.
*/
inline TyErrorId
extractConfigOptionBoolean(
const AnnotatorContext & crclConfig,
const icu::UnicodeString * cpclConfigGroup ,
const ConfigOptionInfo::StOptionInfo & crclOptionInfo,
bool & rclTargetVariable
) {
assert(crclOptionInfo.enValueType == ConfigOptionInfo::enValueType_Boolean);
// BoolValue clBool(rclTargetVariable);
TyErrorId utErrId = extractConfigOption(crclConfig, cpclConfigGroup, crclOptionInfo, rclTargetVariable);
// rclTargetVariable = clBool;
return utErrId;
}
template < class ContainerType, class ElementType >
TyErrorId
extractConfigOptionListImpl(
const AnnotatorContext & crclConfig,
const ConfigOptionInfo::StOptionInfo & crclOptionInfo,
ContainerType & rclTargetContainer,
ElementType * pElem /*not used, just for type information since ContainerType::value_type does not work with HP compiler*/
) {
return extractConfigOptionListImpl(crclConfig, NULL, crclOptionInfo, rclTargetContainer, pElem);
/* assert(crclOptionInfo.bOptionIsMultiValued); */
/* TyErrorId utErrId = UIMA_ERR_NONE; */
/* size_t i; */
/* #if defined(__HPX_ACC__) || defined(__xlC__) || defined(__GNUC__) */
/* ElementType tTemp; */
/* #else */
/* ContainerType::value_type tTemp; */
/* #endif */
/* */
/* vector<ElementType> elements; */
/* crclConfig.extractValue(crclOptionInfo.cpszOptionName, elements); */
/* for (i=0; i<elements.size(); ++i) { */
/* rclTargetContainer.insert(rclTargetContainer.end(), elements[i]); */
/* } */
/* */
/* if (utErrId != UIMA_ERR_NONE || (elements.size() == 0 )) { // could not find option or value(s) */
/* if ( crclOptionInfo.uiNbrOfValuesRequired != 0 */
/* || crclOptionInfo.cpszDefaultValueAsString == NULL) { */
/* // required value not there: return error we got from config */
/* return utErrId; */
/* } */
/* vector< string > vecTmpStrings; */
/* delimitedString2Vector( */
/* vecTmpStrings, */
/* (string)crclOptionInfo.cpszDefaultValueAsString, */
/* ",", */
/* true, // trim strings */
/* false // insert empty strings */
/* ); */
/* // our default value too must have the required nbr of values */
/* assert(vecTmpStrings.size() >= crclOptionInfo.uiNbrOfValuesRequired); */
/* */
/* for (i = 0; i < vecTmpStrings.size(); ++i) { */
/* convertFromString(vecTmpStrings[i], tTemp); */
/* // assumes rclTargetContainer to be an STL container */
/* rclTargetContainer.insert(rclTargetContainer.end(), tTemp); */
/* } */
/* } */
/* if (i < crclOptionInfo.uiNbrOfValuesRequired) { */
/* taph 8/6/1999: ?? maybe we should have a more precise error id: */
/* UIMA_ERR_CONFIG_REQUIRED_OPTION_HAS_NOT_ENOUGH_VALUES */
/* */
/* return UIMA_ERR_CONFIG_REQUIRED_OPTION_IS_EMPTY; */
/* } */
/* return utErrId; */
}
template < class ContainerType, class ElementType >
TyErrorId
extractConfigOptionListImpl(
const AnnotatorContext & crclConfig,
const icu::UnicodeString * cpclConfigGroup,
const ConfigOptionInfo::StOptionInfo & crclOptionInfo,
ContainerType & rclTargetContainer,
ElementType * /*not used, just for type information since ContainerType::value_type does not work with HP compiler*/
) {
assert(crclOptionInfo.bOptionIsMultiValued);
TyErrorId utErrId = UIMA_ERR_NONE;
size_t i;
#if defined(__HPX_ACC__) || defined(__xlC__) || defined(__GNUC__)
ElementType tTemp;
#else
ContainerType::value_type tTemp;
#endif
#if defined(__SUNPRO_CC)
std::vector<ContainerType::value_type> elements;
#else
std::vector<ElementType> elements;
#endif
if (EXISTS(cpclConfigGroup)) {
crclConfig.extractValue(*cpclConfigGroup, crclOptionInfo.cpszOptionName, elements);
} else {
crclConfig.extractValue(crclOptionInfo.cpszOptionName, elements);
}
for (i=0; i<elements.size(); ++i) {
rclTargetContainer.insert(rclTargetContainer.end(), elements[i]);
}
if (utErrId != UIMA_ERR_NONE || (elements.size() == 0 )) { // could not find option or value(s)
if ( crclOptionInfo.uiNbrOfValuesRequired != 0
|| crclOptionInfo.cpszDefaultValueAsString == NULL) {
// required value not there: return error we got from config
return utErrId;
}
std::vector< std::string > vecTmpStrings;
delimitedString2Vector(
vecTmpStrings,
(std::string)crclOptionInfo.cpszDefaultValueAsString,
",",
true, // trim strings
false // insert empty strings
);
// our default value too must have the required nbr of values
assert(vecTmpStrings.size() >= crclOptionInfo.uiNbrOfValuesRequired);
for (i = 0; i < vecTmpStrings.size(); ++i) {
convertFromString(vecTmpStrings[i], tTemp);
// assumes rclTargetContainer to be an STL container
rclTargetContainer.insert(rclTargetContainer.end(), tTemp);
}
}
if (i < crclOptionInfo.uiNbrOfValuesRequired) {
/* taph 8/6/1999: ?? maybe we should have a more precise error id:
UIMA_ERR_CONFIG_REQUIRED_OPTION_HAS_NOT_ENOUGH_VALUES
*/
return UIMA_ERR_CONFIG_REQUIRED_OPTION_IS_EMPTY;
}
return utErrId;
}
/**
This function takes an <TT>ConfigOptionInfo::StOptionInfo</TT>
and uses the information in it to extract multiple values from the
config into the output parameter <TT>rclTargetContainer</TT>.
This works for config values with more than one value.
<TT>rclTargetContainer</TT> is assumed to be an STL container.
<TT>crclOptionInfo.bOptionIsMultiValued</TT> is required to be true.
This function should realy be a (template) member function of class
<TT>ConfigOptionInfo</TT> above, but our compiler can't do that right now.
*/
template < class ContainerType >
inline TyErrorId
extractConfigOptionList(
const AnnotatorContext & crclConfig,
const ConfigOptionInfo::StOptionInfo & crclOptionInfo,
ContainerType & rclTargetContainer
) {
return extractConfigOptionListImpl(crclConfig, crclOptionInfo, rclTargetContainer, STL_ITER2PTR(rclTargetContainer.begin()));
}
/**
This function takes an <TT>ConfigOptionInfo::StOptionInfo</TT>
and uses the information in it to extract multiple values from the
config of group <code>crclConfigGroup</code> into the output parameter <TT>rclTargetContainer</TT>.
This works for config values with more than one value.
<TT>rclTargetContainer</TT> is assumed to be an STL container.
<TT>crclOptionInfo.bOptionIsMultiValued</TT> is required to be true.
This function should realy be a (template) member function of class
<TT>ConfigOptionInfo</TT> above, but our compiler can't do that right now.
*/
template < class ContainerType >
inline TyErrorId
extractConfigOptionList(
const AnnotatorContext & crclConfig,
const icu::UnicodeString * cpclConfigGroup,
const ConfigOptionInfo::StOptionInfo & crclOptionInfo,
ContainerType & rclTargetContainer
) {
return extractConfigOptionListImpl(crclConfig, cpclConfigGroup, crclOptionInfo, rclTargetContainer, STL_ITER2PTR(rclTargetContainer.begin()));
}
}
#endif /* UIMA_CONFIG_TOOLS_HPP */
/* <EOF> */