Example #1
0
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);
  }
}