blob: 528529b5485daa57cb377ed1ad84b352dd2efe90 [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.
*/
// Class header file...
#include "XPathExecutionContextDefault.hpp"
#include <xercesc/sax/Locator.hpp>
#include <xalanc/Include/STLHelper.hpp>
#include <xalanc/PlatformSupport/PrefixResolver.hpp>
#include <xalanc/PlatformSupport/XalanLocator.hpp>
#include <xalanc/PlatformSupport/DoubleSupport.hpp>
#include <xalanc/PlatformSupport/DOMStringHelper.hpp>
#include <xalanc/PlatformSupport/XalanDecimalFormatSymbols.hpp>
#include <xalanc/PlatformSupport/XalanMessageLoader.hpp>
#include <xalanc/DOMSupport/DOMSupport.hpp>
#include "XObjectFactory.hpp"
#include "XalanQName.hpp"
#include "XPathEnvSupport.hpp"
namespace XALAN_CPP_NAMESPACE {
const NodeRefList XPathExecutionContextDefault::s_dummyList(XalanMemMgrs::getDummyMemMgr());
XPathExecutionContextDefault::XPathExecutionContextDefault(
XPathEnvSupport& theXPathEnvSupport,
DOMSupport& theDOMSupport,
XObjectFactory& theXObjectFactory,
XalanNode* theCurrentNode,
const NodeRefListBase* theContextNodeList,
const PrefixResolver* thePrefixResolver) :
XPathExecutionContext(theXObjectFactory.getMemoryManager(), &theXObjectFactory),
m_xpathEnvSupport(&theXPathEnvSupport),
m_domSupport(&theDOMSupport),
m_currentNodeStack(theXObjectFactory.getMemoryManager()),
m_contextNodeListStack(theXObjectFactory.getMemoryManager()),
m_prefixResolver(thePrefixResolver),
m_currentPattern(theXObjectFactory.getMemoryManager()),
m_nodeListCache(theXObjectFactory.getMemoryManager(), eNodeListCacheListSize),
m_stringCache(theXObjectFactory.getMemoryManager()),
m_cachedPosition(),
m_scratchQName(theXObjectFactory.getMemoryManager())
{
m_currentNodeStack.push_back(theCurrentNode);
m_contextNodeListStack.push_back(theContextNodeList == 0 ? &s_dummyList : theContextNodeList);
}
XPathExecutionContextDefault::XPathExecutionContextDefault(
MemoryManager& theManager,
XalanNode* theCurrentNode,
const NodeRefListBase* theContextNodeList,
const PrefixResolver* thePrefixResolver) :
XPathExecutionContext(theManager),
m_xpathEnvSupport(0),
m_domSupport(0),
m_currentNodeStack(theManager),
m_contextNodeListStack(theManager),
m_prefixResolver(thePrefixResolver),
m_currentPattern(theManager),
m_nodeListCache(theManager, eNodeListCacheListSize),
m_stringCache(theManager),
m_cachedPosition(),
m_scratchQName(theManager)
{
m_currentNodeStack.push_back(theCurrentNode);
m_contextNodeListStack.push_back(theContextNodeList == 0 ? &s_dummyList : theContextNodeList);
}
XPathExecutionContextDefault*
XPathExecutionContextDefault::create(
MemoryManager& theManager,
XalanNode* theCurrentNode,
const NodeRefListBase* theContextNodeList,
const PrefixResolver* thePrefixResolver)
{
typedef XPathExecutionContextDefault ThisType;
XalanAllocationGuard theGuard(theManager, theManager.allocate(sizeof(ThisType)));
ThisType* const theResult =
new (theGuard.get()) ThisType(
theManager,
theCurrentNode,
theContextNodeList,
thePrefixResolver);
theGuard.release();
return theResult;
}
XPathExecutionContextDefault::~XPathExecutionContextDefault()
{
reset();
}
void
XPathExecutionContextDefault::problem(
eSource source,
eClassification classification,
const XalanDOMString& msg,
const Locator* locator,
const XalanNode* sourceNode)
{
m_xpathEnvSupport->problem(
source,
classification,
msg,
locator,
sourceNode);
}
void
XPathExecutionContextDefault::problem(
eSource source,
eClassification classification,
const XalanDOMString& msg,
const XalanNode* sourceNode)
{
m_xpathEnvSupport->problem(
source,
classification,
msg,
sourceNode);
}
void
XPathExecutionContextDefault::reset()
{
if (m_xpathEnvSupport != 0)
{
m_xpathEnvSupport->reset();
}
if (m_domSupport != 0)
{
m_domSupport->reset();
}
if (m_xobjectFactory != 0)
{
m_xobjectFactory->reset();
}
m_currentNodeStack.clear();
m_currentNodeStack.push_back(0);
m_contextNodeListStack.clear();
m_contextNodeListStack.push_back(&s_dummyList);
m_prefixResolver = 0;
m_nodeListCache.reset(),
m_stringCache.reset();
m_cachedPosition.clear();
}
XalanNode*
XPathExecutionContextDefault::getCurrentNode() const
{
assert(m_currentNodeStack.empty() == false);
return m_currentNodeStack.back();
}
void
XPathExecutionContextDefault::pushCurrentNode(XalanNode* theCurrentNode)
{
m_currentNodeStack.push_back(theCurrentNode);
}
void
XPathExecutionContextDefault::popCurrentNode()
{
assert(m_currentNodeStack.empty() == false);
m_currentNodeStack.pop_back();
}
bool
XPathExecutionContextDefault::isNodeAfter(
const XalanNode& node1,
const XalanNode& node2) const
{
return m_domSupport->isNodeAfter(node1, node2);
}
void
XPathExecutionContextDefault::pushContextNodeList(const NodeRefListBase& theList)
{
m_cachedPosition.clear();
m_contextNodeListStack.push_back(&theList);
}
void
XPathExecutionContextDefault::popContextNodeList()
{
m_cachedPosition.clear();
m_contextNodeListStack.pop_back();
}
const NodeRefListBase&
XPathExecutionContextDefault::getContextNodeList() const
{
assert(m_contextNodeListStack.empty() == false);
return *m_contextNodeListStack.back();
}
XPathExecutionContextDefault::size_type
XPathExecutionContextDefault::getContextNodeListLength() const
{
assert(m_contextNodeListStack.empty() == false);
return m_contextNodeListStack.back()->getLength();
}
XPathExecutionContextDefault::size_type
XPathExecutionContextDefault::getContextNodeListPosition(const XalanNode& contextNode) const
{
assert(m_contextNodeListStack.empty() == false);
if (m_cachedPosition.m_node == &contextNode)
{
assert((m_cachedPosition.m_index == 0 && m_contextNodeListStack.back()->indexOf(&contextNode) == NodeRefListBase::npos) ||
(m_contextNodeListStack.back()->indexOf(&contextNode) + 1 == m_cachedPosition.m_index));
}
else
{
// Get the index of the node...
const size_type theIndex = m_contextNodeListStack.back()->indexOf(&contextNode);
// If not found, it's 0. Otherwise, it's the index + 1
m_cachedPosition.m_index = theIndex == NodeRefListBase::npos ? 0 : theIndex + 1;
m_cachedPosition.m_node = &contextNode;
}
return m_cachedPosition.m_index;
}
bool
XPathExecutionContextDefault::elementAvailable(const XalanQName& theQName) const
{
assert(m_xpathEnvSupport != 0);
return m_xpathEnvSupport->elementAvailable(theQName.getNamespace(), theQName.getLocalPart());
}
bool
XPathExecutionContextDefault::elementAvailable(
const XalanDOMString& theName,
const Locator* theLocator) const
{
assert(m_xpathEnvSupport != 0);
XalanQNameByValue& theQName = getScratchQName();
theQName.set(theName, m_prefixResolver, theLocator);
return elementAvailable(m_scratchQName);
}
bool
XPathExecutionContextDefault::functionAvailable(const XalanQName& theQName) const
{
assert(m_xpathEnvSupport != 0);
return m_xpathEnvSupport->functionAvailable(theQName.getNamespace(), theQName.getLocalPart());
}
bool
XPathExecutionContextDefault::functionAvailable(
const XalanDOMString& theName,
const Locator* theLocator) const
{
assert(m_xpathEnvSupport != 0);
XalanQNameByValue& theQName = getScratchQName();
theQName.set(theName, m_prefixResolver, theLocator);
return functionAvailable(theQName);
}
const XObjectPtr
XPathExecutionContextDefault::extFunction(
const XalanDOMString& theNamespace,
const XalanDOMString& functionName,
XalanNode* context,
const XObjectArgVectorType& argVec,
const Locator* locator)
{
assert(m_xpathEnvSupport != 0);
return m_xpathEnvSupport->extFunction(
*this,
theNamespace,
functionName,
context,
argVec,
locator);
}
XalanDocument*
XPathExecutionContextDefault::parseXML(
MemoryManager& theManager,
const XalanDOMString& urlString,
const XalanDOMString& base,
ErrorHandler* theErrorHandler) const
{
assert(m_xpathEnvSupport != 0);
return m_xpathEnvSupport->parseXML(
theManager,
urlString,
base,
theErrorHandler);
}
MutableNodeRefList*
XPathExecutionContextDefault::borrowMutableNodeRefList()
{
return m_nodeListCache.get();
}
bool
XPathExecutionContextDefault::returnMutableNodeRefList(MutableNodeRefList* theList)
{
return m_nodeListCache.release(theList);
}
MutableNodeRefList*
XPathExecutionContextDefault::createMutableNodeRefList(MemoryManager& theManager) const
{
return MutableNodeRefList::create(theManager);
}
XalanDOMString&
XPathExecutionContextDefault::getCachedString()
{
return m_stringCache.get();
}
bool
XPathExecutionContextDefault::releaseCachedString(XalanDOMString& theString)
{
return m_stringCache.release(theString);
}
void
XPathExecutionContextDefault::getNodeSetByKey(
XalanNode* /* context */,
const XalanQName& /* qname */,
const XalanDOMString& /* ref */,
const Locator* const /* locator */,
MutableNodeRefList& /* nodelist */)
{
}
void
XPathExecutionContextDefault::getNodeSetByKey(
XalanNode* /* context */,
const XalanDOMString& /* name */,
const XalanDOMString& /* ref */,
const Locator* const /* locator */,
MutableNodeRefList& /* nodelist */)
{
}
const XObjectPtr
XPathExecutionContextDefault::getVariable(
const XalanQName& name,
const Locator* const /* locator */)
{
assert(m_xobjectFactory != 0);
return m_xobjectFactory->createUnknown(name.getLocalPart());
}
const PrefixResolver*
XPathExecutionContextDefault::getPrefixResolver() const
{
return m_prefixResolver;
}
void
XPathExecutionContextDefault::setPrefixResolver(const PrefixResolver* thePrefixResolver)
{
m_prefixResolver = thePrefixResolver;
}
const XalanDOMString*
XPathExecutionContextDefault::getNamespaceForPrefix(const XalanDOMString& prefix) const
{
assert(m_prefixResolver != 0);
return m_prefixResolver->getNamespaceForPrefix(prefix);
}
const XalanDOMString&
XPathExecutionContextDefault::findURIFromDoc(const XalanDocument* owner) const
{
assert(m_xpathEnvSupport != 0);
return m_xpathEnvSupport->findURIFromDoc(owner);
}
const XalanDOMString&
XPathExecutionContextDefault::getUnparsedEntityURI(
const XalanDOMString& theName,
const XalanDocument& theDocument) const
{
return m_domSupport->getUnparsedEntityURI(theName, theDocument);
}
bool
XPathExecutionContextDefault::shouldStripSourceNode(const XalanText& /* node */)
{
return false;
}
void
XPathExecutionContextDefault::error(
const XalanDOMString& msg,
const XalanNode* sourceNode,
const Locator* locator) const
{
assert(m_xpathEnvSupport != 0);
m_xpathEnvSupport->problem(
XPathEnvSupport::eXPATH,
XPathEnvSupport::eError,
msg,
locator,
sourceNode);
MemoryManager& theManager = getMemoryManager();
XalanDOMString uri(theManager);
uri = XalanLocator::getSystemId(locator, uri.c_str());
throw XalanXPathException(
msg,
theManager,
locator);
}
void
XPathExecutionContextDefault::warn(
const XalanDOMString& msg,
const XalanNode* sourceNode,
const Locator* locator) const
{
assert(m_xpathEnvSupport != 0);
m_xpathEnvSupport->problem(
XPathEnvSupport::eXPATH,
XPathEnvSupport::eWarning,
msg,
locator,
sourceNode);
}
void
XPathExecutionContextDefault::message(
const XalanDOMString& msg,
const XalanNode* sourceNode,
const Locator* locator) const
{
assert(m_xpathEnvSupport != 0);
m_xpathEnvSupport->problem(
XPathEnvSupport::eXPATH,
XPathEnvSupport::eWarning,
msg,
locator,
sourceNode);
}
XalanDocument*
XPathExecutionContextDefault::getSourceDocument(const XalanDOMString& theURI) const
{
assert(m_xpathEnvSupport != 0);
return m_xpathEnvSupport->getSourceDocument(theURI);
}
void
XPathExecutionContextDefault::setSourceDocument(
const XalanDOMString& theURI,
XalanDocument* theDocument)
{
assert(m_xpathEnvSupport != 0);
m_xpathEnvSupport->setSourceDocument(theURI, theDocument);
}
void XPathExecutionContextDefault::formatNumber(
double number,
const XalanDOMString& pattern,
XalanDOMString& theResult,
const XalanNode* context,
const Locator* locator)
{
doFormatNumber(number, pattern, 0, theResult, context, locator);
}
void XPathExecutionContextDefault::formatNumber(
double number,
const XalanDOMString& pattern,
const XalanDOMString& /* dfsName */,
XalanDOMString& theResult,
const XalanNode* context,
const Locator* locator)
{
doFormatNumber(number, pattern, 0, theResult, context, locator);
}
void XPathExecutionContextDefault::doFormatNumber(
double number,
const XalanDOMString& /* pattern */,
const XalanDecimalFormatSymbols* theDFS,
XalanDOMString& theResult,
const XalanNode* context,
const Locator* locator)
{
if (DoubleSupport::isNaN(number) == true)
{
if (theDFS != 0)
{
theResult = theDFS->getNaN();
}
else
{
NumberToDOMString(number, theResult);
}
}
else if (DoubleSupport::isNegativeInfinity(number) == true)
{
if (theDFS != 0)
{
theResult = theDFS->getMinusSign();
theResult += theDFS->getInfinity();
}
else
{
NumberToDOMString(number, theResult);
}
}
else if (DoubleSupport::isPositiveInfinity(number) == true )
{
if (theDFS != 0)
{
theResult = theDFS->getInfinity();
}
else
{
NumberToDOMString(number, theResult);
}
}
else
{
const GetCachedString theGuard(*this);
warn(
XalanMessageLoader::getMessage(
theGuard.get(),
XalanMessages::FunctionIsNotImplemented_1Param,
"format-number()"),
context,
locator);
NumberToDOMString(number,theResult);
}
}
}