bool XercesURIResolver::resolveDocument(Sequence &result, const XMLCh* uri, DynamicContext* context, const QueryPathNode *projection) { Node::Ptr doc; // Resolve the uri against the base uri const XMLCh *systemId = uri; XMLURL urlTmp(context->getMemoryManager()); if(urlTmp.setURL(context->getBaseURI(), uri, urlTmp)) { systemId = context->getMemoryManager()->getPooledString(urlTmp.getURLText()); } else { systemId = context->getMemoryManager()->getPooledString(uri); } // Check in the cache DOMDocument *found = _documentMap.get((void*)systemId); // Check to see if we can locate and parse the document if(found == 0) { try { doc = const_cast<DocumentCache*>(context->getDocumentCache())->loadDocument(uri, context, projection); found = (DOMDocument*)((DOMNode*)doc->getInterface(XercesConfiguration::gXerces)); _documentMap.put((void*)systemId, found); _uriMap.put((void*)found, const_cast<XMLCh*>(systemId)); } catch(const XMLParseException& e) { XMLBuffer errMsg; errMsg.set(X("Error parsing resource: ")); errMsg.append(uri); errMsg.append(X(". Error message: ")); errMsg.append(e.getError()); errMsg.append(X(" [err:FODC0002]")); XQThrow2(XMLParseException,X("XercesContextImpl::resolveDocument"), errMsg.getRawBuffer()); } } else { doc = new XercesNodeImpl(found, (XercesURIResolver*)context->getDefaultURIResolver()); } if(doc.notNull()) { result.addItem(doc); return true; } XMLBuffer errMsg; errMsg.set(X("Error retrieving resource: ")); errMsg.append(uri); errMsg.append(X(" [err:FODC0002]")); XQThrow2(XMLParseException,X("XercesContextImpl::resolveDocument"), errMsg.getRawBuffer()); return false; }
void DbXmlUpdateFactory::applyInsertBefore(const PendingUpdate &update, DynamicContext *context) { const DbXmlNodeImpl *next = (const DbXmlNodeImpl*)update.getTarget().get(); if (!next->isUpdateAble()) return; Node::Ptr parent = next->dmParent(context); NsDomNodeRef nextRef = next->getNsDomNode(); applyInserts(update, (const DbXmlNodeImpl *)parent->getInterface(DbXmlNodeImpl::gDbXml), nextRef.get(), context, false); }
void DbXmlUpdateFactory::applyReplaceNode(const PendingUpdate &update, DynamicContext *context) { const DbXmlNodeImpl *target = (const DbXmlNodeImpl*)update.getTarget().get(); if (!target->isUpdateAble()) return; Node::Ptr parent = target->dmParent(context); // insert all new nodes *before* the target, then // mark target for deletion NsDomNodeRef targetRef = target->getNsDomNode(); applyInserts(update, (const DbXmlNodeImpl *)parent->getInterface(DbXmlNodeImpl::gDbXml), targetRef.get(), context, false); forDeletion_.insert(target); }
void DbXmlUpdateFactory::applyInsertAfter(const PendingUpdate &update, DynamicContext *context) { const DbXmlNodeImpl *prev = (const DbXmlNodeImpl*)update.getTarget().get(); if (!prev->isUpdateAble()) return; Node::Ptr parent = prev->dmParent(context); // in order to preserve order for multiple inserts, insertAfter must turn // into insertBefore NsDomNodeRef prevRef = prev->getNsDomNode(); NsDomNodeRef nextRef = prevRef->getNsNextSibling(); if (!nextRef.get()) { DbXmlConfiguration *conf = GET_CONFIGURATION(context); prevRef->refreshNode(conf->getOperationContext(), true); nextRef = prevRef->getNsNextSibling(); } applyInserts(update, (const DbXmlNodeImpl *)parent->getInterface(DbXmlNodeImpl::gDbXml), nextRef.get(), context, true); }
bool XercesURIResolver::putDocument(const Node::Ptr &document, const XMLCh *uri, DynamicContext *context) { // Ignore nodes with no URI if(uri == 0) return true; try { XMLUri uri_obj(uri); // Check for a "file" scheme if(!XPath2Utils::equals(uri_obj.getScheme(), file_scheme)) return false; // Check this is a Xerces data model node const DOMNode *domnode = (const DOMNode*)document->getInterface(XercesConfiguration::gXerces); if(!domnode) return false; // Write the document to disk DOMImplementation *impl = XQillaImplementation::getDOMImplementationImpl(); const XMLCh *path = uri_obj.getPath(); //Get rid of the leading / if it is a Windows path. int colonIdx = XMLString::indexOf(path, chColon); if(path && colonIdx == 2 && XMLString::isAlpha(path[1])){ path++; } // Unescape the URI // Since URI escaping encodes UTF-8 char sequences, it's easier to do the unescaping with a UTF-8 string. UTF8Str path8(path); string unencode8; const char *ptr = path8.str(); while(*ptr) { if(*ptr == '%') { if(ptr[1] == 0) throw MalformedURLException(__FILE__, __LINE__, XMLExcepts::URL_MalformedURL); if(ptr[2] == 0) throw MalformedURLException(__FILE__, __LINE__, XMLExcepts::URL_MalformedURL); unencode8.append(1, (char)(char2hexdigit(ptr[1]) * 0x10 + char2hexdigit(ptr[2]))); ptr += 3; } else { unencode8.append(1, *ptr); ptr += 1; } } LocalFileFormatTarget target(X(unencode8.c_str())); #if _XERCES_VERSION >= 30000 AutoRelease<DOMLSSerializer> writer(impl->createLSSerializer()); AutoRelease<DOMLSOutput> output(impl->createLSOutput()); output->setByteStream(&target); #else // Find the encoding to use const XMLCh *encoding = 0; if(domnode->getNodeType() == DOMNode::DOCUMENT_NODE) { // Use the document's encoding, if this is a document node encoding = ((DOMDocument*)domnode)->getEncoding(); } if(encoding == 0 || *encoding == 0) { // Otherwise, just use UTF-8 encoding = utf8_str; } AutoRelease<DOMWriter> writer(((DOMImplementationLS*)impl)->createDOMWriter()); writer->setEncoding(encoding); #endif try { #if _XERCES_VERSION >= 30000 if(!writer->write(domnode, output)) { #else if(!writer->writeNode(&target, *domnode)) { #endif XMLBuffer buf; buf.append(X("Writing to URI \"")); buf.append(uri_obj.getUriText()); buf.append(X("\" failed.")); XQThrow2(ASTException, X("XercesURIResolver::putDocument"), buf.getRawBuffer()); } } catch(DOMException &ex) { XMLBuffer buf; buf.append(X("Writing to URI \"")); buf.append(uri_obj.getUriText()); buf.append(X("\" failed: ")); buf.append(ex.msg); XQThrow2(ASTException, X("XercesURIResolver::putDocument"), buf.getRawBuffer()); } } catch(const MalformedURLException &ex) { XMLBuffer buf; buf.append(X("Unable to re-write document - bad document URI \"")); buf.append(uri); buf.append(X("\"")); XQThrow2(ASTException, X("XercesURIResolver::putDocument"), buf.getRawBuffer()); } return true; }