KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > gnu > xquery > util > Compare


1 // Copyright (c) 2001, 2003, 2006 Per M.A. Bothner and Brainfood Inc.
2
// This is free software; for terms and warranty disclaimer see ./COPYING.
3

4 package gnu.xquery.util;
5 import gnu.mapping.*;
6 import gnu.kawa.functions.NumberCompare;
7 import gnu.math.*;
8 import gnu.expr.*;
9 import gnu.kawa.xml.*;
10 import gnu.bytecode.ClassType;
11
12 /** Compares two values (or sequences) according to XPath semantics. */
13
14 public class Compare extends Procedure2 implements CanInline
15 {
16   static final int RESULT_GRT = 1;
17   static final int RESULT_EQU = 0;
18   static final int RESULT_LSS = -1;
19   static final int RESULT_NAN = -2;
20   static final int RESULT_NEQ = -3;
21
22   // One flag bit for each of the above RESULT_XXX codes:
23
static final int TRUE_IF_GRT = 1 << (RESULT_GRT + 3);
24   static final int TRUE_IF_EQU = 1 << (RESULT_EQU + 3);
25   static final int TRUE_IF_LSS = 1 << (RESULT_LSS + 3);
26   static final int TRUE_IF_NAN = 1 << (RESULT_NAN + 3);
27   static final int TRUE_IF_NEQ = 1 << (RESULT_NEQ + 3);
28   static final int VALUE_COMPARISON = 1 << 5;
29   static final int LENIENT_COMPARISON = 1 << 6;
30   static final int LENIENT_EQ = (TRUE_IF_EQU|LENIENT_COMPARISON);
31
32   int flags;
33
34   public static Compare make(String JavaDoc name, int flags)
35   {
36     Compare proc = new Compare();
37     proc.setName(name);
38     proc.flags = flags;
39     return proc;
40   }
41
42   /*
43   private static Object toString(object value)
44   {
45     if (value instanceof TreeList)
46       return = ((TreeList) value).stringValue(0, sbuf);
47     else if (value instanceof SeqPosition && ! (node instanceof TreePosition))
48       {
49     SeqPosition pos = (SeqPosition) value;
50     if (pos.sequence instanceof TreeList)
51       {
52         ((TreeList) pos.sequence).stringValue(pos.ipos >> 1, sbuf);
53         return;
54       }
55       }
56   }
57   */

58
59   public static boolean apply(int flags, Object JavaDoc arg1, Object JavaDoc arg2,
60                               NamedCollator collator)
61   {
62     if (arg1 instanceof Values)
63       {
64     Values values1 = (Values) arg1;
65     int index = 0;
66     for (;;)
67       {
68         int next = values1.nextDataIndex(index);
69         if (next < 0)
70           return false;
71         if (apply(flags, values1.getPosNext(index << 1), arg2, collator))
72           return true;
73         index = next;
74       }
75       }
76     if (arg2 instanceof Values)
77       {
78     Values values2 = (Values) arg2;
79     int index = 0;
80     for (;;)
81       {
82         int next = values2.nextDataIndex(index);
83         if (next < 0)
84           return false;
85         if (apply(flags, arg1, values2.getPosNext(index << 1), collator))
86           return true;
87         index = next;
88       }
89       }
90     return atomicCompare(flags,
91                          KNode.atomicValue(arg1),
92                          KNode.atomicValue(arg2),
93                          collator);
94   }
95
96   public static boolean equalityComparison (int flags)
97   {
98     return ((flags & TRUE_IF_GRT) != 0) == ((flags & TRUE_IF_LSS) != 0);
99   }
100
101   public static boolean atomicCompare(int flags, Object JavaDoc arg1, Object JavaDoc arg2,
102                                       NamedCollator collator)
103   {
104     if (arg1 instanceof UntypedAtomic)
105       {
106         String JavaDoc str = arg1.toString();
107         if ((flags & VALUE_COMPARISON) != 0)
108           arg1 = str;
109         else if (arg2 instanceof DateTime)
110           arg1 = XTimeType.parseDateTime(str, ((DateTime) arg2).components());
111         else if (arg2 instanceof Duration)
112           arg1 = Duration.parse(str, ((Duration) arg2).unit());
113         else if (arg2 instanceof Number JavaDoc)
114           arg1 = new DFloNum(str);
115         else if (arg2 instanceof Boolean JavaDoc)
116           arg1 = XDataType.booleanType.valueOf(str);
117         else
118           arg1 = str;
119       }
120     if (arg2 instanceof UntypedAtomic)
121       {
122         String JavaDoc str = arg2.toString();
123         if ((flags & VALUE_COMPARISON) != 0)
124           arg2 = str;
125         else if (arg1 instanceof DateTime)
126           arg2 = XTimeType.parseDateTime(str, ((DateTime) arg1).components());
127         else if (arg1 instanceof Duration)
128           arg2 = Duration.parse(str, ((Duration) arg1).unit());
129         else if (arg1 instanceof Number JavaDoc)
130           arg2 = new DFloNum(str);
131         else if (arg1 instanceof Boolean JavaDoc)
132           arg2 = XDataType.booleanType.valueOf(str);
133         else
134           arg2 = str;
135       }
136     int comp;
137     if (arg1 instanceof Number JavaDoc || arg2 instanceof Number JavaDoc)
138       {
139         if (arg1 instanceof Duration)
140           {
141             if (! (arg2 instanceof Duration))
142               comp = -3;
143             else
144               {
145                 Duration d1 = (Duration) arg1;
146                 Duration d2 = (Duration) arg2;
147                 if ((d1.unit != d2.unit || d1.unit == Unit.duration)
148                     && ! equalityComparison(flags))
149                   comp = -3;
150                 else
151                   comp = Duration.compare(d1, d2);
152               }
153           }
154         else if (arg1 instanceof DateTime)
155           {
156             if (! (arg2 instanceof DateTime))
157               comp = -3;
158             else
159               {
160                 DateTime d1 = (DateTime) arg1;
161                 DateTime d2 = (DateTime) arg2;
162                 int m1 = d1.components();
163                 int m2 = d2.components();
164                 if (m1 != m2)
165                   comp = -3;
166                 else if (! equalityComparison(flags)
167                          && m1 != DateTime.TIME_MASK
168                          && m1 != DateTime.DATE_MASK
169                          && m1 != (DateTime.DATE_MASK|DateTime.TIME_MASK))
170                   comp = -3;
171                 else
172                   comp = DateTime.compare(d1, d2);
173               }
174           }
175         else if (arg2 instanceof Duration || arg2 instanceof DateTime)
176           comp = -3;
177         else
178           comp = NumberCompare.compare(arg1, arg2, false);
179         if (comp == -3 && (flags & LENIENT_COMPARISON) == 0)
180           throw new IllegalArgumentException JavaDoc("values cannot be compared");
181         return NumberCompare.checkCompareCode(comp, flags);
182       }
183     if (arg1 instanceof Symbol)
184       {
185         if (arg2 instanceof Symbol && equalityComparison(flags))
186           comp = arg1.equals(arg2) ? 0 : -2;
187         else
188           comp = -3;
189       }
190     else if (arg1 instanceof Boolean JavaDoc)
191       {
192         if (arg2 instanceof Boolean JavaDoc)
193           {
194             boolean b1 = ((Boolean JavaDoc) arg1).booleanValue();
195             boolean b2 = ((Boolean JavaDoc) arg2).booleanValue();
196             comp = b1 == b2 ? 0 : b2 ? -1 : 1;
197           }
198         else
199           comp = -3;
200       }
201     else if (arg2 instanceof Boolean JavaDoc || arg2 instanceof Symbol)
202       comp = -3;
203     else
204       {
205         String JavaDoc str1 = arg1.toString();
206         String JavaDoc str2 = arg2.toString();
207         /* #ifdef JAVA2 */
208         if (collator != null)
209           comp = collator.compare(str1, str2);
210         else
211         /* #endif */
212           comp = str1.compareTo(str2);
213         comp = comp < 0 ? -1 : comp > 0 ? 1 : 0;
214       }
215     if (comp == -3 && (flags & LENIENT_COMPARISON) == 0)
216       throw new IllegalArgumentException JavaDoc("values cannot be compared");
217     return NumberCompare.checkCompareCode(comp, flags);
218   }
219
220   public Object JavaDoc apply2 (Object JavaDoc arg1, Object JavaDoc arg2)
221   {
222     if ((flags & VALUE_COMPARISON) != 0)
223       {
224         if (arg1 == null || arg1 == Values.empty) return arg1;
225         if (arg2 == null || arg2 == Values.empty) return arg2;
226         return atomicCompare(flags,
227                              KNode.atomicValue(arg1),
228                              KNode.atomicValue(arg2),
229                              null) ? Boolean.TRUE: Boolean.FALSE;
230       }
231     return apply(flags, arg1, arg2, null) ? Boolean.TRUE : Boolean.FALSE;
232   }
233
234   public static final Compare $Eq = make("=",TRUE_IF_EQU);
235   public static final Compare $Ex$Eq
236   = make("!=",TRUE_IF_GRT|TRUE_IF_LSS|TRUE_IF_NAN|TRUE_IF_NEQ);
237   public static final Compare $Gr = make(">",TRUE_IF_GRT);
238   public static final Compare $Gr$Eq= make(">=",TRUE_IF_GRT|TRUE_IF_EQU);
239   public static final Compare $Ls = make("<",TRUE_IF_LSS);
240   public static final Compare $Ls$Eq= make("<=",TRUE_IF_LSS|TRUE_IF_EQU);
241
242   public static final Compare valEq =
243     make("eq",TRUE_IF_EQU|VALUE_COMPARISON);
244   public static final Compare valNe =
245     make("ne",TRUE_IF_GRT|TRUE_IF_LSS|TRUE_IF_NAN|TRUE_IF_NEQ|VALUE_COMPARISON);
246   public static final Compare valGt =
247     make("gt",TRUE_IF_GRT|VALUE_COMPARISON);
248   public static final Compare valGe =
249     make("ge",TRUE_IF_GRT|TRUE_IF_EQU|VALUE_COMPARISON);
250   public static final Compare valLt =
251     make("lt",TRUE_IF_LSS|VALUE_COMPARISON);
252   public static final Compare valLe =
253     make("le",TRUE_IF_LSS|TRUE_IF_EQU|VALUE_COMPARISON);
254
255   public Expression inline (ApplyExp exp, ExpWalker walker)
256   {
257     Expression folded = exp.inlineIfConstant(this, walker);
258     if (folded != exp)
259       return folded;
260     if ((flags & VALUE_COMPARISON) != 0)
261       {
262       }
263     else
264       {
265         exp = new ApplyExp(ClassType.make("gnu.xquery.util.Compare")
266                            .getDeclaredMethod("apply", 4),
267                            new Expression[] { new QuoteExp(IntNum.make(flags)),
268                                               exp.getArg(0),
269                                               exp.getArg(1),
270                                               QuoteExp.nullExp });
271       }
272     if (exp.getTypeRaw() == null)
273       exp.setType(XDataType.booleanType);
274     return exp;
275   }
276 }
277
Popular Tags