#include "../config/pathan_config.h" /* * Copyright (c) 2002, DecisionSoft Limited All rights reserved. * Please see LICENSE.TXT for more information. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static CodepointCollation g_codepointCollation; inline int gettimezone() { time_t tt; time(&tt); struct tm *tm_p = gmtime(&tt); return (int)mktime(tm_p) - (int)tt; } DynamicContextImpl::DynamicContextImpl(const StaticContext *staticContext, XPath2MemoryManager* memMgr) : _staticContext(staticContext), _nsResolver(staticContext->getNSResolver()), _defaultCollation(0), _contextItem(0), _contextPosition(1), _contextSize(1), _varStore(memMgr->createVariableStore()), _implicitTimezone(0), _resolvers(PathanAllocator(memMgr)), _docCache(0), _memMgr(memMgr), _originalMemMgr(memMgr) { time(&_currentTime); } DynamicContextImpl::~DynamicContextImpl() { } void DynamicContextImpl::clearDynamicContext() { _nsResolver = _staticContext->getNSResolver(); _contextItem = 0; _contextSize = 1; _contextPosition = 1; _varStore->clear(); _implicitTimezone = 0; _resolvers.clear(); if(_docCache) _docCache->clearStoredDocuments(); time(&_currentTime); } DynamicContext *DynamicContextImpl::createDynamicContext(XPath2MemoryManager *memMgr) const { if(!memMgr) { memMgr = _memMgr; } return _staticContext->createDynamicContext(memMgr); } DocumentCache *DynamicContextImpl::getDynamicDocumentCache() { if(!_docCache) { _docCache = _staticContext->getDocumentCache()->createDerivedCache(_originalMemMgr); } return _docCache; } void DynamicContextImpl::setContextItem(const Item* item) { _contextItem = item; } /** Set the memory manager to the one given */ void DynamicContextImpl::setMemoryManager(XPath2MemoryManager* memMgr) { _memMgr = memMgr; } void DynamicContextImpl::setContextSize(unsigned int size) { _contextSize = size; } void DynamicContextImpl::setContextPosition(unsigned int pos) { _contextPosition = pos; } const Item* DynamicContextImpl::getContextItem() const { return _contextItem; } unsigned int DynamicContextImpl::getContextSize() const { return _contextSize; } unsigned int DynamicContextImpl::getContextPosition() const { return _contextPosition; } VariableStore* DynamicContextImpl::getVariableStore() { return _varStore; } time_t DynamicContextImpl::getCurrentTime() const { return _currentTime; } void DynamicContextImpl::setCurrentTime(time_t newTime) { _currentTime=newTime; } const ATDurationOrDerived* DynamicContextImpl::getImplicitTimezone() const { if(_implicitTimezone == 0) { int tz = 0; #ifdef WIN32 _tzset(); tz = _timezone; #else /*WIN32*/ tzset (); tz = gettimezone(); #endif // validate tzone Timezone tzone(tz); // c-style the const away since we are in a const method ((DynamicContextImpl*)this)->_implicitTimezone = tzone.asDayTimeDuration(this); } return _implicitTimezone; } void DynamicContextImpl::setImplicitTimezone(const ATDurationOrDerived* timezoneAsDuration) { // validate the timezone -- will trow if invalid Timezone timezone(timezoneAsDuration, this); this->_implicitTimezone = timezoneAsDuration; } XPath2MemoryManager* DynamicContextImpl::getMemoryManager() const { return _memMgr; } XERCES_CPP_NAMESPACE::DOMDocument *DynamicContextImpl::createNewDocument() const { return XERCES_CPP_NAMESPACE_QUALIFIER DOMImplementation::getImplementation()->createDocument(getMemoryManager()); } void DynamicContextImpl::registerURIResolver(URIResolver *resolver) { if(resolver != 0) { _resolvers.push_back(resolver); } } Sequence DynamicContextImpl::resolveDocument(const XMLCh* uri) { bool found = false; Sequence result(getMemoryManager()); std::vector >::reverse_iterator end = _resolvers.rend(); for(std::vector >::reverse_iterator i = _resolvers.rbegin(); i != end; ++i) { if((*i)->resolveDocument(result, uri, this)) { found = true; break; } } if(!found) { XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument *doc = 0; try { doc = getDynamicDocumentCache()->loadXMLDocument(uri, this); } catch(const XMLParseException&) { doc = 0; } if(doc != 0) { result.addItem(getMemoryManager()->createNode(doc)); } else { XERCES_CPP_NAMESPACE_QUALIFIER XMLBuffer errMsg; errMsg.set(X("Error retrieving resource: ")); errMsg.append(uri); DSLthrow(XMLParseException,X("DynamicContextImpl::resolveDocument"), errMsg.getRawBuffer()); } } return result; } Sequence DynamicContextImpl::resolveCollection(const XMLCh* uri) { bool found = false; Sequence result(getMemoryManager()); std::vector >::reverse_iterator end = _resolvers.rend(); for(std::vector >::reverse_iterator i = _resolvers.rbegin(); i != end; ++i) { if((*i)->resolveCollection(result, uri, this)) { found = true; break; } } if(!found) { XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument *doc = 0; try { doc = getDynamicDocumentCache()->loadXMLDocument(uri, this); } catch(const XMLParseException&) { doc = 0; } if(doc != 0) { result.addItem(getMemoryManager()->createNode(doc)); } else { XERCES_CPP_NAMESPACE_QUALIFIER XMLBuffer errMsg; errMsg.set(X("Error retrieving resource: ")); errMsg.append(uri); DSLthrow(XMLParseException,X("DynamicContextImpl::resolveDocument"), errMsg.getRawBuffer()); } } return result; } XERCES_CPP_NAMESPACE_QUALIFIER DOMNode *DynamicContextImpl::validate(const XERCES_CPP_NAMESPACE_QUALIFIER DOMNode* node, DocumentCache::ValidationMode valMode, ValidationContext valContext) { return getDynamicDocumentCache()->validate(node, valMode, valContext, this); } void DynamicContextImpl::trace(const XMLCh* message1, const XMLCh* message2) { char* msg1=XERCES_CPP_NAMESPACE_QUALIFIER XMLString::transcode(message1); char* msg2=XERCES_CPP_NAMESPACE_QUALIFIER XMLString::transcode(message2); std::cerr << msg1 << " " << msg2 << std::endl; XERCES_CPP_NAMESPACE_QUALIFIER XMLString::release(&msg1); XERCES_CPP_NAMESPACE_QUALIFIER XMLString::release(&msg2); } void DynamicContextImpl::setNSResolver(const XERCES_CPP_NAMESPACE_QUALIFIER DOMXPathNSResolver* resolver) { _nsResolver = resolver; } const XERCES_CPP_NAMESPACE_QUALIFIER DOMXPathNSResolver* DynamicContextImpl::getNSResolver() const { return _nsResolver; } const XMLCh* DynamicContextImpl::getUriBoundToPrefix(const XMLCh* prefix) const { const XMLCh* uri = _nsResolver->lookupNamespaceURI(prefix); if(XERCES_CPP_NAMESPACE_QUALIFIER XMLString::stringLen(uri) == 0 && XERCES_CPP_NAMESPACE_QUALIFIER XMLString::stringLen(prefix) > 0){ const XMLCh* msg = XPath2Utils::concatStrings(X("No namespace for prefix \'"), prefix, X("\'"), getMemoryManager()); DSLthrow(NamespaceLookupException, X("XPath2ContextImpl::getUriBoundToPrefix"), msg); } return uri; } const XMLCh* DynamicContextImpl::getPrefixBoundToUri(const XMLCh* uri) const { return _nsResolver->lookupPrefix(uri); } void DynamicContextImpl::setXMLEntityResolver(XERCES_CPP_NAMESPACE_QUALIFIER XMLEntityResolver* const handler) { getDynamicDocumentCache()->setXMLEntityResolver(handler); } void DynamicContextImpl::setDefaultCollation(const XMLCh* URI) { _defaultCollation=getMemoryManager()->getPooledString(URI); } Collation* DynamicContextImpl::getDefaultCollation() const { if(_defaultCollation == 0) { return _staticContext->getDefaultCollation(); } else { return getCollation(_defaultCollation); } }