1 package net.sf.saxon.expr; 2 import net.sf.saxon.om.Item; 3 import net.sf.saxon.om.NamePool; 4 import net.sf.saxon.trans.XPathException; 5 import net.sf.saxon.type.AtomicType; 6 import net.sf.saxon.type.BuiltInAtomicType; 7 import net.sf.saxon.type.ItemType; 8 import net.sf.saxon.type.Type; 9 import net.sf.saxon.value.*; 10 11 15 16 public final class CastableExpression extends UnaryExpression { 17 18 AtomicType targetType; 19 boolean allowEmpty; 20 21 public CastableExpression(Expression source, AtomicType target, boolean allowEmpty) { 22 super(source); 23 this.targetType = target; 24 this.allowEmpty = allowEmpty; 25 } 26 27 31 32 public Expression simplify(StaticContext env) throws XPathException { 33 operand = operand.simplify(env); 34 if (operand instanceof Value) { 35 return BooleanValue.get(effectiveBooleanValue(null)); 36 } 37 return this; 38 } 39 40 43 44 public Expression typeCheck(StaticContext env, ItemType contextItemType) throws XPathException { 45 operand = operand.typeCheck(env, contextItemType); 46 SequenceType atomicType = SequenceType.makeSequenceType( 47 Type.ANY_ATOMIC_TYPE, 48 (allowEmpty ? StaticProperty.ALLOWS_ZERO_OR_ONE 49 : StaticProperty.EXACTLY_ONE)); 50 51 RoleLocator role = new RoleLocator(RoleLocator.TYPE_OP, "castable as", 0, null); 52 role.setSourceLocator(this); 53 operand = TypeChecker.staticTypeCheck(operand, atomicType, false, role, env); 54 55 if (operand instanceof AtomicValue) { 56 return BooleanValue.get(effectiveBooleanValue(null)); 57 } 58 return this; 59 } 60 61 64 65 public Expression optimize(Optimizer opt, StaticContext env, ItemType contextItemType) throws XPathException { 66 operand = operand.optimize(opt, env, contextItemType); 67 if (operand instanceof AtomicValue) { 68 return BooleanValue.get(effectiveBooleanValue(null)); 69 } 70 return this; 71 } 72 73 74 75 78 79 public boolean equals(Object other) { 80 return super.equals(other) && 81 targetType == ((CastableExpression)other).targetType && 82 allowEmpty == ((CastableExpression)other).allowEmpty; 83 } 84 85 88 89 public ItemType getItemType() { 90 return Type.BOOLEAN_TYPE; 91 } 92 93 public int computeCardinality() { 94 return StaticProperty.EXACTLY_ONE; 95 } 96 97 101 102 public int computeSpecialProperties() { 103 int p = super.computeSpecialProperties(); 104 return p | StaticProperty.NON_CREATIVE; 105 } 106 107 110 111 public Item evaluateItem(XPathContext context) { 112 return BooleanValue.get(effectiveBooleanValue(context)); 113 } 114 115 public boolean effectiveBooleanValue(XPathContext context) { 116 try { 117 AtomicValue value = (AtomicValue)operand.evaluateItem(context); 118 if (value == null) { 119 return allowEmpty; 120 } 121 if (targetType instanceof BuiltInAtomicType) { 122 return !(value.convert(targetType, context, true) instanceof ValidationErrorValue); 123 } else { 124 AtomicValue prim = 125 value.convert((AtomicType)targetType.getBuiltInBaseType(), context, true); 126 if (prim instanceof ValidationErrorValue) { 127 return false; 128 } 129 AtomicValue val = 130 targetType.makeDerivedValue(prim, prim.getStringValueCS(), true); 131 return !(val instanceof ValidationErrorValue); 132 } 133 } catch (XPathException err) { 134 return false; 135 } 136 } 137 138 142 143 protected String displayOperator(NamePool pool) { 144 return "castable as " + targetType.toString(pool); 145 } 146 147 } 148 149 | Popular Tags |