|
Lines 8-17
Link Here
|
| 8 |
* Contributors: |
8 |
* Contributors: |
| 9 |
* Andrea Bittau - initial API and implementation from the PsychoPath XPath 2.0 |
9 |
* Andrea Bittau - initial API and implementation from the PsychoPath XPath 2.0 |
| 10 |
* Jesper Steen Moeller - bug 285145 - implement full arity checking |
10 |
* Jesper Steen Moeller - bug 285145 - implement full arity checking |
|
|
11 |
* Jesper Steen Moeller - bug 280555 - Add pluggable collation support |
| 11 |
*******************************************************************************/ |
12 |
*******************************************************************************/ |
| 12 |
|
13 |
|
| 13 |
package org.eclipse.wst.xml.xpath2.processor.internal.function; |
14 |
package org.eclipse.wst.xml.xpath2.processor.internal.function; |
| 14 |
|
15 |
|
|
|
16 |
import org.eclipse.wst.xml.xpath2.processor.DynamicContext; |
| 15 |
import org.eclipse.wst.xml.xpath2.processor.DynamicError; |
17 |
import org.eclipse.wst.xml.xpath2.processor.DynamicError; |
| 16 |
import org.eclipse.wst.xml.xpath2.processor.ResultSequence; |
18 |
import org.eclipse.wst.xml.xpath2.processor.ResultSequence; |
| 17 |
import org.eclipse.wst.xml.xpath2.processor.ResultSequenceFactory; |
19 |
import org.eclipse.wst.xml.xpath2.processor.ResultSequenceFactory; |
|
Lines 58-65
Link Here
|
| 58 |
* Constructor of FnCompare. |
60 |
* Constructor of FnCompare. |
| 59 |
*/ |
61 |
*/ |
| 60 |
public FnCompare() { |
62 |
public FnCompare() { |
| 61 |
// XXX: This should be 2-3 when compare learns how to deal with collations |
63 |
super(new QName("compare"), 2, 3); |
| 62 |
super(new QName("compare"), 2); |
|
|
| 63 |
} |
64 |
} |
| 64 |
|
65 |
|
| 65 |
/** |
66 |
/** |
|
Lines 73-117
Link Here
|
| 73 |
*/ |
74 |
*/ |
| 74 |
@Override |
75 |
@Override |
| 75 |
public ResultSequence evaluate(Collection args) throws DynamicError { |
76 |
public ResultSequence evaluate(Collection args) throws DynamicError { |
| 76 |
return compare(args); |
77 |
return compare(args, dynamic_context()); |
| 77 |
} |
78 |
} |
| 78 |
|
79 |
|
| 79 |
/** |
80 |
/** |
| 80 |
* Compare the arguments. |
81 |
* Compare the arguments. |
| 81 |
* |
82 |
* |
| 82 |
* @param args |
83 |
* @param args |
| 83 |
* are compared. |
84 |
* are compared (optional 3rd argument is the collation) |
|
|
85 |
* @param dynamicContext |
| 86 |
* Current dynamic context |
| 84 |
* @throws DynamicError |
87 |
* @throws DynamicError |
| 85 |
* Dynamic error. |
88 |
* Dynamic error. |
| 86 |
* @return The result of the comparison of the arguments. |
89 |
* @return The result of the comparison of the arguments. |
| 87 |
*/ |
90 |
*/ |
| 88 |
public static ResultSequence compare(Collection args) throws DynamicError { |
91 |
public static ResultSequence compare(Collection args, DynamicContext dynamicContext) throws DynamicError { |
| 89 |
Collection cargs = Function.convert_arguments(args, expected_args()); |
92 |
Collection cargs = Function.convert_arguments(args, expected_args()); |
| 90 |
|
93 |
|
| 91 |
ResultSequence rs = ResultSequenceFactory.create_new(); |
|
|
| 92 |
|
| 93 |
Iterator argiter = cargs.iterator(); |
94 |
Iterator argiter = cargs.iterator(); |
| 94 |
ResultSequence arg1 = (ResultSequence) argiter.next(); |
95 |
ResultSequence arg1 = (ResultSequence) argiter.next(); |
| 95 |
if (arg1.empty()) |
|
|
| 96 |
return rs; |
| 97 |
ResultSequence arg2 = (ResultSequence) argiter.next(); |
96 |
ResultSequence arg2 = (ResultSequence) argiter.next(); |
| 98 |
if (arg2.empty()) |
|
|
| 99 |
return rs; |
| 100 |
|
97 |
|
| 101 |
XSString xstr1 = (XSString) arg1.first(); |
98 |
String collationUri = dynamicContext.default_collation_name(); |
| 102 |
XSString xstr2 = (XSString) arg2.first(); |
99 |
if (argiter.hasNext()) { |
|
|
100 |
ResultSequence collArg = (ResultSequence) argiter.next(); |
| 101 |
collationUri = collArg.first().string_value(); |
| 102 |
} |
| 103 |
|
103 |
|
| 104 |
// XXX collations!!! |
104 |
XSString xstr1 = arg1.empty() ? null : (XSString) arg1.first(); |
| 105 |
int ret = xstr1.value().compareTo(xstr2.value()); |
105 |
XSString xstr2 = arg2.empty() ? null : (XSString) arg2.first(); |
|
|
106 |
|
| 107 |
BigInteger result = compare_string(collationUri, xstr1, xstr2, dynamicContext); |
| 108 |
if (result != null) { |
| 109 |
return ResultSequenceFactory.create_new(new XSInteger(result)); |
| 110 |
} else { |
| 111 |
return ResultSequenceFactory.create_new(); |
| 112 |
} |
| 113 |
} |
| 114 |
|
| 115 |
public static BigInteger compare_string(String collationUri, XSString xstr1, |
| 116 |
XSString xstr2, DynamicContext dynamicContext) throws DynamicError { |
| 117 |
Comparator collator = dynamicContext.get_collation(collationUri); |
| 118 |
if (collator == null) throw DynamicError.unsupported_collation(collationUri); |
| 119 |
|
| 120 |
if (xstr1 == null || xstr2 == null) return null; |
| 121 |
|
| 122 |
int ret = collator.compare(xstr1.value(), xstr2.value()); |
| 106 |
|
123 |
|
| 107 |
if (ret == 0) |
124 |
if (ret == 0) |
| 108 |
rs.add(new XSInteger(BigInteger.valueOf(0))); |
125 |
return BigInteger.ZERO; |
| 109 |
else if (ret < 0) |
126 |
else if (ret < 0) |
| 110 |
rs.add(new XSInteger(BigInteger.valueOf(-1))); |
127 |
return BigInteger.valueOf(-1); |
| 111 |
else |
128 |
else |
| 112 |
rs.add(new XSInteger(BigInteger.valueOf(1))); |
129 |
return BigInteger.ONE; |
| 113 |
|
|
|
| 114 |
return rs; |
| 115 |
} |
130 |
} |
| 116 |
|
131 |
|
| 117 |
/** |
132 |
/** |
|
Lines 125-130
Link Here
|
| 125 |
SeqType arg = new SeqType(new XSString(), SeqType.OCC_QMARK); |
140 |
SeqType arg = new SeqType(new XSString(), SeqType.OCC_QMARK); |
| 126 |
_expected_args.add(arg); |
141 |
_expected_args.add(arg); |
| 127 |
_expected_args.add(arg); |
142 |
_expected_args.add(arg); |
|
|
143 |
_expected_args.add(new SeqType(new XSString(), SeqType.OCC_NONE)); |
| 128 |
} |
144 |
} |
| 129 |
|
145 |
|
| 130 |
return _expected_args; |
146 |
return _expected_args; |