XQQuery *XQQuery::parseModule(const XMLCh *ns, const XMLCh *at, const LocationInfo *location) const { InputSource* srcToUse = 0; if(m_context->getDocumentCache()->getXMLEntityResolver()){ XMLResourceIdentifier resourceIdentifier(XMLResourceIdentifier::UnKnown, at, ns, XMLUni::fgZeroLenString, m_context->getBaseURI()); srcToUse = m_context->getDocumentCache()->getXMLEntityResolver()->resolveEntity(&resourceIdentifier); } if(srcToUse==0) { try { XMLURL urlTmp(m_context->getBaseURI(), at); if (urlTmp.isRelative()) { throw MalformedURLException(__FILE__, __LINE__, XMLExcepts::URL_NoProtocolPresent); } srcToUse = new URLInputSource(urlTmp); } catch(const MalformedURLException&) { // It's not a URL, so let's assume it's a local file name. const XMLCh* baseUri=m_context->getBaseURI(); if(baseUri && baseUri[0]) { XMLCh* tmpBuf = XMLPlatformUtils::weavePaths(baseUri, at); srcToUse = new LocalFileInputSource(tmpBuf); XMLPlatformUtils::fgMemoryManager->deallocate(tmpBuf); } else { srcToUse = new LocalFileInputSource(at); } } } Janitor<InputSource> janIS(srcToUse); XQQuery *module = m_moduleCache->getByURI(srcToUse->getSystemId()); if(module) return module; AutoDelete<DynamicContext> ctxGuard(m_context->createModuleContext()); DynamicContext *moduleCtx = ctxGuard.get(); moduleCtx->setBaseURI(srcToUse->getSystemId()); moduleCtx->setXMLEntityResolver(m_context->getXMLEntityResolver()); AutoDelete<XQQuery> moduleGuard(new (XMLPlatformUtils::fgMemoryManager) XQQuery(ctxGuard.adopt(), true, m_moduleCache, XMLPlatformUtils::fgMemoryManager)); module = moduleGuard; module->setFile(srcToUse->getSystemId()); module->setModuleTargetNamespace(ns); // Put the unparsed module in the cache, to resolve loops correctly m_moduleCache->put(moduleGuard.adopt()); XQilla::parse(*srcToUse, moduleCtx, XQilla::NO_STATIC_RESOLUTION, XMLPlatformUtils::fgMemoryManager, module); return module; }
void XQQuery::importModule(const XMLCh* szUri, VectorOfStrings* locations, StaticContext* context, const LocationInfo *location) { for(ImportedModules::iterator modIt = m_importedModules.begin(); modIt != m_importedModules.end(); ++modIt) { if(XPath2Utils::equals((*modIt)->getModuleTargetNamespace(),szUri)) { XMLBuffer buf(1023,context->getMemoryManager()); buf.set(X("Module for namespace '")); buf.append(szUri); buf.append(X("' has already been imported [err:XQST0047]")); XQThrow3(StaticErrorException, X("XQQuery::ImportModule"), buf.getRawBuffer(), location); } } if(locations==NULL) locations=context->resolveModuleURI(szUri); if(locations==NULL || locations->empty()) { XMLBuffer buf(1023,context->getMemoryManager()); buf.set(X("Cannot locate module for namespace ")); buf.append(szUri); buf.append(X(" without the 'at <location>' keyword [err:XQST0059]")); XQThrow3(StaticErrorException,X("XQQuery::ImportModule"), buf.getRawBuffer(), location); } bool bFound=false; for(VectorOfStrings::iterator it=locations->begin();it!=locations->end();++it) { InputSource* srcToUse = 0; if (context->getDocumentCache()->getXMLEntityResolver()){ XMLResourceIdentifier resourceIdentifier(XMLResourceIdentifier::UnKnown, *it, szUri, XMLUni::fgZeroLenString, context->getBaseURI()); srcToUse = context->getDocumentCache()->getXMLEntityResolver()->resolveEntity(&resourceIdentifier); } if(srcToUse==0) { try { XMLURL urlTmp(context->getBaseURI(), *it); if (urlTmp.isRelative()) { throw MalformedURLException(__FILE__, __LINE__, XMLExcepts::URL_NoProtocolPresent); } srcToUse = new URLInputSource(urlTmp); } catch(const MalformedURLException&) { // It's not a URL, so let's assume it's a local file name. const XMLCh* baseUri=context->getBaseURI(); if(baseUri && baseUri[0]) { XMLCh* tmpBuf = XMLPlatformUtils::weavePaths(baseUri, *it); srcToUse = new LocalFileInputSource(tmpBuf); XMLPlatformUtils::fgMemoryManager->deallocate(tmpBuf); } else { srcToUse = new LocalFileInputSource(*it); } } } Janitor<InputSource> janIS(srcToUse); AutoDelete<DynamicContext> ctxGuard(context->createModuleContext()); DynamicContext *moduleCtx = ctxGuard.get(); moduleCtx->setBaseURI(srcToUse->getSystemId()); LoopDetector loopDetector(context->getXMLEntityResolver(), szUri, location); moduleCtx->setXMLEntityResolver(&loopDetector); AutoDelete<XQQuery> pParsedQuery(XQilla::parse(*srcToUse, ctxGuard.adopt(), XQilla::NO_OPTIMIZATION)); if(!pParsedQuery->getIsLibraryModule()) { XMLBuffer buf(1023,context->getMemoryManager()); buf.set(X("The module at ")); buf.append(srcToUse->getSystemId()); buf.append(X(" is not a module")); XQThrow3(StaticErrorException, X("XQQuery::ImportModule"), buf.getRawBuffer(), location); } if(!XERCES_CPP_NAMESPACE::XMLString::equals(szUri,pParsedQuery->getModuleTargetNamespace())) { XMLBuffer buf(1023,context->getMemoryManager()); buf.set(X("The module at ")); buf.append(srcToUse->getSystemId()); buf.append(X(" specifies a different namespace [err:XQST0059]")); XQThrow3(StaticErrorException, X("XQQuery::ImportModule"), buf.getRawBuffer(), location); } // now move the variable declarations and the function definitions into my context for(UserFunctions::iterator itFn = pParsedQuery->m_userDefFns.begin(); itFn != pParsedQuery->m_userDefFns.end(); ++itFn) { (*itFn)->setModuleDocumentCache(const_cast<DocumentCache*>(moduleCtx->getDocumentCache())); if((*itFn)->isTemplate()) { context->addTemplate(*itFn); } else if((*itFn)->getName()) { context->addCustomFunction(*itFn); } } for(GlobalVariables::iterator itVar = pParsedQuery->m_userDefVars.begin(); itVar != pParsedQuery->m_userDefVars.end(); ++itVar) { for(ImportedModules::const_iterator modIt = m_importedModules.begin(); modIt != m_importedModules.end(); ++modIt) { for(GlobalVariables::const_iterator varIt = (*modIt)->m_userDefVars.begin(); varIt != (*modIt)->m_userDefVars.end(); ++varIt) { if(XPath2Utils::equals((*varIt)->getVariableURI(), (*itVar)->getVariableURI()) && XPath2Utils::equals((*varIt)->getVariableLocalName(), (*itVar)->getVariableLocalName())) { XMLBuffer buf(1023,context->getMemoryManager()); buf.set(X("An imported variable {")); buf.append((*itVar)->getVariableURI()); buf.append(X("}")); buf.append((*itVar)->getVariableLocalName()); buf.append(X(" conflicts with an already defined global variable [err:XQST0049].")); XQThrow3(StaticErrorException, X("XQQuery::ImportModule"), buf.getRawBuffer(), *varIt); } } } } moduleCtx->setXMLEntityResolver(context->getXMLEntityResolver()); m_importedModules.push_back(pParsedQuery.adopt()); bFound=true; } if(!bFound) { XMLBuffer buf(1023,context->getMemoryManager()); buf.set(X("Cannot locate the module for namespace \"")); buf.append(szUri); buf.append(X("\" [err:XQST0059]")); XQThrow3(StaticErrorException,X("XQQuery::ImportModule"), buf.getRawBuffer(), location); } }