/** * Copy an expression. This makes a deep copy. * * @return the copy of the original expression * @param rebindings */ /*@NotNull*/ public Expression copy(RebindingMap rebindings) { CastExpression c2 = new CastExpression(getBaseExpression().copy(rebindings), getTargetType(), allowsEmpty()); ExpressionTool.copyLocationInfo(this, c2); c2.converter = converter; c2.setRetainedStaticContext(getRetainedStaticContext()); c2.setOperandIsStringLiteral(isOperandIsStringLiteral()); return c2; }
/** * Evaluate the expression */ /*@Nullable*/ public AtomicValue evaluateItem(XPathContext context) throws XPathException { try { AtomicValue value = (AtomicValue) getBaseExpression().evaluateItem(context); return doCast(value, context); } catch (ClassCastException e) { e.printStackTrace(); throw e; } }
/** * Is this expression the same as another expression? */ public boolean equals(Object other) { return other instanceof CastExpression && getBaseExpression().isEqual(((CastExpression) other).getBaseExpression()) && getTargetType() == ((CastExpression) other).getTargetType() && allowsEmpty() == ((CastExpression) other).allowsEmpty(); }
/** * Copy an expression. This makes a deep copy. * * @return the copy of the original expression */ public Expression copy() { return new CastExpression(getBaseExpression().copy(), targetType, allowEmpty); }
getOperand().typeCheck(visitor, contextInfo); SequenceType atomicType = SequenceType.makeSequenceType(BuiltInAtomicType.ANY_ATOMIC, getCardinality()); Expression operand = tc.staticTypeCheck(getBaseExpression(), atomicType, role, visitor); setBaseExpression(operand); sourceItemType = operand.getItemType(); if (allowsEmpty()) { return Literal.makeEmptySequence(); } else { XPathException err = new XPathException("Cast does not allow an empty sequence as input"); err.setErrorCode("XPTY0004"); err.setLocation(getLocation()); err.setIsTypeError(true); throw err; int r = th.relationship(sourceType, getTargetType()); if (r == TypeHierarchy.SAME_TYPE) { return operand; converter = new Converter.UpCastingConverter(getTargetType()); } else { converter = rules.getConverter((AtomicType)sourceType, getTargetType()); if (converter == null) { XPathException err = new XPathException("Casting from " + sourceType + " to " + getTargetType() + " can never succeed"); err.setErrorCode("XPTY0004"); err.setLocation(getLocation());
/** * Convert this value-of instruction to an expression that delivers the string-value of the resulting * text node as an untyped atomic value. * * @return the converted expression */ public Expression convertToCastAsString() { if (noNodeIfEmpty || !Cardinality.allowsZero(getSelect().getCardinality())) { return new CastExpression(getSelect(), BuiltInAtomicType.UNTYPED_ATOMIC, true); } else { // must return zero-length string rather than () if empty Expression sf = SystemFunction.makeCall("string", getRetainedStaticContext(), getSelect()); return new CastExpression(sf, BuiltInAtomicType.UNTYPED_ATOMIC, false); } }
Expression operand = getBaseExpression(); if (getTargetType() == BuiltInAtomicType.UNTYPED_ATOMIC) { if (operand.isCallOn(String_1.class)) { Expression e = ((SystemFunctionCall) operand).getArg(0); if (((CastExpression) operand).getTargetType() == BuiltInAtomicType.UNTYPED_ATOMIC) { return operand; } else if (((CastExpression) operand).getTargetType() == BuiltInAtomicType.STRING) { ((CastExpression) operand).setTargetType(BuiltInAtomicType.UNTYPED_ATOMIC); return operand; if (et instanceof AtomicType && e.getCardinality() == StaticProperty.EXACTLY_ONE && th.isSubType(et, getTargetType())) { return e; ItemType it = ((CastExpression) operand).getTargetType(); if (th.isSubType(it, BuiltInAtomicType.STRING) || th.isSubType(it, BuiltInAtomicType.UNTYPED_ATOMIC)) { Expression e = ((CastExpression) operand).getBaseExpression(); ItemType et = e.getItemType(); if (et instanceof AtomicType && e.getCardinality() == StaticProperty.EXACTLY_ONE && th.isSubType(et, getTargetType())) { return e; if (et instanceof AtomicType && e.getCardinality() == StaticProperty.EXACTLY_ONE && th.isSubType(et, getTargetType())) { return e;
/** * Represent the expression as a string. The resulting string will be a valid XPath 3.0 expression * with no dependencies on namespace bindings. * * @return the expression as a string in XPath 3.0 syntax */ public String toString() { return getTargetType().getEQName() + "(" + getBaseExpression().toString() + ")"; }
return null; } else { CastExpression cast = new CastExpression(arguments[0], (AtomicType) type, true); if (arguments[0] instanceof StringLiteral) { cast.setOperandIsStringLiteral(true); if (st instanceof SimpleType) { if (st instanceof AtomicType) { return new CastExpression(arguments[0], (AtomicType) st, true); } else if (st instanceof ListType && env.getXPathVersion() >= 30) { NamespaceResolver resolver = env.getNamespaceResolver();
/** * Perform early (compile-time) evaluation */ protected Expression preEvaluate() throws XPathException { GroundedValue literalOperand = ((Literal) getBaseExpression()).getValue(); if (literalOperand instanceof AtomicValue && converter != null) { ConversionResult result = converter.convert((AtomicValue) literalOperand); if (result instanceof ValidationFailure) { ValidationFailure err = (ValidationFailure) result; String code = err.getErrorCode(); if (code == null) { code = "FORG0001"; } throw new XPathException(err.getMessage(), code, this.getLocation()); } else { return Literal.makeLiteral((AtomicValue) result, this); } } if (literalOperand.getLength() == 0) { if (allowsEmpty()) { return getBaseExpression(); } else { XPathException err = new XPathException("Cast can never succeed: the operand must not be an empty sequence", "XPTY0004", this.getLocation()); err.setIsTypeError(true); throw err; } } return this; }
private AtomicValue doCast(AtomicValue value, XPathContext context) throws XPathException { if (value == null) { if (allowsEmpty()) { return null; } else { XPathException e = new XPathException("Cast does not allow an empty sequence"); e.setXPathContext(context); e.setLocation(getLocation()); e.setErrorCode("XPTY0004"); throw e; if (converter == null) { ConversionRules rules = context.getConfiguration().getConversionRules(); converter = rules.getConverter(value.getPrimitiveType(), getTargetType()); if (converter == null) { XPathException e = new XPathException("Casting from " + value.getPrimitiveType() + " to " + getTargetType() + " is not permitted"); e.setXPathContext(context); e.setLocation(getLocation()); e.setErrorCode("XPTY0004"); throw e; if (getTargetType().isNamespaceSensitive()) { converter = converter.setNamespaceResolver(getRetainedStaticContext()); XPathException xe = err.makeException(); xe.maybeSetErrorCode("FORG0001"); xe.maybeSetLocation(getLocation()); throw xe;
SequenceType atomicType = SequenceType.makeSequenceType(BuiltInAtomicType.ANY_ATOMIC, getCardinality()); Value literalOperand = ((Literal)operand).getValue(); if (literalOperand instanceof AtomicValue) { AtomicValue av = ((AtomicValue)evaluateItem(visitor.getStaticContext().makeEarlyEvaluationContext())); if (av instanceof StringValue) { return new StringLiteral((StringValue)av); if (!isPossibleCast(p, targetType.getPrimitiveType())) { XPathException err = new XPathException("Casting from " + sourceType + " to " + targetType + " can never succeed");
/** * Get the static cardinality of the expression */ public int computeCardinality() { return allowsEmpty() && Cardinality.allowsZero(getBaseExpression().getCardinality()) ? StaticProperty.ALLOWS_ZERO_OR_ONE : StaticProperty.EXACTLY_ONE; }
try { String source = ((StringLiteral)exp).getStringValue(); return new Literal(CastExpression.castStringToQName(source, at, env)); } catch (XPathException e) { grumble(e.getMessage(), e.getErrorCodeLocalPart()); exp = new CastExpression(exp, at, allowEmpty); exp = ExpressionVisitor.make(env).simplify(exp);
/** * Get the static type of the expression */ /*@NotNull*/ public ItemType getItemType() { return getTargetType(); }
public Sequence<?> call(XPathContext context, Sequence[] arguments) throws XPathException { AtomicValue result = doCast((AtomicValue)arguments[0].head(), context); return result == null ? EmptySequence.getInstance() : result; }
/** * Create a cast expression * @param source expression giving the value to be converted * @param target the type to which the value is to be converted * @param allowEmpty true if the expression allows an empty sequence as input, producing * an empty sequence as output. If false, an empty sequence is a type error. */ public CastExpression(Expression source, AtomicType target, boolean allowEmpty) { super(source); this.allowEmpty = allowEmpty; targetType = target; targetPrimitiveType = (AtomicType)target.getPrimitiveItemType(); derived = (targetType.getFingerprint() != targetPrimitiveType.getFingerprint()); adoptChildExpression(source); }
ValidationFailure err = (ValidationFailure)result; String code = err.getErrorCode(); dynamicError(err.getMessage(), code, context); return null;
arguments[0] instanceof StringLiteral) { try { AtomicValue av = CastExpression.castStringToQName(((StringLiteral)arguments[0]).getStringValue(), (AtomicType)fcall.getItemType(env.getConfiguration().getTypeHierarchy()), env);
getOperand().typeCheck(visitor, contextInfo); SequenceType atomicType = SequenceType.makeSequenceType(BuiltInAtomicType.ANY_ATOMIC, getCardinality()); Expression operand = tc.staticTypeCheck(getBaseExpression(), atomicType, role, visitor); setBaseExpression(operand); sourceItemType = operand.getItemType(); if (allowsEmpty()) { return Literal.makeEmptySequence(); } else { XPathException err = new XPathException("Cast does not allow an empty sequence as input"); err.setErrorCode("XPTY0004"); err.setLocation(getLocation()); err.setIsTypeError(true); throw err; int r = th.relationship(sourceType, getTargetType()); if (r == TypeHierarchy.SAME_TYPE) { return operand; converter = new Converter.UpCastingConverter(getTargetType()); } else { converter = rules.getConverter((AtomicType)sourceType, getTargetType()); if (converter == null) { XPathException err = new XPathException("Casting from " + sourceType + " to " + getTargetType() + " can never succeed"); err.setErrorCode("XPTY0004"); err.setLocation(getLocation());