| /* |
| * Copyright 1999-2004 The Apache Software Foundation. |
| * |
| * Licensed 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" |
| |
| |
| |
| XALAN_CPP_NAMESPACE_BEGIN |
| |
| |
| |
| const NodeRefList XPathExecutionContextDefault::s_dummyList; |
| |
| |
| |
| XPathExecutionContextDefault::XPathExecutionContextDefault( |
| XPathEnvSupport& theXPathEnvSupport, |
| DOMSupport& theDOMSupport, |
| XObjectFactory& theXObjectFactory, |
| XalanNode* theCurrentNode, |
| const NodeRefListBase* theContextNodeList, |
| const PrefixResolver* thePrefixResolver) : |
| XPathExecutionContext(&theXObjectFactory), |
| m_xpathEnvSupport(&theXPathEnvSupport), |
| m_domSupport(&theDOMSupport), |
| m_currentNodeStack(), |
| m_contextNodeListStack(), |
| m_prefixResolver(thePrefixResolver), |
| m_nodeListCache(eNodeListCacheListSize), |
| m_stringCache(), |
| m_cachedPosition(), |
| m_scratchQName() |
| { |
| m_currentNodeStack.push_back(theCurrentNode); |
| |
| m_contextNodeListStack.push_back(theContextNodeList == 0 ? &s_dummyList : theContextNodeList); |
| } |
| |
| |
| |
| XPathExecutionContextDefault::XPathExecutionContextDefault( |
| XalanNode* theCurrentNode, |
| const NodeRefListBase* theContextNodeList, |
| const PrefixResolver* thePrefixResolver) : |
| XPathExecutionContext(), |
| m_xpathEnvSupport(0), |
| m_domSupport(0), |
| m_currentNodeStack(), |
| m_contextNodeListStack(), |
| m_prefixResolver(thePrefixResolver), |
| m_nodeListCache(eNodeListCacheListSize), |
| m_stringCache(), |
| m_cachedPosition(), |
| m_scratchQName() |
| { |
| m_currentNodeStack.push_back(theCurrentNode); |
| |
| m_contextNodeListStack.push_back(theContextNodeList == 0 ? &s_dummyList : theContextNodeList); |
| } |
| |
| |
| |
| |
| XPathExecutionContextDefault::~XPathExecutionContextDefault() |
| { |
| reset(); |
| } |
| |
| |
| |
| 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 |
| #if defined(XALAN_NO_MUTABLE) |
| ((XPathExecutionContextDefault*)this)->m_cachedPosition.m_index = theIndex == NodeRefListBase::npos ? 0 : theIndex + 1; |
| ((XPathExecutionContextDefault*)this)->m_cachedPosition.m_node = &contextNode; |
| #else |
| m_cachedPosition.m_index = theIndex == NodeRefListBase::npos ? 0 : theIndex + 1; |
| m_cachedPosition.m_node = &contextNode; |
| #endif |
| } |
| |
| 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 LocatorType* 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 LocatorType* 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 LocatorType* locator) |
| { |
| assert(m_xpathEnvSupport != 0); |
| |
| return m_xpathEnvSupport->extFunction(*this, theNamespace, functionName, context, argVec, locator); |
| } |
| |
| |
| |
| XalanDocument* |
| XPathExecutionContextDefault::parseXML( |
| const XalanDOMString& urlString, |
| const XalanDOMString& base) const |
| { |
| assert(m_xpathEnvSupport != 0); |
| |
| return m_xpathEnvSupport->parseXML(urlString, base); |
| } |
| |
| |
| |
| MutableNodeRefList* |
| XPathExecutionContextDefault::borrowMutableNodeRefList() |
| { |
| return m_nodeListCache.get(); |
| } |
| |
| |
| |
| bool |
| XPathExecutionContextDefault::returnMutableNodeRefList(MutableNodeRefList* theList) |
| { |
| return m_nodeListCache.release(theList); |
| } |
| |
| |
| |
| MutableNodeRefList* |
| XPathExecutionContextDefault::createMutableNodeRefList() const |
| { |
| return new MutableNodeRefList; |
| } |
| |
| |
| |
| XalanDOMString& |
| XPathExecutionContextDefault::getCachedString() |
| { |
| return m_stringCache.get(); |
| } |
| |
| |
| |
| bool |
| XPathExecutionContextDefault::releaseCachedString(XalanDOMString& theString) |
| { |
| return m_stringCache.release(theString); |
| } |
| |
| |
| |
| void |
| XPathExecutionContextDefault::getNodeSetByKey( |
| XalanDocument* /* doc */, |
| const XalanQName& /* qname */, |
| const XalanDOMString& /* ref */, |
| MutableNodeRefList& /* nodelist */) |
| { |
| } |
| |
| |
| |
| void |
| XPathExecutionContextDefault::getNodeSetByKey( |
| XalanDocument* /* doc */, |
| const XalanDOMString& /* name */, |
| const XalanDOMString& /* ref */, |
| const LocatorType* /* locator */, |
| MutableNodeRefList& /* nodelist */) |
| { |
| } |
| |
| |
| |
| const XObjectPtr |
| XPathExecutionContextDefault::getVariable( |
| const XalanQName& name, |
| const LocatorType* /* 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); |
| } |
| |
| |
| |
| 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 LocatorType* locator) const |
| { |
| assert(m_xpathEnvSupport != 0); |
| |
| XalanLocator::size_type lineNumber = XalanLocator::getUnknownValue(); |
| XalanLocator::size_type columnNumber = XalanLocator::getUnknownValue(); |
| |
| XalanDOMString uri; |
| |
| if (locator != 0) |
| { |
| lineNumber = locator->getLineNumber(); |
| columnNumber = locator->getColumnNumber(); |
| |
| const XalanDOMChar* id = |
| locator->getPublicId(); |
| |
| if (id != 0) |
| { |
| uri = id; |
| } |
| else |
| { |
| id = locator->getSystemId(); |
| |
| if (id != 0) |
| { |
| uri = id; |
| } |
| } |
| } |
| |
| if (m_xpathEnvSupport->problem( |
| XPathEnvSupport::eXPATHProcessor, |
| XPathEnvSupport::eError, |
| m_prefixResolver, |
| sourceNode, |
| msg, |
| c_wstr(uri), |
| lineNumber, |
| columnNumber) == true) |
| { |
| throw XalanXPathException(msg, uri, lineNumber, columnNumber); |
| } |
| } |
| |
| |
| |
| void |
| XPathExecutionContextDefault::warn( |
| const XalanDOMString& msg, |
| const XalanNode* sourceNode, |
| const LocatorType* locator) const |
| { |
| assert(m_xpathEnvSupport != 0); |
| |
| XalanLocator::size_type lineNumber = XalanLocator::getUnknownValue(); |
| XalanLocator::size_type columnNumber = XalanLocator::getUnknownValue(); |
| |
| XalanDOMString uri; |
| |
| if (locator != 0) |
| { |
| lineNumber = locator->getLineNumber(); |
| columnNumber = locator->getColumnNumber(); |
| |
| const XalanDOMChar* id = |
| locator->getPublicId(); |
| |
| if (id != 0) |
| { |
| uri = id; |
| } |
| else |
| { |
| id = locator->getSystemId(); |
| |
| if (id != 0) |
| { |
| uri = id; |
| } |
| } |
| } |
| |
| if (m_xpathEnvSupport->problem( |
| XPathEnvSupport::eXPATHProcessor, |
| XPathEnvSupport::eWarning, |
| m_prefixResolver, |
| sourceNode, |
| msg, |
| c_wstr(uri), |
| lineNumber, |
| columnNumber) == true) |
| { |
| throw XalanXPathException(msg, uri, lineNumber, columnNumber); |
| } |
| } |
| |
| |
| |
| void |
| XPathExecutionContextDefault::message( |
| const XalanDOMString& msg, |
| const XalanNode* sourceNode, |
| const LocatorType* locator) const |
| { |
| assert(m_xpathEnvSupport != 0); |
| |
| XalanLocator::size_type lineNumber = XalanLocator::getUnknownValue(); |
| XalanLocator::size_type columnNumber = XalanLocator::getUnknownValue(); |
| |
| XalanDOMString uri; |
| |
| if (locator != 0) |
| { |
| lineNumber = locator->getLineNumber(); |
| columnNumber = locator->getColumnNumber(); |
| |
| const XalanDOMChar* id = |
| locator->getPublicId(); |
| |
| if (id != 0) |
| { |
| uri = id; |
| } |
| else |
| { |
| id = locator->getSystemId(); |
| |
| if (id != 0) |
| { |
| uri = id; |
| } |
| } |
| } |
| |
| if (m_xpathEnvSupport->problem( |
| XPathEnvSupport::eXPATHProcessor, |
| XPathEnvSupport::eMessage, |
| m_prefixResolver, |
| sourceNode, |
| msg, |
| c_wstr(uri), |
| lineNumber, |
| columnNumber) == true) |
| { |
| throw XalanXPathException(msg, uri, lineNumber, columnNumber); |
| } |
| } |
| |
| |
| 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 LocatorType* 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 LocatorType* 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 LocatorType* locator) |
| { |
| if (DoubleSupport::isNaN(number) == true) |
| { |
| if (theDFS != 0) |
| { |
| theResult = theDFS->getNaN(); |
| } |
| else |
| { |
| DoubleToDOMString(number, theResult); |
| } |
| } |
| else if (DoubleSupport::isNegativeInfinity(number) == true) |
| { |
| if (theDFS != 0) |
| { |
| theResult = theDFS->getMinusSign(); |
| theResult += theDFS->getInfinity(); |
| } |
| else |
| { |
| DoubleToDOMString(number, theResult); |
| } |
| } |
| else if (DoubleSupport::isPositiveInfinity(number) == true ) |
| { |
| if (theDFS != 0) |
| { |
| theResult = theDFS->getInfinity(); |
| } |
| else |
| { |
| DoubleToDOMString(number, theResult); |
| } |
| } |
| else |
| { |
| warn( |
| XalanMessageLoader::getMessage(XalanMessages::FunctionIsNotImplemented_1Param,"format-number()"), |
| context, |
| locator); |
| |
| DoubleToDOMString(number,theResult); |
| } |
| } |
| |
| |
| |
| XALAN_CPP_NAMESPACE_END |