Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
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);
  }
}