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