Esempio n. 1
0
BoolResult FunctionContains::boolResult(DynamicContext* context) const
{
    Sequence str1 = getParamNumber(1,context)->toSequence(context);
    Sequence str2 = getParamNumber(2,context)->toSequence(context);

    Collation* collation = NULL;
    if(getNumArgs()>2) {
        Sequence collArg = getParamNumber(3,context)->toSequence(context);
        const XMLCh* collName = collArg.first()->asString(context);
        try {
            context->getItemFactory()->createAnyURI(collName, context);
        } catch(XPath2ErrorException &e) {
            XQThrow(FunctionException, X("FunctionContains::createSequence"), X("Invalid collationURI"));  
        }
        collation=context->getCollation(collName, this);
        if(collation==NULL)
            XQThrow(FunctionException,X("FunctionContains::createSequence"),X("Collation object is not available"));
    }
    else
        collation=context->getCollation(CodepointCollation::getCodepointCollationName(), this);

    const XMLCh* container = XMLUni::fgZeroLenString;
    if(!str1.isEmpty())
        container=str1.first()->asString(context);
    const XMLCh* pattern = XMLUni::fgZeroLenString;
    if(!str2.isEmpty())
        pattern=str2.first()->asString(context);

    if(XMLString::stringLen(pattern)==0) return true;
    else if(XMLString::stringLen(container)==0) return false;

    return XMLString::patternMatch(container, pattern) > -1;
}
Esempio n. 2
0
Item::Ptr Multiply::execute(const AnyAtomicType::Ptr &atom1, const AnyAtomicType::Ptr &atom2, DynamicContext *context) const
{
  if(atom1.isNull() || atom2.isNull()) return 0;

  // xs:double * xs:duration (only xdt:dayTimeDuration and xdt:yearMonthDuration)
  if(atom1->isNumericValue() &&
     (atom2->getPrimitiveTypeIndex() == AnyAtomicType::DAY_TIME_DURATION ||
      atom2->getPrimitiveTypeIndex() == AnyAtomicType::YEAR_MONTH_DURATION)) {
      return ((const ATDurationOrDerived*)atom2.get())->multiply((const Numeric*)atom1.get(), context);
  }
  // xs:duration * xs:double (only xdt:dayTimeDuration and xdt:yearMonthDuration)
  if(atom2->isNumericValue() &&
     (atom1->getPrimitiveTypeIndex() == AnyAtomicType::DAY_TIME_DURATION ||
      atom1->getPrimitiveTypeIndex() == AnyAtomicType::YEAR_MONTH_DURATION)) {
    return ((const ATDurationOrDerived*)atom1.get())->multiply((const Numeric*)atom2.get(), context);
  }

  // numeric * numeric
  if(atom1->isNumericValue()) {
    if(atom2->isNumericValue()) {
      return ((const Numeric*)atom1.get())->multiply((const Numeric*)atom2.get(), context);
    }
    else {
      XQThrow(XPath2ErrorException,X("Multiply::createSequence"), X("An attempt to multiply a non numeric type to a numeric type has occurred [err:XPTY0004]"));
    }
  }

  XQThrow(XPath2ErrorException,X("Multiply::createSequence"), X("The operator * has been called on invalid operand types [err:XPTY0004]"));

}
Esempio n. 3
0
Item::Ptr Divide::execute(const AnyAtomicType::Ptr &atom1, const AnyAtomicType::Ptr &atom2, DynamicContext *context) const
{
  if(atom1 == NULLRCP || atom2 == NULLRCP) return 0;
  
  if(atom1->isNumericValue()) {
    if(atom2->isNumericValue()) {
      return (const Item::Ptr)((Numeric*)(const AnyAtomicType*)atom1)->divide((const Numeric::Ptr )atom2, context);
    }
    else {
      XQThrow(XPath2ErrorException,X("Divide::createSequence"), X("An attempt to divide a numeric type by a non-numeric type has occurred [err:XPTY0004]"));
    }
  }

  if(atom1->getPrimitiveTypeIndex() == AnyAtomicType::DAY_TIME_DURATION ||
     atom1->getPrimitiveTypeIndex() == AnyAtomicType::YEAR_MONTH_DURATION) {
    const ATDurationOrDerived* duration = (const ATDurationOrDerived*)atom1.get();
    if(atom2->isNumericValue()) {
      return (const Item::Ptr)duration->divide((const Numeric *)atom2.get(), context);
    }
    else if(atom2->getPrimitiveTypeIndex() == AnyAtomicType::DAY_TIME_DURATION ||
              atom2->getPrimitiveTypeIndex() == AnyAtomicType::YEAR_MONTH_DURATION) {
      return (const Item::Ptr)duration->divide((const ATDurationOrDerived*)atom2.get(), context);
    }
    else {
      XQThrow(XPath2ErrorException,X("Divide::createSequence"), X("An attempt to divide an xs:duration by an invalid type has occured [err:XPTY0004]"));
    }
  }
  else {
    XQThrow(XPath2ErrorException,X("Divide::createSequence"), X("The operator div has been called on invalid operand types [err:XPTY0004]"));
  }

  return 0;
}
Esempio n. 4
0
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 *XQNamespaceConstructor::staticTypingImpl(StaticContext *context)
{
  _src.clear();

  _src.add(m_name->getStaticAnalysis());

  if(m_name->getStaticAnalysis().isUpdating()) {
    XQThrow(StaticErrorException,X("XQNamespaceConstructor::staticTyping"),
            X("It is a static error for the name expression of an namespace constructor "
              "to be an updating expression [err:XUST0001]"));
  }

  unsigned int i;
  for(i = 0; i < m_children->size(); ++i) {
    _src.add((*m_children)[i]->getStaticAnalysis());

    if((*m_children)[i]->getStaticAnalysis().isUpdating()) {
      XQThrow(StaticErrorException,X("XQNamespaceConstructor::staticTyping"),
              X("It is a static error for the a value expression of an namespace constructor "
                "to be an updating expression [err:XUST0001]"));
    }
  }

  _src.getStaticType() = StaticType::NAMESPACE_TYPE;
  _src.creative(true);
  _src.setProperties(StaticAnalysis::DOCORDER | StaticAnalysis::GROUPED |
                     StaticAnalysis::PEER | StaticAnalysis::SUBTREE | StaticAnalysis::SAMEDOC |
                     StaticAnalysis::ONENODE);
  return this;
}
Esempio n. 6
0
ASTNode *UTransform::staticTypingImpl(StaticContext *context)
{
    _src.clear();

    // Add all the binding variables to the new scope
    VectorOfCopyBinding::iterator end = bindings_->end();
    for(VectorOfCopyBinding::iterator it0 = bindings_->begin(); it0 != end; ++it0) {
        if((*it0)->expr_->getStaticAnalysis().isUpdating()) {
            XQThrow(StaticErrorException,X("UTransform::staticTyping"),
                    X("It is a static error for the copy expression of a transform expression "
                      "to be an updating expression [err:XUST0001]"));
        }
    }

    // Call staticTyping on the modify expression
    _src.add(modify_->getStaticAnalysis());
    _src.updating(false);

    if(!modify_->getStaticAnalysis().isUpdating() && !modify_->getStaticAnalysis().isPossiblyUpdating())
        XQThrow(StaticErrorException, X("UTransform::staticTyping"),
                X("The modify expression is not an updating expression [err:XUST0002]"));

    // Call staticResolution on the return expression
    _src.getStaticType() = return_->getStaticAnalysis().getStaticType();
    _src.setProperties(return_->getStaticAnalysis().getProperties());
    _src.add(return_->getStaticAnalysis());

    if(return_->getStaticAnalysis().isUpdating()) {
        XQThrow(StaticErrorException,X("UTransform::staticTyping"),
                X("It is a static error for the return expression of a transform expression "
                  "to be an updating expression [err:XUST0001]"));
    }

    VectorOfCopyBinding *newBindings = context == 0 ? 0 :
                                       new (context->getMemoryManager()) VectorOfCopyBinding(XQillaAllocator<CopyBinding*>(context->getMemoryManager()));

    VectorOfCopyBinding::reverse_iterator rend = bindings_->rend();
    for(VectorOfCopyBinding::reverse_iterator it = bindings_->rbegin(); it != rend; ++it) {
        // Remove our binding variable from the StaticAnalysis data (removing it if it's not used)
        if(!_src.removeVariable((*it)->uri_, (*it)->name_)) {
            (*it)->qname_ = 0;
        }

        _src.add((*it)->expr_->getStaticAnalysis());

        // Add the new VB at the front of the new Bindings
        // (If it's a let binding, and it's variable isn't used, don't add it - there's no point)
        if(newBindings && (*it)->qname_) {
            CopyBinding *newVB = new (context->getMemoryManager()) CopyBinding(context->getMemoryManager(), **it);
            newVB->setLocationInfo(*it);
            newBindings->insert(newBindings->begin(), newVB);
        }
    }

    // Overwrite our bindings with the new ones
    if(newBindings)
        bindings_ = newBindings;

    return this;
}
Esempio n. 7
0
ASTNode *XQIf::staticTypingImpl(StaticContext *context)
{
  _src.clear();

  if(_test->getStaticAnalysis().isUpdating()) {
    XQThrow(StaticErrorException,X("XQIf::staticTyping"),
            X("It is a static error for the conditional expression of an if expression "
              "to be an updating expression [err:XUST0001]"));
  }

  _src.add(_test->getStaticAnalysis());

  _src.getStaticType() = _whenTrue->getStaticAnalysis().getStaticType();
  _src.setProperties(_whenTrue->getStaticAnalysis().getProperties());
  _src.add(_whenTrue->getStaticAnalysis());

  if(_src.isUpdating()) {
    if(!_whenFalse->getStaticAnalysis().isUpdating() &&
       !_whenFalse->getStaticAnalysis().isPossiblyUpdating())
      XQThrow(StaticErrorException, X("XQIf::staticTyping"),
              X("Mixed updating and non-updating operands [err:XUST0001]"));
  }
  else {
    if(_whenFalse->getStaticAnalysis().isUpdating() &&
       !_whenTrue->getStaticAnalysis().isPossiblyUpdating())
      XQThrow(StaticErrorException, X("XQIf::staticTyping"),
              X("Mixed updating and non-updating operands [err:XUST0001]"));
  }

  _src.getStaticType() |= _whenFalse->getStaticAnalysis().getStaticType();
  _src.setProperties(_src.getProperties() & _whenFalse->getStaticAnalysis().getProperties());
  _src.add(_whenFalse->getStaticAnalysis());

  return this;
}
Esempio n. 8
0
Sequence FunctionCompare::createSequence(DynamicContext* context, int flags) const
{
    Sequence str1 = getParamNumber(1,context)->toSequence(context);
    Sequence str2 = getParamNumber(2,context)->toSequence(context);
    if(str1.isEmpty() || str2.isEmpty())
        return Sequence(context->getMemoryManager());

    Collation* collation = NULL;
    if(getNumArgs()>2) {
        Sequence collArg = getParamNumber(3,context)->toSequence(context);
        const XMLCh* collName = collArg.first()->asString(context);
        try {
            context->getItemFactory()->createAnyURI(collName, context);
        } catch(XPath2ErrorException &e) {
            XQThrow(FunctionException, X("FunctionCompare::createSequence"), X("Invalid argument to compare function"));  
        }
        collation = context->getCollation(collName, this);
        if(collation == NULL)
            XQThrow(FunctionException,X("FunctionCompare::createSequence"),X("Collation object is not available"));
    }
    else
        collation = context->getDefaultCollation(this);
    if(collation == NULL)
        collation = context->getCollation(CodepointCollation::getCodepointCollationName(), this);

    const XMLCh* string1 = str1.first()->asString(context);
    const XMLCh* string2 = str2.first()->asString(context);
    Sequence result(context->getItemFactory()->createInteger(collation->compare(string1,string2), context), context->getMemoryManager());

    return result;
}
Esempio n. 9
0
ASTNode *XQCastAs::staticTypingImpl(StaticContext *context)
{
  _src.clear();

  const SequenceType::ItemType *itemType = _exprType->getItemType();
  if(itemType != NULL) {
    _src.getStaticType() = StaticType::create(_typeIndex);
    if(_exprType->getOccurrenceIndicator() == SequenceType::QUESTION_MARK) {
      _src.getStaticType().multiply(0, 1);
    }
  }

  _src.add(_expr->getStaticAnalysis());

  if(_typeIndex == AnyAtomicType::QNAME &&
     !_expr->getStaticAnalysis().getStaticType().containsType(StaticType::QNAME_TYPE) &&
     (_exprType->getOccurrenceIndicator() == SequenceType::EXACTLY_ONE ||
      _expr->getStaticAnalysis().getStaticType().containsType(StaticType::ITEM_TYPE))) {
    XQThrow(TypeErrorException,X("XQCastAs::staticTyping"),
            X("Only a subtype of xs:QName can be cast to a subtype of xs:QName [err:XPTY0004]"));
  }
  if(_typeIndex == AnyAtomicType::NOTATION &&
     !_expr->getStaticAnalysis().getStaticType().containsType(StaticType::NOTATION_TYPE) &&
     (_exprType->getOccurrenceIndicator() == SequenceType::EXACTLY_ONE ||
      _expr->getStaticAnalysis().getStaticType().containsType(StaticType::ITEM_TYPE))) {
    XQThrow(TypeErrorException,X("XQCastAs::staticTyping"),
            X("Only a subtype of xs:NOTATION can be cast to a subtype of xs:NOTATION [err:XPTY0004]"));
  }

  return this;
}
Esempio n. 10
0
Sequence FunctionDocument::createSequence(DynamicContext* context, int flags) const
{
  const XMLCh *baseURI;
  if(getNumArgs() == 2) {
    baseURI = ((Node*)getParamNumber(2, context)->next(context).get())->dmBaseURI(context).first()->asString(context);
  }
  else {
    baseURI = context->getBaseURI();
  }

  Sequence result(context->getMemoryManager());
  Result args = getParamNumber(1, context);
  Item::Ptr uriArg;
  while((uriArg = args->next(context)).notNull()) {
    const XMLCh *uri = uriArg->asString(context);
    if(!XPath2Utils::isValidURI(uri, context->getMemoryManager()))
      XQThrow(FunctionException, X("FunctionDocument::createSequence"), X("Invalid argument to fn:document function [err:FODC0005]"));

    try {
      XMLUri base(baseURI);
      XMLUri full(&base, uri);
      uri = context->getMemoryManager()->getPooledString(full.getUriText());
    }
    catch(MalformedURLException &e){
      XQThrow(FunctionException, X("FunctionDocument::createSequence"), X("Invalid argument to resolve-uri [err:FORG0002]"));
    }

    result.joinSequence(context->resolveDocument(uri, this, context->getProjection() ? queryPathTree_ : 0));
  }

  return result;
}
Esempio n. 11
0
Item::Ptr XQCastAs::CastAsResult::getSingleResult(DynamicContext *context) const
{
  // The semantics of the cast expression are as follows:
  //    1. Atomization is performed on the input expression.
  Result toBeCasted(_di->getExpression()->createResult(context));

  const Item::Ptr first = toBeCasted->next(context);

  if(first == NULLRCP) {
    //    3. If the result of atomization is an empty sequence:
    //       1. If ? is specified after the target type, the result of the cast expression is an empty sequence.
    //       2. If ? is not specified after the target type, a type error is raised [err:XPTY0004].
    if(_di->getSequenceType()->getOccurrenceIndicator() == SequenceType::EXACTLY_ONE) {
      XQThrow(TypeErrorException,X("XQCastAs::CastAsResult::getSingleResult"),
              X("The input to a non-optional cast as expression is an empty sequence [err:XPTY0004]"));
    }
    else {
      return 0;
    }
  }

  const Item::Ptr second = toBeCasted->next(context);

  //    2. If the result of atomization is a sequence of more than one atomic value, a type error is raised.[err:XPTY0004]
  if(second != NULLRCP) {
    XQThrow(TypeErrorException,X("XQCastAs::CastAsResult::getSingleResult"),
            X("The input to a cast as expression is more than one atomic value [err:XPTY0004]"));
  }

  //    4. If the result of atomization is a single atomic value, the result of the cast expression depends on the input type and the target type.
  //       The normative definition of these rules is given in [XQuery 1.0 and XPath 2.0 Functions and Operators].
  return _di->cast((const AnyAtomicType*)first.get(), context);
}
Esempio n. 12
0
EventGenerator::Ptr XQNamespaceConstructor::generateEvents(EventHandler *events, DynamicContext *context,
                                                      bool preserveNS, bool preserveType) const
{
  const XMLCh *nodeName = m_name->createResult(context)->next(context)->asString(context);
  if(*nodeName && !XMLChar1_0::isValidNCName(nodeName, XMLString::stringLen(nodeName)))
    XQThrow(ASTException,X("XQNamespaceConstructor::generateEvents"),
            X("The name for the namespace node must be either a zero-length string or a valid xs:NCName [err:XTDE0920]"));

  if(XPath2Utils::equals(nodeName, XMLUni::fgXMLNSString))
    XQThrow(ASTException,X("XQNamespaceConstructor::generateEvents"),
            X("The name for the namespace node must not be \"xmlns\" [err:XTDE0920]"));

  XMLBuffer value;
  getStringValue(m_children, value, context);

  if(value.getLen() == 0)
    XQThrow(ASTException,X("XQNamespaceConstructor::generateEvents"),
            X("The value for the namespace node must not be empty [err:XTDE0930]"));

  if(XPath2Utils::equals(nodeName, XMLUni::fgXMLString) &&
     !XPath2Utils::equals(value.getRawBuffer(), XMLUni::fgXMLURIName))
    XQThrow(ASTException,X("XQNamespaceConstructor::generateEvents"),
            X("The name for the namespace node must not be \"xml\"  when the value is not \"http://www.w3.org/XML/1998/namespace\" [err:XTDE0925]"));

  if(XPath2Utils::equals(value.getRawBuffer(), XMLUni::fgXMLURIName) &&
     !XPath2Utils::equals(nodeName, XMLUni::fgXMLString))
    XQThrow(ASTException,X("XQNamespaceConstructor::generateEvents"),
            X("The value for the namespace node must not be \"http://www.w3.org/XML/1998/namespace\"  when the name is not \"xml\" [err:XTDE0925]"));

  events->namespaceEvent(nodeName, value.getRawBuffer());
  return 0;
}
Esempio n. 13
0
Sequence FunctionLocalname::createSequence(DynamicContext* context, int flags) const
{
  XPath2MemoryManager* memMgr = context->getMemoryManager();

  Node::Ptr ctxNode;
  if(getNumArgs() == 1) {
    Sequence arg=getParamNumber(1,context)->toSequence(context);
    if(arg.isEmpty())
      return Sequence(context->getItemFactory()->createString(XERCES_CPP_NAMESPACE_QUALIFIER XMLUni::fgZeroLenString, context), memMgr);
    ctxNode=arg.first();
  }
  else {
    const Item::Ptr item = context->getContextItem();
    if(item==NULLRCP)
      XQThrow(FunctionException, X("FunctionLocalName::createSequence"),X("Undefined context item in fn:local-name [err:XPDY0002]"));
    if(!item->isNode())
      XQThrow(FunctionException, X("FunctionLocalName::createSequence"),X("The context item is not a node [err:XPTY0004]"));
    ctxNode=item;
	}

  ATQNameOrDerived::Ptr name = ctxNode->dmNodeName(context);
  if(name.notNull())
    return Sequence(context->getItemFactory()->createString(((const ATQNameOrDerived*)name.get())->getName(), context), memMgr);

  return Sequence(context->getItemFactory()->createString(XERCES_CPP_NAMESPACE_QUALIFIER XMLUni::fgZeroLenString, context), memMgr);
}
Esempio n. 14
0
Item::Ptr PromoteAnyURIResult::next(DynamicContext *context)
{
  Item::Ptr item = parent_->next(context);
  if(item.notNull()) {
    assert(item->isAtomicValue());
    const AnyAtomicType *atomic = (const AnyAtomicType *)item.get();

    // 4. For each item of type xs:anyURI in the atomic sequence that can be promoted to the expected atomic
    //    type using URI promotion as described in B.1 Type Promotion, the promotion is done.
    if(atomic->getPrimitiveTypeIndex() == AnyAtomicType::ANY_URI) {
      try {
        item = atomic->castAs(AnyAtomicType::STRING, context);
      } catch (XPath2TypeCastException &e) {
        XQThrow(XPath2ErrorException, X("SequenceType::AtomicTypeConvertFunctionArgResult::next"),
                 X("AnyURI type promotion failed (for promotable type)"));
      } catch (const XMLException& e) {
        XQThrow(XPath2ErrorException, X("SequenceType::AtomicTypeConvertFunctionArgResult::next"),
                 X("AnyURI type promotion failed (for promotable type)"));
      }
    }
  }
  else {
    parent_ = 0;
  }

  return item;
}
Esempio n. 15
0
Item::Ptr PromoteNumericResult::next(DynamicContext *context)
{
  Item::Ptr item = parent_->next(context);
  if(item.notNull()) {
    assert(item->isAtomicValue());
    const AnyAtomicType *atomic = (const AnyAtomicType *)item.get();

    // 3. For each numeric item in the atomic sequence that can be promoted to the expected atomic type using
    //    the promotion rules in B.1 Type Promotion, the promotion is done.
    if(atomic->isNumericValue()) {
      try {
        const Numeric::Ptr promotedType = ((const Numeric*)atomic)->
          promoteTypeIfApplicable(typeIndex_, context);
        if(promotedType.notNull()) {
          item = promotedType;
        }
      } catch (XPath2TypeCastException &e) {
        XQThrow(XPath2ErrorException, X("SequenceType::AtomicTypeConvertFunctionArgResult::next"),
                 X("Numeric type promotion failed (for promotable type)"));
      } catch (const XMLException& e) {
        XQThrow(XPath2ErrorException, X("SequenceType::AtomicTypeConvertFunctionArgResult::next"),
                 X("Numeric type promotion failed (for promotable type)"));
      }
    }
  }
  else {
    parent_ = 0;
  }

  return item;
}
Esempio n. 16
0
ASTNode *URename::staticTypingImpl(StaticContext *context)
{
  _src.clear();

  _src.add(target_->getStaticAnalysis());

  if(target_->getStaticAnalysis().isUpdating()) {
    XQThrow(StaticErrorException,X("URename::staticTyping"),
            X("It is a static error for the target expression of a rename expression "
              "to be an updating expression [err:XUST0001]"));
  }

  if(!target_->getStaticAnalysis().getStaticType().
     containsType(StaticType::ELEMENT_TYPE|StaticType::ATTRIBUTE_TYPE|StaticType::PI_TYPE)) {
    XQThrow(XPath2TypeMatchException,X("URename::staticTyping"),
            X("It is a type error for the target expression of a rename expression not to be a single element, "
              "attribute or processing instruction [err:XUTY0012]"));
  }

  _src.add(name_->getStaticAnalysis());

  if(name_->getStaticAnalysis().isUpdating()) {
    XQThrow(StaticErrorException,X("URename::staticTyping"),
            X("It is a static error for the name expression of a rename expression "
              "to be an updating expression [err:XUST0001]"));
  }

  _src.updating(true);
  return this;
}
Esempio n. 17
0
ASTNode *Intersect::staticTypingImpl(StaticContext *context)
{
  _src.clear();

  _src.copy(_args[0]->getStaticAnalysis());

  if(_args[0]->getStaticAnalysis().isUpdating()) {
    XQThrow(StaticErrorException,X("Intersect::staticTyping"),
            X("It is a static error for an operand of an operator "
              "to be an updating expression [err:XUST0001]"));
  }

  _src.add(_args[1]->getStaticAnalysis());

  _src.getStaticType().typeNodeIntersect(_args[1]->getStaticAnalysis().getStaticType());
  _src.getStaticType().multiply(0, 1);

  if(_args[1]->getStaticAnalysis().isUpdating()) {
    XQThrow(StaticErrorException,X("Intersect::staticTyping"),
            X("It is a static error for an operand of an operator "
              "to be an updating expression [err:XUST0001]"));
  }

  return this;
}
Esempio n. 18
0
PendingUpdateList UInsertAsLast::createUpdateList(DynamicContext *context) const
{
  Node::Ptr node = (Node*)target_->createResult(context)->next(context).get();

  if(node->dmNodeKind() != Node::element_string &&
     node->dmNodeKind() != Node::document_string)
    XQThrow(XPath2TypeMatchException,X("UInsertAsLast::createUpdateList"),
            X("It is a type error for the target expression of an insert as last expression not to be a single element "
              "or document [err:XUTY0005]"));

  Sequence alist(context->getMemoryManager());
  Sequence clist(context->getMemoryManager());

  Result value = source_->createResult(context);
  Item::Ptr item;
  while((item = value->next(context)).notNull()) {
    if(((Node*)item.get())->dmNodeKind() == Node::attribute_string) {
      if(!clist.isEmpty())
        XQThrow(ASTException,X("UInsertAsLast::createUpdateList"),
                X("Attribute nodes must occur before other nodes in the source expression for an insert as last expression [err:XUTY0004]"));

      //    b. No attribute node in $alist may have a QName whose implied namespace binding conflicts with a namespace
      //       binding in the "namespaces" property of $target [err:XUDY0023].  
      ATQNameOrDerived::Ptr qname = ((Node*)item.get())->dmNodeName(context);
      if(qname->getURI() != 0 && *(qname->getURI()) != 0) {
        ATAnyURIOrDerived::Ptr uri = FunctionNamespaceURIForPrefix::uriForPrefix(qname->getPrefix(), node, context, this);
        if(uri.notNull() && !XPath2Utils::equals(uri->asString(context), qname->getURI())) {
          XMLBuffer buf;
          buf.append(X("Implied namespace binding for the insert as last expression (\""));
          buf.append(qname->getPrefix());
          buf.append(X("\" -> \""));
          buf.append(qname->getURI());
          buf.append(X("\") conflicts with those already existing on the parent element of the target attribute [err:XUDY0023]"));
          XQThrow3(DynamicErrorException, X("UInsertInto::createUpdateList"), buf.getRawBuffer(), this);
        }
      }

      alist.addItem(item);
    }
    else
      clist.addItem(item);
  }

  PendingUpdateList result;

  if(!alist.isEmpty()) {
    // 3. If $alist is not empty and into is specified, the following checks are performed:
    //    a. $target must be an element node [err:XUTY0022].
    if(node->dmNodeKind() == Node::document_string)
      XQThrow(XPath2TypeMatchException,X("UInsertInto::createUpdateList"),
              X("It is a type error if an insert expression specifies the insertion of an attribute node into a document node [err:XUTY0022]"));
    result.addUpdate(PendingUpdate(PendingUpdate::INSERT_ATTRIBUTES, node, alist, this));
  }
  if(!clist.isEmpty()) {
    result.addUpdate(PendingUpdate(PendingUpdate::INSERT_INTO_AS_LAST, node, clist, this));
  }

  return result;
}
Esempio n. 19
0
PendingUpdateList UReplaceValueOf::createUpdateList(DynamicContext *context) const
{
  Node::Ptr node = (Node*)target_->createResult(context)->next(context).get();

  if(node->dmNodeKind() == Node::document_string)
    XQThrow(XPath2TypeMatchException,X("UReplaceValueOf::createUpdateList"),
            X("The target expression of a replace expression does not return a single "
              "node that is not a document node [err:XUTY0008]"));
    
  XMLBuffer buf;
  XQDOMConstructor::getStringValue(expr_, buf, context);

  // If $target is a comment node, and $string contains two adjacent hyphens or ends with a hyphen, a dynamic error is raised [err:XQDY0072].
  if(node->dmNodeKind() == Node::comment_string) {
    bool foundOne = false;
    for(const XMLCh *str = buf.getRawBuffer(); *str; ++str) {
      if(*str == '-') {
        if(foundOne) {
          XQThrow(DynamicErrorException,X("UReplaceValueOf::createUpdateList"),
                  X("The replace value of expression would result in a comment node whose content contains two adjacent hyphens [err:XQDY0072]"));
        }
        else foundOne = true;
      }
      else {
        foundOne = false;
      }
    }

    if(foundOne) {
      XQThrow(DynamicErrorException,X("UReplaceValueOf::createUpdateList"),
              X("The replace value of expression would result in a comment node whose content ends with a hyphen [err:XQDY0072]"));
    }
  }
  // If $target is a processing instruction node, and $string contains the substring "?>", a dynamic error is raised [err:XQDY0026].
  else if(node->dmNodeKind() == Node::processing_instruction_string) {
    bool foundQuestion = false;
    for(const XMLCh *str = buf.getRawBuffer(); *str; ++str) {
      if(*str == '?') {
        foundQuestion = true;
      }
      else {
        if(foundQuestion && *str == '>') {
          XQThrow(DynamicErrorException,X("UReplaceValueOf::createUpdateList"),
                  X("The replace value of expression would result in a processing instruction node whose content includes the string \"?>\" [err:XQDY0026]"));
        }
        foundQuestion = false;
      }
    }
  }

  Item::Ptr value = context->getItemFactory()->createString(buf.getRawBuffer(), context);

  if(node->dmNodeKind() == Node::element_string) {
    return PendingUpdate(PendingUpdate::REPLACE_ELEMENT_CONTENT, node, value, this);
  }
  else {
    return PendingUpdate(PendingUpdate::REPLACE_VALUE, node, value, this);
  }
}
Esempio n. 20
0
ASTNode* XQCastAs::staticResolution(StaticContext *context)
{
  XPath2MemoryManager *mm = context->getMemoryManager();

  _exprType->staticResolution(context);

  const SequenceType::ItemType *itemType = _exprType->getItemType();
  if(itemType != NULL) {
    if((XPath2Utils::equals(itemType->getTypeURI(), XERCES_CPP_NAMESPACE_QUALIFIER SchemaSymbols::fgURI_SCHEMAFORSCHEMA) &&
        XPath2Utils::equals(itemType->getType()->getName(), szNOTATION)) ||
       (XPath2Utils::equals(itemType->getTypeURI(), FunctionConstructor::XMLChXPath2DatatypesURI) &&
        XPath2Utils::equals(itemType->getType()->getName(), AnyAtomicType::fgDT_ANYATOMICTYPE)))
      XQThrow(TypeErrorException,X("XQCastAs::CastAsResult::getSingleResult"),
              X("The target type of a cast expression must be an atomic type that is in the in-scope schema types and is not xs:NOTATION or xdt:anyAtomicType [err:XPST0080]"));
  }

  if(_exprType->getItemTestType() != SequenceType::ItemType::TEST_ATOMIC_TYPE)
    XQThrow(TypeErrorException,X("XQCastAs::staticResolution"),X("Cannot cast to a non atomic type"));

  _typeIndex = context->getItemFactory()->
    getPrimitiveTypeIndex(_exprType->getTypeURI(),
                          _exprType->getConstrainingType()->getName(), _isPrimitive);

  // If this is a cast to xs:QName or xs:NOTATION and the argument is a string literal
  // evaluate immediately, since they aren't allowed otherwise
  if((_typeIndex == AnyAtomicType::QNAME || _typeIndex == AnyAtomicType::NOTATION) &&
     _expr->getType() == LITERAL &&
     ((XQLiteral*)_expr)->getPrimitiveType() == AnyAtomicType::STRING) {

    AutoDelete<DynamicContext> dContext(context->createDynamicContext());
    dContext->setMemoryManager(mm);

    AnyAtomicType::Ptr item = (AnyAtomicType*)_expr->createResult(dContext)->next(dContext).get();
    try {
      if(_isPrimitive) {
        item = item->castAsNoCheck(_typeIndex, 0, 0, dContext);
      }
      else {
        item = item->castAsNoCheck(_typeIndex, _exprType->getTypeURI(),
                                   _exprType->getConstrainingType()->getName(), dContext);
      }
    }
    catch(XQException &e) {
      if(e.getXQueryLine() == 0)
        e.setXQueryPosition(this);
      throw;
    }

    return XQLiteral::create(item, dContext, mm, this)->staticResolution(context);
  }

  _expr = new (mm) XQAtomize(_expr, mm);
  _expr->setLocationInfo(this);
  _expr = _expr->staticResolution(context);

  return this;
}
Esempio n. 21
0
PendingUpdateList URename::createUpdateList(DynamicContext *context) const
{
  Node::Ptr node = (Node*)target_->createResult(context)->next(context).get();

  if(node->dmNodeKind() != Node::element_string &&
     node->dmNodeKind() != Node::attribute_string &&
     node->dmNodeKind() != Node::processing_instruction_string)
    XQThrow(XPath2TypeMatchException,X("URename::createUpdateList"),
            X("It is a type error for the target expression of a rename expression not to be a single element, "
              "attribute or processing instruction [err:XUTY0012]"));

  ATQNameOrDerived::Ptr qname = (ATQNameOrDerived*)name_->createResult(context)->next(context).get();

  // 3. The following checks are performed for error conditions:
  //    a. If $target is an element node, the "namespaces" property of $target must not include any namespace binding that conflicts
  //       with the implied namespace binding of $QName [err:XUDY0023].
  if(node->dmNodeKind() == Node::element_string) {
    ATAnyURIOrDerived::Ptr uri = FunctionNamespaceURIForPrefix::uriForPrefix(qname->getPrefix(), node, context, this);
    if(uri.notNull() && !XPath2Utils::equals(uri->asString(context), qname->getURI())) {
      XMLBuffer buf;
      buf.append(X("Implied namespace binding for the rename expression (\""));
      buf.append(qname->getPrefix());
      buf.append(X("\" -> \""));
      buf.append(qname->getURI());
      buf.append(X("\") conflicts with those already existing on the target element [err:XUDY0023]"));
      XQThrow3(DynamicErrorException, X("URename::createUpdateList"), buf.getRawBuffer(), this);
    }
  }
  //    b. If $target is an attribute node that has a parent, the "namespaces" property of parent($target) must not include any
  //       namespace binding that conflicts with the implied namespace binding of $QName [err:XUDY0023].
  else if(node->dmNodeKind() == Node::attribute_string) {
    Node::Ptr parentNode = node->dmParent(context);
    if(parentNode.notNull() && qname->getURI() != 0 && *(qname->getURI()) != 0) {
      ATAnyURIOrDerived::Ptr uri = FunctionNamespaceURIForPrefix::uriForPrefix(qname->getPrefix(), parentNode, context, this);
      if(uri.notNull() && !XPath2Utils::equals(uri->asString(context), qname->getURI())) {
        XMLBuffer buf;
        buf.append(X("Implied namespace binding for the rename expression (\""));
        buf.append(qname->getPrefix());
        buf.append(X("\" -> \""));
        buf.append(qname->getURI());
        buf.append(X("\") conflicts with those already existing on the parent element of the target attribute [err:XUDY0023]"));
        XQThrow3(DynamicErrorException, X("URename::createUpdateList"), buf.getRawBuffer(), this);
      }
    }
  }
  //    c. If $target is processing instruction node, $QName must not include a non-empty namespace prefix. [err:XUDY0025].
  else if(node->dmNodeKind() == Node::processing_instruction_string && !XPath2Utils::equals(qname->getPrefix(), XMLUni::fgZeroLenString))
    XQThrow(XPath2TypeMatchException,X("URename::createUpdateList"),
            X("The target of a rename expression is a processing instruction node, and the new name "
              "expression returned a QName with a non-empty namespace prefix [err:XUDY0025]"));

  return PendingUpdate(PendingUpdate::RENAME, node, qname, this);
}
Esempio n. 22
0
Sequence FunctionDocAvailable::createSequence(DynamicContext* context, int flags) const {
  Sequence uriArg = getParamNumber(1,context)->toSequence(context);
  
  if (uriArg.isEmpty()) {
    return Sequence(context->getMemoryManager());
  }
  
  const XMLCh* uri = uriArg.first()->asString(context);
  // on Windows, we can have URIs using \ instead of /; let's normalize them
  XMLCh backSlash[]={ XERCES_CPP_NAMESPACE_QUALIFIER chBackSlash, XERCES_CPP_NAMESPACE_QUALIFIER chNull };
  if(XERCES_CPP_NAMESPACE_QUALIFIER XMLString::findAny(uri,backSlash))
  {
	  XMLCh* newUri=XERCES_CPP_NAMESPACE_QUALIFIER XMLString::replicate(uri,context->getMemoryManager());
	  for(unsigned int i=0;i<XERCES_CPP_NAMESPACE_QUALIFIER XMLString::stringLen(newUri);i++)
		  if(newUri[i]==XERCES_CPP_NAMESPACE_QUALIFIER chBackSlash)
			  newUri[i]=XERCES_CPP_NAMESPACE_QUALIFIER chForwardSlash;
	  uri=newUri;
  }
  if(!XPath2Utils::isValidURI(uri, context->getMemoryManager()))
    XQThrow(FunctionException, X("FunctionDocAvailable::createSequence"), X("Invalid argument to fn:doc-available function [err:FODC0005]"));

  bool bSuccess=false;
  try {
    bSuccess = !context->resolveDocument(uri, this).isEmpty();
  } 
  catch(...) {
  }
  return Sequence(context->getItemFactory()->createBoolean(bSuccess, context), context->getMemoryManager());
}
Esempio n. 23
0
BoolResult FunctionDocAvailable::boolResult(DynamicContext* context) const
{
  Sequence uriArg = getParamNumber(1,context)->toSequence(context);
  
  if (uriArg.isEmpty()) return false;
  
  const XMLCh* uri = uriArg.first()->asString(context);
  // on Windows, we can have URIs using \ instead of /; let's normalize them
  XMLCh backSlash[]={ chBackSlash, chNull };
  if(XMLString::findAny(uri,backSlash))
  {
	  XMLCh* newUri=XMLString::replicate(uri,context->getMemoryManager());
	  for(unsigned int i=0;i<XMLString::stringLen(newUri);i++)
		  if(newUri[i]==chBackSlash)
			  newUri[i]=chForwardSlash;
	  uri=newUri;
  }
  if(!XPath2Utils::isValidURI(uri, context->getMemoryManager()))
    XQThrow(FunctionException, X("FunctionDocAvailable::createSequence"), X("Invalid argument to fn:doc-available function [err:FODC0005]"));

  try {
    return !context->resolveDocument(uri, this).isEmpty();
  } 
  catch(...) {
  }
  return false;
}
Esempio n. 24
0
Item::Ptr DistinctValueResult::next(DynamicContext *context)
{
  if(toDo_) {
    toDo_ = false;
    parent_ = fdv_->getParamNumber(1, context);

    Collation *collation;
    if(fdv_->getNumArgs() > 1) {
        const XMLCh* collName = fdv_->getParamNumber(2, context)->next(context)->asString(context);
        try {
            context->getItemFactory()->createAnyURI(collName, context);
        } catch(XPath2ErrorException &e) {
            XQThrow(FunctionException, X("FunctionDistinctValues::DistinctValueResult::next"), X("Invalid collationURI"));  
        }
        collation = context->getCollation(collName, this);
    }
    else
        collation = context->getDefaultCollation(this);

    alreadySeen_ = new DistinctSet(dvCompare(collation, context));
  }

  AnyAtomicType::Ptr item;
  while(true) {
    item = (const AnyAtomicType *)parent_->next(context).get();
    if(item.isNull()) break;

    if(alreadySeen_->insert(item).second)
      return item;
  }

  parent_ = 0;
  return 0;
}
Esempio n. 25
0
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;
}
Sequence FunctionAdjustTimeToTimezone::createSequence(DynamicContext* context, int flags) const
{
	XPath2MemoryManager* memMgr = context->getMemoryManager();

  //If $srcval is the empty sequence, then the result is the empty sequence.
  Sequence op1 = getParamNumber(1, context)->toSequence(context);
  if (op1.isEmpty()) {
    return Sequence(memMgr);
  }
  const ATTimeOrDerived* time = (const ATTimeOrDerived*)(const Item*)op1.first();

  //If $timezone is not specified, then $timezone is the value of the implicit timezone in the evaluation context.
  ATDurationOrDerived::Ptr timezoneAsDuration = 0;

  if (getNumArgs() > 1) {
    Sequence op2 = getParamNumber(2, context)->toSequence(context);
    if (op2.isEmpty()) {
      // unset the timezone
      return Sequence(time->setTimezone(0, context), memMgr);
    } else {
      timezoneAsDuration = (const ATDurationOrDerived::Ptr )op2.first();
      Timezone::Ptr timezone = new Timezone(timezoneAsDuration, context);
      if(!timezoneAsDuration->equals(timezone->asDayTimeDuration(context), context)) {
        XQThrow(FunctionException, X("FunctionAdjustTimeToTimeZone::createSequence"),X("Invalid timezone value [err:FODT0003]"));
      }
    }
  }
  else {
    timezoneAsDuration = context->getImplicitTimezone();
  }

  return Sequence(time->addTimezone(timezoneAsDuration, context), memMgr);

}
Esempio n. 27
0
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;
}
Esempio n. 28
0
EventGenerator::Ptr XQAttributeConstructor::generateEvents(EventHandler *events, DynamicContext *context,
                                                      bool preserveNS, bool preserveType) const
{
  AnyAtomicType::Ptr itemName = m_name->createResult(context)->next(context);
  const ATQNameOrDerived* pQName = (const ATQNameOrDerived*)itemName.get();
  const XMLCh *prefix = pQName->getPrefix();
  const XMLCh *uri = pQName->getURI();
  const XMLCh *name = pQName->getName();

  if((uri==NULL && XPath2Utils::equals(name, XMLUni::fgXMLNSString)) ||
     XPath2Utils::equals(uri, XMLUni::fgXMLNSURIName))
    XQThrow(ASTException,X("DOM Constructor"),X("A computed attribute constructor cannot create a namespace declaration [err:XQDY0044]"));

  XMLBuffer value;
  getStringValue(m_children, value, context);

  const XMLCh *typeURI = SchemaSymbols::fgURI_SCHEMAFORSCHEMA;
  const XMLCh *typeName = ATUntypedAtomic::fgDT_UNTYPEDATOMIC;

  // check if it's xml:id
  static const XMLCh id[] = { 'i', 'd', 0 };
  if(XPath2Utils::equals(name, id) && XPath2Utils::equals(uri, XMLUni::fgXMLURIName)) {
    // If the attribute name is xml:id, the string value and typed value of the attribute are further normalized by 
    // discarding any leading and trailing space (#x20) characters, and by replacing sequences of space (#x20) characters 
    // by a single space (#x20) character.
    XMLString::collapseWS(value.getRawBuffer(), context->getMemoryManager());
    typeURI = SchemaSymbols::fgURI_SCHEMAFORSCHEMA;
    typeName = XMLUni::fgIDString;
  }

  events->attributeEvent(emptyToNull(prefix), emptyToNull(uri), name, value.getRawBuffer(), typeURI, typeName);
  return 0;
}
Esempio n. 29
0
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);
}
Esempio n. 30
0
void XQGlobalVariable::staticTyping(StaticContext* context, StaticTyper *styper)
{
  VariableTypeStore* varStore = context->getVariableTypeStore();

  if(m_Value != NULL) {
    XQUserFunction::staticTypeFunctionCalls(m_Value, context, styper);

    m_Value = m_Value->staticTyping(context, styper);
    _src.copy(m_Value->getStaticAnalysis());

    if(m_Value->getStaticAnalysis().isUpdating()) {
      XQThrow(StaticErrorException,X("XQGlobalVariable::staticTyping"),
              X("It is a static error for the initializing expression of a global variable "
                "to be an updating expression [err:XUST0001]"));
    }
  }

  if(m_Value == 0 || !required_) {
    if(m_Type != 0) {
      bool isPrimitive;
      m_Type->getStaticType(_src.getStaticType(), context, isPrimitive, m_Type);
    }
    else {
      _src.getStaticType() = StaticType(StaticType::ITEM_TYPE, 0, StaticType::UNLIMITED);
    }
  }

  varStore->declareGlobalVar(m_szURI, m_szLocalName, _src);
}