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; }
TupleNode *ForTuple::staticResolution(StaticContext *context) { parent_ = parent_->staticResolution(context); varURI_ = context->getUriBoundToPrefix(XPath2NSUtils::getPrefix(varQName_, context->getMemoryManager()), this); varName_ = XPath2NSUtils::getLocalName(varQName_); if(posQName_ && *posQName_) { posURI_ = context->getUriBoundToPrefix(XPath2NSUtils::getPrefix(posQName_, context->getMemoryManager()), this); posName_ = XPath2NSUtils::getLocalName(posQName_); if(XPath2Utils::equals(posName_, varName_) && XPath2Utils::equals(posURI_, varURI_)) { XMLBuffer errMsg; errMsg.set(X("The positional variable with name {")); errMsg.append(posURI_); errMsg.append(X("}")); errMsg.append(posName_); errMsg.append(X(" conflicts with the iteration variable [err:XQST0089]")); XQThrow(StaticErrorException,X("ForTuple::staticResolution"), errMsg.getRawBuffer()); } } expr_ = expr_->staticResolution(context); return this; }
ASTNode* XQFunctionCall::staticResolution(StaticContext *context) { if(uri_ == 0) { if(prefix_ == 0 || *prefix_ == 0) { uri_ = context->getDefaultFuncNS(); } else { uri_ = context->getUriBoundToPrefix(prefix_, this); } } ASTNode *result = context->lookUpFunction(uri_, name_, *args_, this); if(result == 0) { XMLBuffer buf; buf.set(X("A function called {")); buf.append(uri_); buf.append(X("}")); buf.append(name_); buf.append(X(" with ")); XPath2Utils::numToBuf(args_ ? (unsigned int)args_->size() : 0, buf); buf.append(X(" arguments is not defined [err:XPST0017]")); XQThrow(StaticErrorException, X("XQFunctionCall::staticResolution"), buf.getRawBuffer()); } // Our arguments don't belong to us anymore for(VectorOfASTNodes::iterator i = args_->begin(); i != args_->end(); ++i) { *i = 0; } // Release this object this->release(); return result->staticResolution(context); }
Item::Ptr AtomizeResult::next(DynamicContext *context) { // for $item in (Expr) return // typeswitch ($item) // case $value as atomic value return $value // default $node return fn:data($node) Item::Ptr result = _sub->next(context); while(result.isNull()) { _sub = 0; result = _parent->next(context); if(result.isNull()) { _parent = 0; return 0; } if(result->isNode()) { _sub = ((Node*)result.get())->dmTypedValue(context); result = _sub->next(context); } else if(result->isFunction()) { XMLBuffer buf; buf.set(X("Sequence does not match type (xs:anyAtomicType | node())*")); buf.append(X(" - found item of type ")); result->typeToBuffer(context, buf); buf.append(X(" [err:XPTY0004]")); XQThrow(XPath2TypeMatchException, X("AtomizeResult::next"), buf.getRawBuffer()); } } return result; }
void FunctionLookup::insertFunction(FuncFactory *func) { // Use similar algorithm to lookup in order to detect overlaps // in argument numbers RefHash2KeysTableOfEnumerator<FuncFactory> iterator(const_cast<RefHash2KeysTableOf< FuncFactory >* >(&_funcTable)); // // Walk the matches for the primary key (name) looking for overlaps: // ensure func->max < min OR func->min > max // iterator.setPrimaryKey(func->getURINameHash()); while(iterator.hasMoreElements()) { FuncFactory *entry= &(iterator.nextElement()); if ((func->getMaxArgs() < entry->getMinArgs()) || (func->getMinArgs() > entry->getMaxArgs())) continue; // overlap -- throw exception XMLBuffer buf; buf.set(X("Multiple functions have the same expanded QName and number of arguments {")); buf.append(func->getURI()); buf.append(X("}")); buf.append(func->getName()); buf.append(X("#")); if(func->getMinArgs() >= entry->getMinArgs() && func->getMinArgs() <= entry->getMaxArgs()) XPath2Utils::numToBuf((unsigned int)func->getMinArgs(), buf); else XPath2Utils::numToBuf((unsigned int)entry->getMinArgs(), buf); buf.append(X(" [err:XQST0034].")); XQThrow2(StaticErrorException,X("FunctionLookup::insertFunction"), buf.getRawBuffer()); } // Ok to add function size_t secondaryKey = SECONDARY_KEY(func); _funcTable.put((void*)func->getURINameHash(), (int)secondaryKey, func); }
Result XQNameExpression::createResult(DynamicContext* context, int flags) const { AnyAtomicType::Ptr itemName = getExpression()->createResult(context)->next(context); switch(itemName->getPrimitiveTypeIndex()) { case AnyAtomicType::QNAME: return (Item::Ptr)itemName; case AnyAtomicType::STRING: case AnyAtomicType::UNTYPED_ATOMIC: try { return (Item::Ptr)context->getItemFactory()->createDerivedFromAtomicType(AnyAtomicType::QNAME, itemName->asString(context), context); } catch(XQException &) { XQThrow(ASTException,X("XQNameExpression::NameExpressionResult::createResult"), X("The name expression cannot be converted to a xs:QName [err:XQDY0074]")); } default: break; } XMLBuffer buf; buf.set(X("The name expression must be a single xs:QName, xs:string or xs:untypedAtomic")); buf.append(X(" - found item of type ")); itemName->typeToBuffer(context, buf); buf.append(X(" [err:XPTY0004]")); XQThrow(XPath2TypeMatchException, X("XQNameExpression::NameExpressionResult::createResult"), buf.getRawBuffer()); }
ASTNode* FunctionLookup::lookUpFunction(const XMLCh* URI, const XMLCh* fname, const VectorOfASTNodes &args, XPath2MemoryManager* memMgr) const { if (this != g_globalFunctionTable) { ASTNode *ret = g_globalFunctionTable->lookUpFunction( URI, fname, args, memMgr); if (ret) return ret; } RefHash2KeysTableOfEnumerator<FuncFactory> iterator(const_cast<RefHash2KeysTableOf< FuncFactory >* >(&_funcTable)); // // Walk the matches for the primary key (name) looking for matches // based on allowable parameters // XMLBuffer key; key.set(fname); key.append(':'); key.append(URI); iterator.setPrimaryKey(key.getRawBuffer()); size_t nargs = args.size(); while(iterator.hasMoreElements()) { FuncFactory *entry= &(iterator.nextElement()); if (entry->getMinArgs() <= nargs && entry->getMaxArgs() >= nargs) return entry->createInstance(args, memMgr); } return NULL; }
const ExternalFunction *FunctionLookup::lookUpExternalFunction( const XMLCh* URI, const XMLCh* fname, size_t numArgs) const { size_t secondaryKey = numArgs; XMLBuffer key; key.set(fname); key.append(':'); key.append(URI); return _exFuncTable.get(key.getRawBuffer(), (int)secondaryKey); }
EventGenerator::Ptr XQCommentConstructor::generateEvents(EventHandler *events, DynamicContext *context, bool preserveNS, bool preserveType) const { XMLBuffer value; getStringValue(m_value, value, context); // Check for two dashes in a row, or a dash at the end if(xslt_) { XMLBuffer buf(value.getLen()); bool foundDash = false; const XMLCh *ptr = value.getRawBuffer(); const XMLCh *end = ptr + value.getLen(); while(ptr != end) { if(*ptr == chDash) { if(foundDash) { buf.append(' '); } foundDash = true; } else foundDash = false; buf.append(*ptr); ++ptr; } if(foundDash) { buf.append(' '); } value.set(buf.getRawBuffer()); } else { bool foundDash = false; const XMLCh *ptr = value.getRawBuffer(); const XMLCh *end = ptr + value.getLen(); while(ptr != end) { if(*ptr == chDash) { if(foundDash) break; foundDash = true; } else foundDash = false; ++ptr; } if(foundDash) XQThrow(ASTException,X("DOM Constructor"),X("It is a dynamic error if the result of the content expression of " "a computed comment constructor contains two adjacent hyphens or " "ends with a hyphen. [err:XQDY0072]")); } events->commentEvent(value.getRawBuffer()); return 0; }
virtual InputSource *resolveEntity(XMLResourceIdentifier* resourceIdentifier) { if(resourceIdentifier->getResourceIdentifierType() == XMLResourceIdentifier::UnKnown && XPath2Utils::equals(resourceIdentifier->getNameSpace(), m_PreviousModuleNamespace)) { XMLBuffer buf; buf.set(X("The graph of module imports contains a cycle for namespace '")); buf.append(resourceIdentifier->getNameSpace()); buf.append(X("' [err:XQST0073]")); XQThrow3(StaticErrorException, X("LoopDetector::resolveEntity"), buf.getRawBuffer(), m_location); } if(m_pParentResolver) return m_pParentResolver->resolveEntity(resourceIdentifier); return NULL; }
FunctionRef::Ptr FunctionRefImpl::partialApply(const Result &arg, unsigned int argNum, DynamicContext *context, const LocationInfo *location) const { if(getNumArgs() < argNum) { XMLBuffer buf; buf.set(X("The function item argument to fn:partial-apply() must have an arity of at least ")); XPath2Utils::numToBuf(argNum, buf); buf.append(X(" - found item of type ")); typeToBuffer(context, buf); buf.append(X(" [err:TBD]")); XQThrow3(XPath2TypeMatchException, X("FunctionRefImpl::partialApply"), buf.getRawBuffer(), location); } return new FunctionRefImpl(this, arg, argNum - 1, context); }
static void duplicateVariableError(const XQGlobalVariable *existing, const XQGlobalVariable *bad, MessageListener *mlistener) { if(mlistener) { mlistener->warning(X("In the context of this variable declaration"), existing); } XMLBuffer buf; buf.set(X("A variable with name {")); buf.append(bad->getVariableURI()); buf.append(X("}")); buf.append(bad->getVariableLocalName()); buf.append(X(" conflicts with an existing global variable [err:XQST0049].")); XQThrow3(StaticErrorException, X("XQQuery::staticResolution"), buf.getRawBuffer(), bad); }
const XMLCh *FunctionReplace::replace(const XMLCh *input, const XMLCh *pattern, const XMLCh *replacement, const XMLCh *options, MemoryManager *mm) { // Always turn off head character optimisation, since it is broken XMLBuffer optionsBuf; optionsBuf.set(options); optionsBuf.append(chLatin_H); //Now attempt to replace RegularExpression regEx(pattern, optionsBuf.getRawBuffer(), mm); #ifdef HAVE_ALLMATCHES return regEx.replace(input, replacement, mm); #else return regEx.replace(input, replacement); #endif }
Result FunctionRefImpl::execute(const VectorOfResults &args, DynamicContext *context, const LocationInfo *location) const { if(args.size() != getNumArgs()) { XMLBuffer buf; buf.set(X("The function item invoked does not accept ")); XPath2Utils::numToBuf((unsigned int)args.size(), buf); buf.append(X(" arguments - found item of type ")); typeToBuffer(context, buf); buf.append(X(" [err:XPTY0004]")); XQThrow3(XPath2TypeMatchException, X("FunctionRefImpl::execute"), buf.getRawBuffer(), location); } FunctionRefScope scope(this, args, context); AutoVariableStoreReset vsReset(context, &scope); return instance_->createResult(context); }
ASTNode *XQAtomize::staticTypingImpl(StaticContext *context) { _src.clear(); _src.getStaticType() = expr_->getStaticAnalysis().getStaticType(); _src.add(expr_->getStaticAnalysis()); if(expr_->getStaticAnalysis().isUpdating()) { XQThrow(StaticErrorException,X("XQAtomize::staticTyping"), X("It is a static error for an atomized expression " "to be an updating expression [err:XUST0001]")); } if(_src.getStaticType().isType(StaticType::FUNCTION_TYPE) && _src.getStaticType().getMin() > 0) { XMLBuffer buf; buf.set(X("Sequence does not match type (xs:anyAtomicType | node())*")); buf.append(X(" - the expression has a static type of ")); _src.getStaticType().typeToBuf(buf); buf.append(X(" [err:XPTY0004]")); XQThrow(XPath2TypeMatchException, X("XQAtomize::staticTyping"), buf.getRawBuffer()); } if(!_src.getStaticType().containsType(StaticType::NODE_TYPE|StaticType::FUNCTION_TYPE)) { // If the expression has no nodes, this function does nothing return substitute(expr_); } if(doPSVI_) { _src.getStaticType().substitute(StaticType::ELEMENT_TYPE | StaticType::ATTRIBUTE_TYPE, StaticType(StaticType::ANY_ATOMIC_TYPE, 0, StaticType::UNLIMITED)); } else { _src.getStaticType().substitute(StaticType::ELEMENT_TYPE | StaticType::ATTRIBUTE_TYPE, StaticType::UNTYPED_ATOMIC_TYPE); } _src.getStaticType().substitute(StaticType::DOCUMENT_TYPE | StaticType::TEXT_TYPE, StaticType::UNTYPED_ATOMIC_TYPE); _src.getStaticType().substitute(StaticType::NAMESPACE_TYPE | StaticType::COMMENT_TYPE | StaticType::PI_TYPE, StaticType::STRING_TYPE); // Remove function types _src.getStaticType() &= StaticType(StaticType::NODE_TYPE | StaticType::ANY_ATOMIC_TYPE, 0, StaticType::UNLIMITED); return this; }
Item::Ptr SequenceType::TypeMatchesResult::next(DynamicContext *context) { Item::Ptr item = _parent->next(context); if(item.isNull()) { _parent = 0; } else if(!_seqType->getItemType()->matches(item, context)) { XMLBuffer buf; buf.set(X("Sequence does not match type ")); _seqType->toBuffer(buf); buf.append(X(" - found item of type ")); item->typeToBuffer(context, buf); buf.append(X(" [")); buf.append(_errorCode); buf.append(X("]")); XQThrow(XPath2TypeMatchException, X("SequenceType::MatchesResult::next"), buf.getRawBuffer()); } return item; }
void RegExpFunction::copyRegExp(RegExpFunction* source, XPath2MemoryManager* memMgr) { if(source->regExp_) { pattern_ = memMgr->getPooledString(source->pattern_); options_ = memMgr->getPooledString(source->options_); // Always turn off head character optimisation, since it is broken XMLBuffer optionsBuf; optionsBuf.set(options_); optionsBuf.append(chLatin_H); //compiling regexp again try { regExp_ = new (memMgr) RegularExpression(pattern_, optionsBuf.getRawBuffer(), memMgr); } catch (ParseException &e){ processParseException(e, "RegExpFunction::copyRegExp", memMgr); } } }
bool XQQuery::staticTypingOnce(StaticTyper *styper) { switch(m_staticTyped) { case AFTER: return false; case DURING: { XMLBuffer buf; buf.set(X("The graph of module imports contains a cycle for namespace '")); buf.append(getModuleTargetNamespace()); buf.append(X("' [err:XQST0093]")); XQThrow2(StaticErrorException, X("XQQuery::staticResolution"), buf.getRawBuffer()); } case BEFORE: break; } m_staticTyped = DURING; staticTyping(styper); m_staticTyped = AFTER; m_moduleCache->ordered_.push_back(this); return true; }
ASTNode *ArithmeticOperator::staticTypingImpl(StaticContext *context) { _src.clear(); bool emptyArgument = false; for(VectorOfASTNodes::iterator i = _args.begin(); i != _args.end(); ++i) { if((*i)->getStaticAnalysis().isUpdating()) { XQThrow(StaticErrorException,X("ArithmeticOperator::staticTyping"), X("It is a static error for an operand of an operator " "to be an updating expression [err:XUST0001]")); } if((*i)->getStaticAnalysis().getStaticType().getMin() == 0) emptyArgument = true; _src.add((*i)->getStaticAnalysis()); if((*i)->isDateOrTimeAndHasNoTimezone(context)) _src.implicitTimezoneUsed(true); } _src.getStaticType() = StaticType(); calculateStaticType(); if(!emptyArgument && _src.getStaticType().getMax() == 0) { XMLBuffer errMsg; errMsg.set(X("The operator ")); errMsg.append(_opName); errMsg.append(X(" has been called on invalid operand types [err:XPTY0004]")); XQThrow(XPath2ErrorException,X("ArithmeticOperator::staticResolution"), errMsg.getRawBuffer()); } if(emptyArgument) _src.getStaticType().setCardinality(0, 1); else _src.getStaticType().setCardinality(1, 1); return this; }
ASTNode *XQNameExpression::staticTypingImpl(StaticContext *context) { _src.clear(); _src.getStaticType() = StaticType::QNAME_TYPE; _src.add(expr_->getStaticAnalysis()); if(expr_->getStaticAnalysis().getStaticType().isType(StaticType::QNAME_TYPE)) { return expr_; } if(!expr_->getStaticAnalysis().getStaticType(). containsType(StaticType::QNAME_TYPE|StaticType::STRING_TYPE|StaticType::UNTYPED_ATOMIC_TYPE)) { XMLBuffer buf; buf.set(X("The name expression must be a single xs:QName, xs:string or xs:untypedAtomic")); buf.append(X(" - the expression has a static type of ")); expr_->getStaticAnalysis().getStaticType().typeToBuf(buf); buf.append(X(" [err:XPTY0004]")); XQThrow(XPath2TypeMatchException, X("XQNameExpression::staticTyping"), buf.getRawBuffer()); } return this; }
Item::Ptr SequenceType::OccurrenceMatchesResult::next(DynamicContext *context) { Item::Ptr item = _parent->next(context); // "SequenceType matching between a given value and a given SequenceType is performed as follows: // If the SequenceType is empty, the match succeeds only if the value is an empty sequence." if(_seqType->getItemType() == NULL && item.notNull()) { XMLBuffer buf; buf.set(X("Sequence does not match type ")); _seqType->toBuffer(buf); buf.append(X(" - the sequence contains items [")); buf.append(X(" [")); buf.append(_errorCode); buf.append(X("]")); XQThrow(XPath2TypeMatchException, X("SequenceType::OccurrenceMatchesResult::next"), buf.getRawBuffer()); } // "If the SequenceType contains an ItemType and an OccurrenceIndicator, the match succeeds only if // the number of items in the value matches the OccurrenceIndicator and each of these items matches the ItemType. " if(_seqType->getItemType() && (_seqType->getOccurrenceIndicator() == PLUS || _seqType->getOccurrenceIndicator() == EXACTLY_ONE) && item.isNull()) { XMLBuffer buf; buf.set(X("Sequence does not match type ")); _seqType->toBuffer(buf); buf.append(X(" - the sequence does not contain items [")); buf.append(_errorCode); buf.append(X("]")); XQThrow(XPath2TypeMatchException, X("SequenceType::OccurrenceMatchesResult::next"), buf.getRawBuffer()); } // "If the SequenceType is an ItemType with no OccurrenceIndicator, the match succeeds only if // the value contains precisely one item and that item matches the ItemType " if(_seqType->getItemType() && (_seqType->getOccurrenceIndicator() == EXACTLY_ONE || _seqType->getOccurrenceIndicator() == QUESTION_MARK) && item.notNull()) { // Do the tests on the number of items up front, // since often functions that cast to a single or // optional item only call next once. - jpcs Item::Ptr second = _parent->next(context); if(second.isNull()) { _parent = 0; } else { XMLBuffer buf; buf.set(X("Sequence does not match type ")); _seqType->toBuffer(buf); buf.append(X(" - the sequence contains more than one item [")); buf.append(_errorCode); buf.append(X("]")); XQThrow(XPath2TypeMatchException, X("SequenceType::OccurrenceMatchesResult::next"), buf.getRawBuffer()); } } if(item.isNull()) { *resultPointer_ = 0; } else { *resultPointer_ = _parent; } return item; }
void XQQuery::importModule(const XMLCh* szUri, VectorOfStrings* locations, const LocationInfo *location) { for(ImportedModules::iterator modIt = m_importedModules.begin(); modIt != m_importedModules.end(); ++modIt) { if(XPath2Utils::equals((*modIt)->getModuleTargetNamespace(),szUri)) { XMLBuffer buf; 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); } } // Search in the module cache XQQuery *module = 0; if(!XPath2Utils::equals(szUri, m_szTargetNamespace)) { module = m_moduleCache->getByNamespace(szUri); if(module != 0) { importModule(module); return; } } if(locations == NULL) locations = m_context->resolveModuleURI(szUri); if(locations == NULL || locations->empty()) { XMLBuffer buf; 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); } for(VectorOfStrings::iterator it=locations->begin();it!=locations->end();++it) { module = parseModule(szUri, *it, location); if(!module->getIsLibraryModule()) { XMLBuffer buf; buf.set(X("The module at ")); buf.append(module->getFile()); buf.append(X(" is not a module")); XQThrow3(StaticErrorException, X("XQQuery::ImportModule"), buf.getRawBuffer(), location); } if(!XERCES_CPP_NAMESPACE::XMLString::equals(szUri, module->getModuleTargetNamespace())) { XMLBuffer buf; buf.set(X("The module at ")); buf.append(module->getFile()); buf.append(X(" specifies a different namespace [err:XQST0059]")); XQThrow3(StaticErrorException, X("XQQuery::ImportModule"), buf.getRawBuffer(), location); } } // Search in the module cache again, to get the head of the linked list of modules module = m_moduleCache->getByNamespace(szUri); if(!module) { XMLBuffer buf; 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); } importModule(module); }
void XQUserFunction::staticResolutionStage1(StaticContext *context) { XPath2MemoryManager *mm = context->getMemoryManager(); resolveName(context); if(name_ != 0 && !isTemplate_ && !delayed_) { if(XPath2Utils::equals(uri_, XMLUni::fgXMLURIName) || XPath2Utils::equals(uri_, SchemaSymbols::fgURI_SCHEMAFORSCHEMA) || XPath2Utils::equals(uri_, SchemaSymbols::fgURI_XSI) || XPath2Utils::equals(uri_, XQFunction::XMLChFunctionURI) || XPath2Utils::equals(uri_, SchemaSymbols::fgURI_SCHEMAFORSCHEMA)) { XQThrow(FunctionException, X("XQUserFunction::staticResolutionStage1"), X("A user defined function must not be in the namespaces xml, xsd, xsi, fn or xdt [err:XQST0045]")); } else if(uri_ == 0 || *uri_ == 0) XQThrow(FunctionException, X("XQUserFunction::staticResolutionStage1"), X("A user defined function must be defined in a namespace [err:XQST0060]")); } // Check for the implementation of an external function if(body_ == NULL) { exFunc_ = context->lookUpExternalFunction(uri_, name_, minArgs_); if(exFunc_ == NULL) { XMLBuffer buf; buf.set(X("External function '{")); buf.append(uri_); buf.append(X("}")); buf.append(name_); buf.append(X("' with ")); XMLCh szNumBuff[20]; XMLString::binToText((unsigned int)minArgs_, szNumBuff, 19, 10); buf.append(szNumBuff); buf.append(X(" argument(s) has not been bound to an implementation")); XQThrow(FunctionException, X("XQUserFunction::staticResolutionStage1"), buf.getRawBuffer()); } } signature_->staticResolution(context); // Resolve the mode names if(modes_) { if(modes_->empty()) { XQThrow(StaticErrorException, X("XQUserFunction::staticResolution"), X("At least one mode must be specified for a template [err:XTSE0550]")); } ModeList::iterator it, it2; for(it = modes_->begin(); it != modes_->end(); ++it) { (*it)->staticResolution(context); // Check for "#all" with other values if((*it)->getState() == Mode::ALL && modes_->size() != 1) { XQThrow3(StaticErrorException, X("XQUserFunction::staticResolution"), X("The mode #all must not be specified in addition to other modes [err:XTSE0550]"), *it); } // Check for duplicate modes it2 = it; for(++it2; it2 != modes_->end(); ++it2) { if((*it)->getState() == (*it2)->getState() && XPath2Utils::equals((*it)->getName(), (*it2)->getName()) && XPath2Utils::equals((*it)->getURI(), (*it2)->getURI())) { XMLBuffer buf; buf.append(X("The mode {")); buf.append((*it)->getURI()); buf.append(X("}")); buf.append((*it)->getName()); buf.append(X(" has been specified more than once [err:XTSE0550]")); XQThrow3(StaticErrorException, X("XQUserFunction::staticResolution"), buf.getRawBuffer(), *it2); } } } } // Set up a default StaticType and StaticAnalysis if(signature_->returnType) { if(body_ != NULL) { body_ = signature_->returnType->convertFunctionArg(body_, context, /*numericfunction*/false, signature_->returnType); } bool isPrimitive; signature_->returnType->getStaticType(src_.getStaticType(), context, isPrimitive, signature_->returnType); } else { // Default type is item()* src_.getStaticType() = StaticType(StaticType::ITEM_TYPE, 0, StaticType::UNLIMITED); } if(signature_->updating == FunctionSignature::OP_TRUE) { src_.updating(true); } // TBD What about the other parts of the StaticAnalysis - jpcs src_.forceNoFolding(true); if(pattern_ != 0 && !pattern_->empty()) { // Set the pattern's initial static type to NODE_TYPE VectorOfASTNodes::iterator patIt = pattern_->begin(); for(; patIt != pattern_->end(); ++patIt) { const_cast<StaticAnalysis&>((*patIt)->getStaticAnalysis()).getStaticType() = StaticType(StaticType::NODE_TYPE, 0, StaticType::UNLIMITED); } } if(isTemplate_) { // Build an instance of the template for us to call VectorOfASTNodes newArgs = VectorOfASTNodes(XQillaAllocator<ASTNode*>(mm)); if(signature_->argSpecs != 0) { ArgumentSpecs::const_iterator argIt; for(argIt = signature_->argSpecs->begin(); argIt != signature_->argSpecs->end(); ++argIt) { XQVariable *argVar = new (mm) XQVariable((*argIt)->getURI(), (*argIt)->getName(), mm); argVar->setLocationInfo(*argIt); newArgs.push_back(argVar); } } templateInstance_ = createInstance(newArgs, mm); templateInstance_->setLocationInfo(this); } }
Sequence FunctionUnparsedText::createSequence(DynamicContext* context, int flags) const { Item::Ptr uriArg = getParamNumber(1, context)->next(context); if(uriArg.isNull()) { return Sequence(context->getMemoryManager()); } const XMLCh *uri = uriArg->asString(context); if(!XPath2Utils::isValidURI(uri, context->getMemoryManager())) XQThrow(FunctionException, X("FunctionUnparsedText::createSequence"), X("The argument to fn:unparsed-text() is not a valid URI [err:XTDE1170]")); // TBD Implement a URIResolver method for resolving unparsed text - jpcs const XMLCh *baseUri = context->getBaseURI(); InputSource *srcToUse = 0; if(context->getXMLEntityResolver()){ XMLResourceIdentifier resourceIdentifier(XMLResourceIdentifier::UnKnown, uri, 0, XMLUni::fgZeroLenString, baseUri); srcToUse = context->getXMLEntityResolver()->resolveEntity(&resourceIdentifier); } if(srcToUse == 0) { try { // Resolve the uri against the base uri XMLURL urlTmp; if(baseUri && *baseUri) { urlTmp.setURL(baseUri, uri); } else { urlTmp.setURL(uri); } srcToUse = new URLInputSource(urlTmp); } catch(const MalformedURLException &e) { } } if(srcToUse == 0) { // It's not a URL, so let's assume it's a local file name. if(baseUri && *baseUri) { AutoDeallocate<XMLCh> tmpBuf(XMLPlatformUtils::weavePaths(baseUri, uri), XMLPlatformUtils::fgMemoryManager); srcToUse = new LocalFileInputSource(tmpBuf); } else { srcToUse = new LocalFileInputSource(uri); } } Janitor<InputSource> janIS(srcToUse); if(getNumArgs() == 2) { const XMLCh *encoding = getParamNumber(2, context)->next(context)->asString(context); srcToUse->setEncoding(encoding); } XMLBuffer result; try { BinInputStream *stream = srcToUse->makeStream(); if(stream == NULL) { XMLBuffer buf; buf.set(X("Cannot read unparsed content from ")); buf.append(uri); buf.append(X(" [err:XTDE1170]")); XQThrow2(FunctionException,X("FunctionUnparsedText::createSequence"), buf.getRawBuffer()); } Janitor<BinInputStream> janStream(stream); #ifdef HAVE_GETCONTENTTYPE if(FunctionMatches::matches(stream->getContentType(), X("(text|application)/(xml|[^ +;]+\\+xml)"), X("i"))) { srcToUse->setEncoding(0); srcToUse->setEncoding(FindXMLEncoding().start(*srcToUse, context)); } #endif XPath2Utils::readSource(stream, context->getMemoryManager(), result, srcToUse->getEncoding()); } catch(XMLException &e) { XMLBuffer buf; buf.set(X("Exception reading unparsed content: ")); buf.append(e.getMessage()); buf.append(X(" [err:XTDE1190]")); XQThrow2(FunctionException,X("FunctionUnparsedText::createSequence"), buf.getRawBuffer()); } return Sequence(context->getItemFactory()->createString(result.getRawBuffer(), context), context->getMemoryManager()); }
void SequenceType::ItemType::staticResolution(StaticContext *context, const LocationInfo *location) { // Prefix resolution should only happen once // (since SequenceType objects can be multiple times in the AST) if(!staticallyResolved_) { staticallyResolved_ = true; if(m_pType && m_TypeURI == 0) { const XMLCh *prefix = m_pType->getPrefix(); // an empty prefix means the default element and type namespace if(prefix == 0 || *prefix == 0) { m_TypeURI = context->getDefaultElementAndTypeNS(); } else { m_TypeURI = context->getUriBoundToPrefix(prefix, location); } } if(m_pName && m_NameURI == 0) { const XMLCh *prefix = m_pName->getPrefix(); // if we are testing for an attribute, an empty prefix means empty namespace; if we are testing an element, it means // the default element and type namespace if(prefix == 0 || *prefix == 0) { if(m_nTestType == TEST_ELEMENT || m_nTestType == TEST_SCHEMA_ELEMENT || m_nTestType == TEST_DOCUMENT || m_nTestType == TEST_SCHEMA_DOCUMENT) m_NameURI = context->getDefaultElementAndTypeNS(); } else { m_NameURI = context->getUriBoundToPrefix(prefix, location); } } } if(m_pType) { if(m_nTestType == ItemType::TEST_ATOMIC_TYPE) { // check if the type to be tested is defined and is really an atomic one if(!context->getDocumentCache()->isTypeDefined(m_TypeURI, m_pType->getName())) { XMLBuffer buf; buf.set(X("Type {")); buf.append(m_TypeURI); buf.append(X("}:")); buf.append(m_pType->getName()); buf.append(X(" is not defined [err:XPST0051]")); XQThrow3(StaticErrorException, X("SequenceType::ItemType::staticResolution"), buf.getRawBuffer(), location); } if(!context->getDocumentCache()->isTypeOrDerivedFromType(m_TypeURI, m_pType->getName(), FunctionConstructor::XMLChXPath2DatatypesURI, AnyAtomicType::fgDT_ANYATOMICTYPE)) { XMLBuffer buf; buf.set(X("Type {")); buf.append(m_TypeURI); buf.append(X("}:")); buf.append(m_pType->getName()); buf.append(X(" is not an atomic type [err:XPST0051]")); XQThrow3(StaticErrorException, X("SequenceType::ItemType::staticResolution"), buf.getRawBuffer(), location); } } else if(!context->getDocumentCache()->isTypeDefined(m_TypeURI, m_pType->getName())) { XMLBuffer msg; msg.set(X("Type {")); msg.append(m_TypeURI); msg.append(X("}")); msg.append(m_pType->getName()); msg.append(X(" is not defined [err:XPTY0004]")); XQThrow3(XPath2ErrorException,X("SequenceType::ItemType::matchesNameType"), msg.getRawBuffer(), location); } } switch(m_nTestType) { case TEST_SCHEMA_DOCUMENT: case TEST_SCHEMA_ELEMENT: { // retrieve the type of the element name SchemaElementDecl *elemDecl = context->getDocumentCache()->getElementDecl(m_NameURI, m_pName->getName()); if(elemDecl == NULL) { XMLBuffer msg(1023, context->getMemoryManager()); msg.set(X("Element {")); msg.append(m_NameURI); msg.append(X("}")); msg.append(m_pName->getName()); msg.append(X(" is not defined as a global element [err:XPST0081]")); XQThrow3(StaticErrorException,X("SequenceType::ItemType::staticResolution"), msg.getRawBuffer(), location); } break; } case TEST_SCHEMA_ATTRIBUTE: { // retrieve the type of the attribute name SchemaAttDef *attrDecl = context->getDocumentCache()->getAttributeDecl(m_NameURI, m_pName->getName()); if(attrDecl == NULL) { XMLBuffer msg(1023, context->getMemoryManager()); msg.set(X("Attribute {")); msg.append(m_NameURI); msg.append(X("}")); msg.append(m_pName->getName()); msg.append(X(" is not defined as a global attribute [err:XPST0081]")); XQThrow3(StaticErrorException,X("SequenceType::ItemType::staticResolution"), msg.getRawBuffer(), location); } break; } default: break; } if(returnType_) returnType_->staticResolution(context); }
int main(int /*argc*/, char ** /*argv*/) { Normalizer *normalizer = new Normalizer(); DOMDocument *doc = normalizer->createDocument(); bool *tmpTrue = new bool(true); bool *tmpFalse = new bool(false); DOMElement* docFirstElement = doc->createElementNS(X("http://www.test.com"),X("docEle")); doc->appendChild(docFirstElement); DOMElement* docFirstElementChild = doc->createElementNS(X("http://www.test2.com"),X("docEleChild")); docFirstElement->appendChild(docFirstElementChild); //create default ns doc->normalizeDocument(); normalizer->serializeNode(doc); XERCES_STD_QUALIFIER cout << "\n\n"; //add in binding docFirstElement->setPrefix(X("po")); doc->normalizeDocument(); normalizer->serializeNode(doc); XERCES_STD_QUALIFIER cout << "\n\n"; //use default DOMElement* docFirstElementChildChild = doc->createElementNS(X("http://www.test2.com"),X("docEleChildChild")); docFirstElementChild->appendChild(docFirstElementChildChild); doc->normalizeDocument(); normalizer->serializeNode(doc); XERCES_STD_QUALIFIER cout << "\n\n"; // this block is needed to destroy the XMLBuffer { //use a binding XMLBuffer buf; buf.set(XMLUni::fgXMLNSString); buf.append(chColon); buf.append(X("po2")); docFirstElementChild->removeAttributeNS(XMLUni::fgXMLNSURIName, XMLUni::fgXMLNSString); docFirstElement->removeAttributeNS(XMLUni::fgXMLNSURIName, XMLUni::fgXMLNSString); docFirstElement->setAttributeNS(XMLUni::fgXMLNSURIName, buf.getRawBuffer(), X("http://www.test2.com")); docFirstElementChild->setPrefix(X("po2")); doc->normalizeDocument(); normalizer->serializeNode(doc); XERCES_STD_QUALIFIER cout << "\n\n"; } //some siblngs to ensure the scope stacks are working docFirstElementChildChild = doc->createElementNS(X("http://www.test3.com"),X("docEleChildChild2")); docFirstElementChild->appendChild(docFirstElementChildChild); docFirstElementChildChild = doc->createElementNS(X("http://www.test4.com"),X("po4:docEleChildChild3")); docFirstElementChild->appendChild(docFirstElementChildChild); docFirstElementChildChild = doc->createElementNS(X("http://www.test4.com"),X("po4:docEleChildChild4")); docFirstElementChild->appendChild(docFirstElementChildChild); doc->normalizeDocument(); normalizer->serializeNode(doc); XERCES_STD_QUALIFIER cout << "\n\n"; //conflicting prefix docFirstElementChildChild->setAttributeNS(XMLUni::fgXMLNSURIName, X("po4"), X("conflict")); doc->normalizeDocument(); normalizer->serializeNode(doc); XERCES_STD_QUALIFIER cout << "\n\n"; //conflicting default docFirstElementChildChild = doc->createElementNS(X("http://www.test4.com"),X("docEleChildChild5")); docFirstElementChild->appendChild(docFirstElementChildChild); docFirstElementChildChild->setAttributeNS(XMLUni::fgXMLNSURIName, XMLUni::fgXMLNSString, X("conflict")); doc->normalizeDocument(); normalizer->serializeNode(doc); XERCES_STD_QUALIFIER cout << "\n\n"; //set the xmlns to "" DOMElement *noNamespaceEle = doc->createElementNS(X(""),X("noNamespace")); docFirstElementChildChild->appendChild(noNamespaceEle); doc->normalizeDocument(); normalizer->serializeNode(doc); XERCES_STD_QUALIFIER cout << "\n\n"; //now lets do a bit off attribute testing on the doc ele docFirstElement->setAttributeNS(X("http://testattr.com"), X("attr1"), X("value")); docFirstElement->setAttributeNS(X("http://testattr.com"), X("attr2"), X("value")); docFirstElement->setAttributeNS(X("http://testattr2.com"), X("attr3"), X("value")); docFirstElement->setAttributeNS(X("http://www.test.com"), X("attr4"), X("value")); docFirstElement->setAttributeNS(X("http://testattr2.com"), X("po:attr5"), X("value")); docFirstElement->setAttributeNS(X("http://testattr2.com"), X("poFake:attr6"), X("value")); docFirstElement->setAttributeNS(X("http://testattr3.com"), X("po3:attr7"), X("value")); doc->normalizeDocument(); normalizer->serializeNode(doc); XERCES_STD_QUALIFIER cout << "\n\n"; //and now on one of its children docFirstElementChildChild->setAttributeNS(X("http://testattr.com"), X("attr1"), X("value")); docFirstElementChildChild->setAttributeNS(X("http://testattr.com"), X("attr2"), X("value")); docFirstElementChildChild->setAttributeNS(X("http://testattr2.com"), X("attr3"), X("value")); docFirstElementChildChild->setAttributeNS(X("http://www.test.com"), X("attr4"), X("value")); docFirstElementChildChild->setAttributeNS(X("http://testattr2.com"), X("po:attr5"), X("value")); docFirstElementChildChild->setAttributeNS(X("http://testattr2.com"), X("poFake:attr6"), X("value")); docFirstElementChildChild->setAttributeNS(X("http://testattr3.com"), X("po3:attr7"), X("value")); docFirstElementChildChild->setAttributeNS(X("http://testattr4.com"), X("po4:attr8"), X("value")); //test for a clash with our NSx attrs docFirstElementChildChild->setAttributeNS(X("http://testclash.com"), X("NS1:attr9"), X("value")); docFirstElementChildChild->setAttributeNS(XMLUni::fgXMLNSURIName, X("xmlns:NS1"), X("http://testclash.com")); //clash with standard prefix docFirstElementChildChild->setAttributeNS(X("http://testattr5.com"), X("po:attr10"), X("value")); doc->normalizeDocument(); normalizer->serializeNode(doc); XERCES_STD_QUALIFIER cout << "\n\n"; //2 prefix with the same uri docFirstElementChildChild = doc->createElementNS(X("http://www.uri1.com"),X("docEleChildChild6")); docFirstElementChild->appendChild(docFirstElementChildChild); docFirstElementChildChild->setAttributeNS(XMLUni::fgXMLNSURIName, X("xmlns:uri1"), X("http://www.uri1.com")); docFirstElementChildChild->setAttributeNS(XMLUni::fgXMLNSURIName, X("xmlns:uri1b"), X("http://www.uri1.com")); docFirstElementChildChild->setAttributeNS(X("http://www.uri1.com"), X("uri1:attr1"), X("value")); docFirstElementChildChild->setAttributeNS(X("http://www.uri1.com"), X("uri1b:attr2"), X("value")); doc->normalizeDocument(); normalizer->serializeNode(doc); XERCES_STD_QUALIFIER cout << "\n\n"; //check to see we use the nearest binding and for more inheritence DOMElement *docFirstElementChildChildChild = doc->createElementNS(X("http://www.uri1.com"),X("docEleChildChildChild")); docFirstElementChildChild->appendChild(docFirstElementChildChildChild); docFirstElementChildChild->setAttributeNS(XMLUni::fgXMLNSURIName, X("xmlns:nearerThanPo"), X("http://www.test.com")); docFirstElementChildChildChild->setAttributeNS(X("http://testattr.com"), X("attr2"), X("value")); docFirstElementChildChildChild->setAttributeNS(X("http://www.test.com"), X("attr1"), X("value")); doc->normalizeDocument(); normalizer->serializeNode(doc); XERCES_STD_QUALIFIER cout << "\n\n"; //NS1.1 stuff //test creating default prefix when NS1 has been set to "" noNamespaceEle->setAttributeNS(XMLUni::fgXMLNSURIName, X("xmlns:NS1"), X("")); DOMElement *noNamespaceChild = doc->createElementNS(X("http://testclash.com"),X("testing1.1Stuff")); noNamespaceEle->appendChild(noNamespaceChild); doc->normalizeDocument(); normalizer->serializeNode(doc); noNamespaceChild = doc->createElementNS(X("http://testclash.com"),X("NS1:testing1.1Stuff")); noNamespaceEle->appendChild(noNamespaceChild); noNamespaceChild->setAttributeNS(X("http://www.someRandomUri.com"), X("attr"), X("value")); doc->normalizeDocument(); normalizer->serializeNode(doc); //check error conditions XERCES_STD_QUALIFIER cout << "error conditions" << XERCES_STD_QUALIFIER endl; DOMConfiguration *conf = doc->getDOMConfig(); conf->setParameter(XMLUni::fgDOMErrorHandler, normalizer); conf->setParameter(XMLUni::fgDOMNamespaces, true); DOMElement *level1Node = doc->createElement(X("level1Node")); docFirstElement->appendChild(level1Node); doc->normalizeDocument(); docFirstElement->removeChild(level1Node); docFirstElement->setAttribute(X("level1Attr"), X("level1")); doc->normalizeDocument(); docFirstElement->removeAttribute(X("level1Attr")); //cant check this as Xerces does not let us do it // noNamespaceChild->setAttributeNS(X("http://www.someRandomUri.com"), X("xmlns"), X("value")); // doc->normalizeDocument(); //lets do a sanity test on a comment DOMComment *comment = doc->createComment(X("some comment")); docFirstElement->appendChild(comment); doc->normalizeDocument(); normalizer->serializeNode(doc); conf->setParameter(XMLUni::fgDOMComments, false); docFirstElement->appendChild(comment); doc->normalizeDocument(); normalizer->serializeNode(doc); //and on a CDATA DOMCDATASection *cData = doc->createCDATASection(X("some cdata")); docFirstElement->appendChild(cData); doc->normalizeDocument(); normalizer->serializeNode(doc); conf->setParameter(XMLUni::fgDOMCDATASections, false); docFirstElement->appendChild(cData); doc->normalizeDocument(); normalizer->serializeNode(doc); delete normalizer; delete tmpTrue; delete tmpFalse; return 0; }