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.om.SequenceIterator; 5 import net.sf.saxon.trans.XPathException; 6 import net.sf.saxon.type.ItemType; 7 import net.sf.saxon.type.Type; 8 import net.sf.saxon.value.*; 9 10 import java.io.PrintStream ; 11 12 15 16 public final class InstanceOfExpression extends UnaryExpression { 17 18 ItemType targetType; 19 int targetCardinality; 20 21 public InstanceOfExpression(Expression source, SequenceType target) { 22 super(source); 23 targetType = target.getPrimaryType(); 24 if (targetType == null) { 25 throw new IllegalArgumentException ("Primary item type must not be null"); 26 } 27 targetCardinality = target.getCardinality(); 28 } 29 30 34 35 public Expression typeCheck(StaticContext env, ItemType contextItemType) throws XPathException { 36 operand = operand.typeCheck(env, contextItemType); 37 if (operand instanceof Value) { 38 return (AtomicValue)evaluateItem(null); 39 } 40 41 43 if (Cardinality.subsumes(targetCardinality, operand.getCardinality())) { 44 int relation = Type.relationship(operand.getItemType(), targetType); 45 if (relation == Type.SAME_TYPE || relation == Type.SUBSUMED_BY) { 46 return BooleanValue.TRUE; 47 } else if (relation == Type.DISJOINT) { 48 if (!Cardinality.allowsZero(targetCardinality) || !Cardinality.allowsZero(operand.getCardinality())) { 50 return BooleanValue.FALSE; 51 } 52 } 53 } 54 return this; 55 } 56 57 74 75 public Expression optimize(Optimizer opt, StaticContext env, ItemType contextItemType) throws XPathException { 76 Expression e = super.optimize(opt, env, contextItemType); 77 if (e != this) { 78 return e; 79 } 80 if (Cardinality.subsumes(targetCardinality, operand.getCardinality())) { 81 int relation = Type.relationship(operand.getItemType(), targetType); 82 if (relation == Type.SAME_TYPE || relation == Type.SUBSUMED_BY) { 83 return BooleanValue.TRUE; 84 } else if (relation == Type.DISJOINT) { 85 if (!Cardinality.allowsZero(targetCardinality) || !Cardinality.allowsZero(operand.getCardinality())) { 87 return BooleanValue.FALSE; 88 } 89 } 90 } 91 return this; 92 } 93 94 95 98 99 public boolean equals(Object other) { 100 return super.equals(other) && 101 targetType == ((InstanceOfExpression)other).targetType && 102 targetCardinality == ((InstanceOfExpression)other).targetCardinality; 103 } 104 105 108 109 public int computeCardinality() { 110 return StaticProperty.EXACTLY_ONE; 111 } 112 113 116 117 public ItemType getItemType() { 118 return Type.BOOLEAN_TYPE; 119 } 120 121 124 125 public Item evaluateItem(XPathContext context) throws XPathException { 126 return BooleanValue.get(effectiveBooleanValue(context)); 127 } 128 129 132 133 public boolean effectiveBooleanValue(XPathContext context) throws XPathException { 134 SequenceIterator iter = operand.iterate(context); 135 int count = 0; 136 while (true) { 137 Item item = iter.next(); 138 if (item == null) break; 139 count++; 140 if (!targetType.matchesItem(item)) { 141 return false; 142 } 143 if (count==2 && !Cardinality.allowsMany(targetCardinality)) { 144 return false; 145 } 146 } 147 if (count==0 && ((targetCardinality & StaticProperty.ALLOWS_ZERO)==0)) { 148 return false; 149 } 150 return true; 151 } 152 153 157 158 protected String displayOperator(NamePool pool) { 159 return "instance of " + targetType.toString(pool) + Cardinality.getOccurrenceIndicator(targetCardinality); 160 } 161 162 165 166 public void display(int level, NamePool pool, PrintStream out) { 167 out.println(ExpressionTool.indent(level) + "instance of" ); 168 operand.display(level+1, pool, out); 169 out.println(ExpressionTool.indent(level+1) + 170 targetType.toString(pool) + 171 Cardinality.getOccurrenceIndicator(targetCardinality)); 172 } 173 174 } 175 176 | Popular Tags |