1 package com.icl.saxon.expr; 2 import com.icl.saxon.Context; 3 import com.icl.saxon.functions.*; 4 5 6 10 11 final class RelationalExpression extends BinaryExpression { 12 13 16 17 public RelationalExpression(){}; 18 19 25 26 public RelationalExpression(Expression p1, int op, Expression p2) { 27 super(p1, op, p2); 28 } 29 30 34 35 public Expression simplify() throws XPathException { 36 37 p1 = p1.simplify(); 38 p2 = p2.simplify(); 39 40 42 if (p1 instanceof SingletonExpression && 43 (p2 instanceof StringValue || 44 p2 instanceof NumericValue || 45 p2 instanceof FragmentValue || 46 p2 instanceof TextFragmentValue )) { 47 48 Expression s = new SingletonComparison((SingletonExpression)p1, operator, (Value)p2); 49 s.setStaticContext(getStaticContext()); 50 return s; 51 } 52 53 if (p2 instanceof SingletonExpression && 54 (p1 instanceof StringValue || 55 p1 instanceof NumericValue || 56 p1 instanceof FragmentValue || 57 p1 instanceof TextFragmentValue )) { 58 59 Expression s = new SingletonComparison((SingletonExpression)p2, 60 Value.inverse(operator), (Value)p1); 61 s.setStaticContext(getStaticContext()); 62 return s; 63 } 64 65 67 if (p1 instanceof NodeSetExpression && 68 (p2 instanceof StringValue || 69 p2 instanceof NumericValue || 70 p2 instanceof FragmentValue || 71 p2 instanceof TextFragmentValue )) { 72 73 Expression s = new NodeSetComparison((NodeSetExpression)p1, operator, (Value)p2); 74 s.setStaticContext(getStaticContext()); 75 return s; 76 } 77 78 if (p2 instanceof NodeSetExpression && 79 (p1 instanceof StringValue || 80 p1 instanceof NumericValue || 81 p1 instanceof FragmentValue || 82 p1 instanceof TextFragmentValue )) { 83 84 Expression s = new NodeSetComparison((NodeSetExpression)p2, 85 Value.inverse(operator), (Value)p1); 86 s.setStaticContext(getStaticContext()); 87 return s; 88 } 89 90 92 if ((p1 instanceof Value) && (p2 instanceof Value)) { 93 return evaluate(null); 94 } 95 96 98 if ((p1 instanceof Count) && (((Count)p1).getNumberOfArguments()==1) && 99 (((Count)p1).argument[0].getDataType()==Value.NODESET) && 100 (p2 instanceof NumericValue) && (((Value)p2).asNumber()==0)) { 101 if (operator == Tokenizer.EQUALS || operator == Tokenizer.LE) { 102 Not fn = new Not(); 104 fn.addArgument(((Count)p1).argument[0]); 105 fn.setStaticContext(getStaticContext()); 106 return fn; 107 } else if (operator == Tokenizer.NE || operator == Tokenizer.GT) { 108 BooleanFn fn = new BooleanFn(); 110 fn.addArgument(((Count)p1).argument[0]); 111 fn.setStaticContext(getStaticContext()); 112 return fn; 113 } else if (operator == Tokenizer.GE) { 114 return new BooleanValue(true); 116 } else { return new BooleanValue(false); 119 } 120 } 121 122 124 if ((p2 instanceof Count) && 125 (p1 instanceof NumericValue) && (((Value)p1).asNumber()==0)) { 126 Expression s = new RelationalExpression(p2, Value.inverse(operator), p1).simplify(); 127 s.setStaticContext(getStaticContext()); 128 return s; 129 } 130 131 133 if ((p1 instanceof StringLength) && 134 (((StringLength)p1).getNumberOfArguments()==1) && 135 (p2 instanceof NumericValue) && (((Value)p2).asNumber()==0)) { 136 137 Expression arg = ((StringLength)p1).argument[0]; 139 if (!(arg instanceof StringValue)) { 140 StringFn fn = new StringFn(); 141 fn.addArgument(arg); 142 arg = fn; 143 } 144 145 if (operator == Tokenizer.EQUALS || operator == Tokenizer.LE) { 146 Not fn = new Not(); 148 fn.addArgument(arg); 149 fn.setStaticContext(getStaticContext()); 150 return fn; 151 } else if (operator == Tokenizer.GT || operator == Tokenizer.NE) { 152 BooleanFn fn = new BooleanFn(); 154 fn.addArgument(arg); 155 fn.setStaticContext(getStaticContext()); 156 return fn; 157 } else if (operator == Tokenizer.GE) { 158 return new BooleanValue(true); 160 } else { 161 return new BooleanValue(false); 163 } 164 } 165 166 168 if ((p2 instanceof StringLength) && 169 (p1 instanceof NumericValue) && (((Value)p1).asNumber()==0)) { 170 Expression s = new RelationalExpression(p2, Value.inverse(operator), p1).simplify(); 171 s.setStaticContext(getStaticContext()); 172 return s; 173 } 174 175 177 if ((p1 instanceof Position) && (p2 instanceof NumericValue)) { 178 double pos = ((NumericValue)p2).asNumber(); 179 switch (operator) { 180 case Tokenizer.EQUALS: 181 return new PositionRange((int)pos, (int)pos); 182 case Tokenizer.GE: 183 return new PositionRange((int)pos, Integer.MAX_VALUE); 184 case Tokenizer.NE: 185 break; 186 case Tokenizer.LT: 187 return new PositionRange(1, (int)Math.floor(pos - 0.00000000001) ); 188 case Tokenizer.GT: 189 return new PositionRange((int)Math.ceil(pos + 0.00000000001), Integer.MAX_VALUE); 190 case Tokenizer.LE: 191 return new PositionRange(1, ((int)pos)); 192 } 193 } 194 if ((p1 instanceof NumericValue) && (p2 instanceof Position)) { 195 double pos = ((NumericValue)p1).asNumber(); 196 switch (operator) { 197 case Tokenizer.EQUALS: 198 return new PositionRange((int)pos, (int)pos); 199 case Tokenizer.LE: 200 return new PositionRange((int)pos, Integer.MAX_VALUE); 201 case Tokenizer.NE: 202 break; 203 case Tokenizer.GT: 204 return new PositionRange(1, (int)Math.floor(pos - 0.00000000001) ); 205 case Tokenizer.LT: 206 return new PositionRange((int)Math.ceil(pos + 0.00000000001), Integer.MAX_VALUE); 207 case Tokenizer.GE: 208 return new PositionRange(1, (int)pos); 209 } 210 } 211 212 214 if ((p1 instanceof Position) && (p2 instanceof Last)) { 215 switch (operator) { 216 case Tokenizer.EQUALS: 217 case Tokenizer.GE: 218 return new IsLastExpression(true); 219 case Tokenizer.NE: 220 case Tokenizer.LT: 221 return new IsLastExpression(false); 222 case Tokenizer.GT: 223 return new BooleanValue(false); 224 case Tokenizer.LE: 225 return new BooleanValue(true); 226 } 227 } 228 if ((p1 instanceof Last) && (p2 instanceof Position)) { 229 switch (operator) { 230 case Tokenizer.EQUALS: 231 case Tokenizer.LE: 232 return new IsLastExpression(true); 233 case Tokenizer.NE: 234 case Tokenizer.GT: 235 return new IsLastExpression(false); 236 case Tokenizer.LT: 237 return new BooleanValue(false); 238 case Tokenizer.GE: 239 return new BooleanValue(true); 240 } 241 } 242 return this; 243 } 244 245 250 251 public Value evaluate(Context c) throws XPathException { 252 return new BooleanValue(evaluateAsBoolean(c)); 253 } 254 255 260 261 public boolean evaluateAsBoolean(Context c) throws XPathException { 262 Value s1 = p1.evaluate(c); 263 Value s2 = p2.evaluate(c); 264 return s1.compare(operator, s2); 265 } 266 267 271 272 public int getDataType() { 273 return Value.BOOLEAN; 274 } 275 276 284 285 public Expression reduce(int dependencies, Context context) throws XPathException { 286 287 if ((getDependencies() & dependencies) != 0 ) { 288 Expression e = new RelationalExpression( 289 p1.reduce(dependencies, context), 290 operator, 291 p2.reduce(dependencies, context)); 292 e.setStaticContext(getStaticContext()); 293 return e.simplify(); 294 } else { 295 return this; 296 } 297 } 298 299 300 } 301 302 | Popular Tags |