blob: a8cbbe4f30fa5ae1a5c561737b36599a190d130c [file] [log] [blame]
/*
* 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.
*/
#if !defined(XPATHFUNCTIONTABLE_HEADER_GUARD_1357924680)
#define XPATHFUNCTIONTABLE_HEADER_GUARD_1357924680
// Base include file. Must be first.
#include <xalanc/XPath/XPathDefinitions.hpp>
#include <algorithm>
#include <xalanc/XalanDOM/XalanDOMString.hpp>
#include <xalanc/Include/STLHelper.hpp>
#include <xalanc/XPath/Function.hpp>
#include <xalanc/XPath/XalanXPathException.hpp>
namespace XALAN_CPP_NAMESPACE {
/**
* Exception class thrown when an unknown function is encountered
*/
class XALAN_XPATH_EXPORT XPathExceptionFunctionNotAvailable : public XalanXPathException
{
public:
typedef Function::LocatorType LocatorType;
XPathExceptionFunctionNotAvailable(
const XalanDOMString& theFunctionName,
XalanDOMString& theResult,
const Locator* theLocator);
XPathExceptionFunctionNotAvailable(const XPathExceptionFunctionNotAvailable& other);
~XPathExceptionFunctionNotAvailable();
};
/**
* Exception class thrown when an installFunction() is called with a
* function name that is not supported.
*/
class XALAN_XPATH_EXPORT XPathExceptionFunctionNotSupported : public XalanXPathException
{
public:
XPathExceptionFunctionNotSupported(
const XalanDOMChar* theFunctionName,
XalanDOMString& theResult,
const Locator* theLocator);
XPathExceptionFunctionNotSupported(const XPathExceptionFunctionNotSupported& other);
~XPathExceptionFunctionNotSupported();
};
/**
* Class defines a table of functions that can be called in XPath expresions.
*/
class XALAN_XPATH_EXPORT XPathFunctionTable
{
public:
enum { InvalidFunctionNumberID = -1, TableSize = 36 };
typedef size_t SizeType;
typedef XalanDOMString::size_type StringSizeType;
typedef DeleteFunctor<Function> DeleteFunctorType;
/**
* Constructor.
*
* @param fCreateTable If true, the internal table will be created. Otherwise, CreateTable() must be called.
*/
XPathFunctionTable(bool fCreateTable = true);
~XPathFunctionTable();
void
setMemoryManager(MemoryManager& theManager)
{
m_memoryManager = &theManager;
}
/**
* Set up the internal table.
*/
void
CreateTable();
/**
* Destroy the internal table.
*/
void
DestroyTable();
/**
* Retrieve the function object for a specified function name. If
* the named Function is not found, an exception is thrown.
*
* @param theFunctionName The name of function
* @param theLocator The Locator instance to use when reporting an error.
* @return function named
*/
const Function&
get(
const XalanDOMString& theFunctionName,
const Locator* theLocator) const
{
const int theFunctionID =
getFunctionIndex(theFunctionName);
if (theFunctionID != InvalidFunctionNumberID)
{
return *m_functionTable[theFunctionID];
}
else
{
MemoryManager* const theManager = m_memoryManager;
XalanDOMString theResult(*theManager);
throw XPathExceptionFunctionNotAvailable(
theFunctionName,
theResult,
theLocator);
}
}
private:
/**
* Retrieve the function object for a specified function name.
*
* @deprecated This operator is deprecated.
* @param theFunctionName name of function
* @return function named
*/
const Function&
operator[](const XalanDOMString& theFunctionName) const
{
const int theFunctionID =
getFunctionIndex(theFunctionName);
if (theFunctionID != InvalidFunctionNumberID)
{
return *m_functionTable[theFunctionID];
}
else
{
MemoryManager* const theManager = m_memoryManager;
XalanDOMString theResult(*theManager);
throw XPathExceptionFunctionNotAvailable(
theFunctionName,
theResult,
0);
}
}
public:
/**
* Retrieve the function object for a specified function ID number.
*
* @param theFunctionID ID number of the function
* @return function named
*/
const Function&
operator[](int theFunctionID) const
{
assert(theFunctionID >= 0 && theFunctionID < TableSize);
assert(m_functionTable[theFunctionID] != 0);
return *m_functionTable[theFunctionID];
}
/**
* Map a function ID to the corresponding name.
*
* @param theFunctionID The ID number of the function
* @return The name of the function, or an empty string if the function doesn't exist.
*/
const XalanDOMString&
idToName(int theFunctionID,
XalanDOMString& theResult) const
{
if (theFunctionID >= 0 && theFunctionID < TableSize)
{
theResult.assign(
s_functionNames[theFunctionID].m_name,
s_functionNames[theFunctionID].m_size);
}
return theResult;
}
/**
* Map a function name to the corresponding ID number.
*
* @param theName name of function
* @return The ID number of function, or InvalidFunctionNumberID if the function doesn't exist.
*/
int
nameToID(const XalanDOMString& theName) const
{
return getFunctionIndex(theName);
}
/**
* Insert a named function into the function table.
*
* @param theFunctionName name of function
* @param theFunction function object corresponding to name
*/
void
InstallFunction(
const XalanDOMString& theFunctionName,
const Function& theFunction)
{
InstallFunction(theFunctionName.c_str(), theFunction);
}
/**
* Remove a named function from the function table.
*
* @param theFunctionName name of function
* @return true if the function was found and removed.
*/
bool
UninstallFunction(const XalanDOMString& theFunctionName)
{
return UninstallFunction(theFunctionName.c_str());
}
/**
* Insert a named function into the function table.
*
* @param theFunctionName name of function
* @param theFunction function object corresponding to name
*/
void
InstallFunction(
const XalanDOMChar* theFunctionName,
const Function& theFunction);
/**
* Remove a named function from the function table.
*
* @param theFunctionName name of function
* @return true if the function was found and removed.
*/
bool
UninstallFunction(const XalanDOMChar* theFunctionName);
/**
* Whether a named function is in the function table.
*
* @param theFunctionName name of function
* @return true if function is in table
*/
bool
isInstalledFunction(const XalanDOMString& theFunctionName) const
{
return getFunctionIndex(theFunctionName) != InvalidFunctionNumberID ? true : false;
}
/**
* Add a list of the names of installed functions to a vector of names.
*
* @param theIterator function table iterator to append names to
*/
template<class OutputIteratorType>
void
getInstalledFunctionNames(OutputIteratorType theIterator) const
{
XalanDOMString theString(XalanMemMgrs::getDefaultXercesMemMgr());
for (int i = 0; i < TableSize; ++i)
{
if (m_functionTable[i] != 0)
{
theString.assign(
s_functionNames[i].m_name,
s_functionNames[i].m_size);
*theIterator = theString;
++theIterator;
}
}
}
struct FunctionNameTableEntry
{
const XalanDOMChar* m_name;
StringSizeType m_size;
};
// These are static strings for the functions supported.
// Note that the XSLT functions are also here, since it's
// just easier to do it this way.
// The string "id"
static const XalanDOMChar s_id[];
// The string "key"
static const XalanDOMChar s_key[];
// The string "not"
static const XalanDOMChar s_not[];
// The string "sum"
static const XalanDOMChar s_sum[];
// The string "lang"
static const XalanDOMChar s_lang[];
// The string "last"
static const XalanDOMChar s_last[];
// The string "name"
static const XalanDOMChar s_name[];
// The string "true"
static const XalanDOMChar s_true[];
// The string "count"
static const XalanDOMChar s_count[];
// The string "false"
static const XalanDOMChar s_false[];
// The string "floor"
static const XalanDOMChar s_floor[];
// The string "round"
static const XalanDOMChar s_round[];
// The string "concat"
static const XalanDOMChar s_concat[];
// The string "number"
static const XalanDOMChar s_number[];
// The string "string"
static const XalanDOMChar s_string[];
// The string "boolean"
static const XalanDOMChar s_boolean[];
// The string "ceiling"
static const XalanDOMChar s_ceiling[];
// The string "current"
static const XalanDOMChar s_current[];
// The string "contains"
static const XalanDOMChar s_contains[];
// The string "document"
static const XalanDOMChar s_document[];
// The string "position"
static const XalanDOMChar s_position[];
// The string "substring"
static const XalanDOMChar s_substring[];
// The string "translate"
static const XalanDOMChar s_translate[];
// The string "local-name"
static const XalanDOMChar s_localName[];
// The string "generate-id"
static const XalanDOMChar s_generateId[];
// The string "starts-with"
static const XalanDOMChar s_startsWith[];
// The string "format-number"
static const XalanDOMChar s_formatNumber[];
// The string "namespace-uri"
static const XalanDOMChar s_namespaceUri[];
// The string "string-length"
static const XalanDOMChar s_stringLength[];
// The string "normalize-space"
static const XalanDOMChar s_normalizeSpace[];
// The string "substring-after"
static const XalanDOMChar s_substringAfter[];
// The string "system-property"
static const XalanDOMChar s_systemProperty[];
// The string "substring-before"
static const XalanDOMChar s_substringBefore[];
// The string "element-available"
static const XalanDOMChar s_elementAvailable[];
// The string "function-available"
static const XalanDOMChar s_functionAvailable[];
// The string "unparsed-entity-uri"
static const XalanDOMChar s_unparsedEntityUri[];
// A table of function names.
static const FunctionNameTableEntry s_functionNames[];
// The size of the table.
static const SizeType s_functionNamesSize;
private:
static int
getFunctionIndex(const XalanDOMString& theName)
{
return getFunctionIndex(
theName.c_str(),
theName.length());
}
static int
getFunctionIndex(const XalanDOMChar* theName)
{
return getFunctionIndex(
theName,
XalanDOMString::length(theName));
}
static int
getFunctionIndex(
const XalanDOMChar* theName,
StringSizeType theNameLength);
MemoryManager* m_memoryManager;
const Function* m_functionTable[TableSize];
const Function** const m_functionTableEnd;
// The last one in the table of function names.
static const FunctionNameTableEntry* const s_lastFunctionName;
};
}
#endif // XPATHFUNCTIONTABLE_HEADER_GUARD_1357924680