src/xalanc/XPath/XPathExecutionContextDefault.cpp (482 lines of code) (raw):

/* * 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); } } }