KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > xquark > xquery > reconstruction > EvaluationVisitor


1 /*
2  * This file belongs to the XQuark distribution.
3  * Copyright (C) 2003 Universite de Versailles Saint-Quentin.
4  * Copyright (C) 2003 XQuark Group.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307.
19  * You can also get it at http://www.gnu.org/licenses/lgpl.html
20  *
21  * For more information on this software, see http://www.xquark.org.
22  */

23
24 package org.xquark.xquery.reconstruction;
25
26 import java.math.BigDecimal JavaDoc;
27 import java.sql.Timestamp JavaDoc;
28 import java.util.*;
29
30 import org.w3c.dom.Attr JavaDoc;
31 import org.w3c.dom.Node JavaDoc;
32 import org.w3c.dom.Text JavaDoc;
33 import org.xquark.schema.SchemaException;
34 import org.xquark.schema.SchemaManager;
35 import org.xquark.schema.SimpleType;
36 import org.xquark.schema.validation.ValidationContextProvider;
37 import org.xquark.xml.xdbc.XMLDBCException;
38 import org.xquark.xpath.datamodel.*;
39 import org.xquark.xquery.metadata.DynamicContext;
40 import org.xquark.xquery.parser.*;
41 import org.xquark.xquery.parser.primitivefunctions.fnfunctions.*;
42 import org.xquark.xquery.parser.primitivefunctions.xsfunctions.*;
43 import org.xquark.xquery.parser.util.Constants;
44 import org.xquark.xquery.xdbc.XDBCResultSetInterface;
45
46 /**
47  * A simple class for evaluating en attendant the real evaluator.
48  * evaluate the expression and return true or false
49  *
50  */

51 public class EvaluationVisitor extends DefaultParserVisitor {
52     // **********************************************************************
53
// * VERSIONING
54
// **********************************************************************
55
private static final String JavaDoc RCSRevision = "$Revision: 1.7 $";
56     private static final String JavaDoc RCSName = "$Name: $";
57     // **********************************************************************
58
// * CLASS VARIABLES
59
// **********************************************************************
60
private XDBCResultSetInterface resultSet = null;
61
62     private boolean verdict = false;
63
64     private ArrayList resnodes = null;
65     private Comparable JavaDoc resvalue = null;
66
67     protected static TypedDocumentImpl docimpl = null;
68     static {
69         docimpl = new TypedDocumentImpl();
70     }
71     private SchemaManager schemamanager = null;
72     private DynamicContext dc = null;
73     private ValidationContextProvider context = null;
74
75     public static Integer JavaDoc UNKNOWN_TYPE = new Integer JavaDoc(-1);
76     public static Integer JavaDoc BOOLEAN_TYPE = new Integer JavaDoc(0);
77     public static Integer JavaDoc VALUE_TYPE = new Integer JavaDoc(1);
78     public static Integer JavaDoc NODE_TYPE = new Integer JavaDoc(2);
79     public static Integer JavaDoc TUPLE_TYPE = new Integer JavaDoc(3);
80     public static Integer JavaDoc BUFFER_TYPE = new Integer JavaDoc(4);
81     private Stack returnType = new Stack();
82
83     /**
84      *
85      */

86     public EvaluationVisitor(XDBCResultSetInterface resultSet, ValidationContextProvider context) {
87         this.schemamanager = new SchemaManager();
88         this.resultSet = resultSet;
89         this.context = context;
90     }
91
92     /**
93      *
94      */

95     public EvaluationVisitor(SchemaManager schemamanager, XDBCResultSetInterface resultSet) {
96         this.schemamanager = schemamanager;
97         this.resultSet = resultSet;
98     }
99
100     public void setReturnType(Integer JavaDoc setType) {
101         if (!returnType.isEmpty())
102             this.returnType.pop();
103         returnType.push(setType);
104     }
105
106     private void clear() {
107         resnodes = null;
108         resvalue = null;
109         verdict = false;
110     }
111     private void setResnodes(ArrayList nodes) {
112         resnodes = nodes;
113         resvalue = null;
114         verdict = false;
115     }
116     private void setValue(Comparable JavaDoc comp) {
117         resnodes = null;
118         resvalue = comp;
119         verdict = false;
120     }
121     private void setVerdict(boolean bool) {
122         resnodes = null;
123         resvalue = null;
124         verdict = bool;
125     }
126     public void setSchemaManager(SchemaManager schemamanager) {
127         this.schemamanager = schemamanager;
128     }
129     public void setDynamicContext(DynamicContext dc) {
130         this.dc = dc;
131     }
132     public void reset() {
133         clear();
134         this.resultSet = null;
135         returnType.clear();
136     }
137     public void reset(XDBCResultSetInterface resultSet) {
138         clear();
139         this.resultSet = resultSet;
140         returnType.clear();
141     }
142     public boolean getVerdict() {
143         return verdict;
144     }
145     public Comparable JavaDoc getResValue() {
146         return resvalue;
147     }
148     public ArrayList getResNodes() {
149         return resnodes;
150     }
151
152     public void visit(AttributeValuePair arg) throws XQueryException {
153         if (arg.isXmlns()) {
154             setResnodes(null);
155             return;
156         }
157         if (!(arg.getExpression1() instanceof QName)) {
158             throw new XQueryException("EvaluationVisitor : name of AttributeValuePair is not a QName : " + arg.getExpression1());
159         }
160         QName attName = (QName) arg.getExpression1();
161         Object JavaDoc attValue = null;
162         if (!(arg.getExpression2() instanceof Value)) {
163             returnType.push(VALUE_TYPE);
164             arg.getExpression2().accept(this);
165             returnType.pop();
166             if (resvalue == null) {
167                 throw new XQueryException("EvaluationVisitor : value of AttributeValuePair is null : " + arg.getExpression2());
168             }
169             attValue = resvalue;
170         } else
171             attValue = ((Value) arg.getExpression2()).getObjectValue();
172         if (attValue != null) {
173             TypedAttributeImpl att = new TypedAttributeImpl(docimpl, ((QName) attName).getNameSpace(), ((QName) attName).getLocalName());
174             att.setNodeValue(attValue.toString());
175             att.setTypedValue(attValue);
176             ArrayList tmplist = new ArrayList(1);
177             tmplist.add(att);
178             setResnodes(tmplist);
179             return;
180         }
181         setResnodes(null);
182     }
183
184     public void visit(BinOpANDExpression arg) throws XQueryException {
185         XQueryExpression exp1 = arg.getExpression1();
186         EvaluationVisitor visitor = new EvaluationVisitor(this.schemamanager, resultSet);
187         visitor.setReturnType(EvaluationVisitor.BOOLEAN_TYPE);
188         exp1.accept(visitor);
189         verdict = visitor.getVerdict();
190         if (!verdict) {
191             setVerdict(false);
192             return;
193         }
194         XQueryExpression exp2 = arg.getExpression2();
195         visitor.reset(resultSet);
196         visitor.setReturnType(EvaluationVisitor.BOOLEAN_TYPE);
197         exp2.accept(visitor);
198         verdict &= visitor.getVerdict();
199         setVerdict(verdict);
200     }
201
202     public void visit(BinOpORExpression arg) throws XQueryException {
203         XQueryExpression exp1 = arg.getExpression1();
204         EvaluationVisitor visitor = new EvaluationVisitor(this.schemamanager, resultSet);
205         exp1.accept(visitor);
206         verdict = visitor.getVerdict();
207         if (verdict) {
208             setVerdict(true);
209             return;
210         }
211         XQueryExpression exp2 = arg.getExpression2();
212         visitor.reset(resultSet);
213         exp2.accept(visitor);
214         verdict = verdict || visitor.getVerdict();
215         setVerdict(verdict);
216     }
217
218     // public void visit(CastTreatExpression arg) throws XQueryException
219
// public void visit(ContextDeclaration arg) throws XQueryException
220
// public void visit(Dereference arg) throws XQueryException
221

222     public void visit(Element arg) throws XQueryException {
223         XQueryExpression startTag = arg.getStartTag();
224         if (!(startTag instanceof QName))
225             throw new XQueryException("Tag of Element expression is not a QName : " + startTag);
226         Integer JavaDoc rettype = (Integer JavaDoc) returnType.peek();
227         QName startTagQName = null;
228         TypedElement element = null;
229         ArrayList tmplist = null;
230         StringBuffer JavaDoc buf = null;
231         if (rettype == NODE_TYPE) {
232             startTagQName = (QName) startTag;
233             element = new TypedElementImpl(docimpl, startTagQName.getNameSpace(), startTagQName.getLocalName());
234             tmplist = arg.getAttributes();
235             if (tmplist != null && !tmplist.isEmpty()) {
236                 for (int i = 0; i < tmplist.size(); i++) {
237                     AttributeValuePair attValPair = (AttributeValuePair) tmplist.get(i);
238                     attValPair.accept(this);
239                     if (resnodes != null) {
240                         TypedAttribute att = (TypedAttribute) resnodes.get(0);
241                         element.setAttributeNodeNS((Attr JavaDoc) att);
242                     }
243                 }
244             }
245         } else
246             buf = new StringBuffer JavaDoc();
247         tmplist = arg.getSubExpressions();
248         if (tmplist != null && !tmplist.isEmpty()) {
249             for (int i = 0; i < tmplist.size(); i++) {
250                 XQueryExpression subExpr = (XQueryExpression) tmplist.get(i);
251                 subExpr.accept(this);
252                 if (rettype == NODE_TYPE && resnodes != null) {
253                     for (int j = 0; j < resnodes.size(); j++) {
254                         TypedNode resnode = (TypedNode) resnodes.get(j);
255                         if (docimpl != resnode.getOwnerDocument())
256                             resnode = (TypedNode) element.getOwnerDocument().importNode(resnode, true);
257                         if (resnode instanceof TypedAttributeImpl) {
258                             element.setAttributeNodeNS((Attr JavaDoc) resnode);
259                         } else if (resnode instanceof TypedElementImpl) {
260                             element.appendChild((Node JavaDoc) resnode);
261                         } else if (resnode instanceof TypedValueImpl) {
262                             element.appendChild((Node JavaDoc) resnode);
263                         } else {
264                             throw new XQueryException("Could not add child : " + resnode + " to parent.");
265                             // do nothing for now, warning?
266
}
267                     }
268                 }
269                 else if (rettype == VALUE_TYPE && resvalue != null) {
270                     buf.append(resvalue.toString());
271                 }
272             }
273         }
274         clear();
275         if (rettype == VALUE_TYPE) {
276             setValue(buf.toString());
277         } else { //if (retType == NODE_TYPE) {
278
tmplist = new ArrayList(1);
279             tmplist.add(element);
280             setResnodes(tmplist);
281         }
282     }
283
284     // public void visit (FLWRExpression arg) throws XQueryException
285
// public void visit (FunctionCall arg) throws XQueryException
286
// public void visit(FunctionDefinition arg) throws XQueryException
287
// public void visit(InstanceOfExpression arg) throws XQueryException
288
// public void visit(InternalFunctionCall arg) throws XQueryException
289
public void visit(ITEExpression arg) throws XQueryException {
290         returnType.push(BOOLEAN_TYPE);
291         arg.getIfExpression().accept(this);
292         returnType.pop();
293         if (verdict)
294             arg.getThenExpression().accept(this);
295         else
296             arg.getElseExpression().accept(this);
297     }
298     
299     public void visit(LibraryFunctionCall arg) throws XQueryException {
300         FunctionDeclaration funDecl = arg.getFunctionDefinition();
301         if (funDecl.getExpressions() != null) {
302             // TODO
303
} else {
304             Object JavaDoc[] params = new Object JavaDoc[arg.getArguments().size()];
305             for (int i=0;i<arg.getArguments().size();i++) {
306                 returnType.push(VALUE_TYPE);
307                 arg.getArgument(i).accept(this);
308                 params[i] = resvalue;
309                 returnType.pop();
310             }
311             Object JavaDoc obj = dc.invoke(arg,params);
312             setValue((Comparable JavaDoc)obj);
313         }
314     }
315     
316     // public void visit(ListOpAFTERExpression arg) throws XQueryException
317

318     public void visit(ListOpArithExpression arg) throws XQueryException {
319         XQueryExpression exp1 = arg.getExpression1();
320         XQueryExpression exp2 = arg.getExpression2();
321         int operator = arg.getOperator();
322
323         returnType.push(UNKNOWN_TYPE);
324         exp1.accept(this);
325         ArrayList trees1 = resnodes;
326         Number JavaDoc value1 = (resvalue instanceof Number JavaDoc) ? (Number JavaDoc) resvalue : null;
327         exp2.accept(this);
328         ArrayList trees2 = resnodes;
329         Number JavaDoc value2 = (resvalue instanceof Number JavaDoc) ? (Number JavaDoc) resvalue : null;
330         returnType.pop();
331
332         //TypedDocument docimpl = new TypedDocument() ;
333
//Integer retType = (Integer)returnType.pop();
334
if ((trees1 == null || trees1.isEmpty()) && (trees2 == null || trees2.isEmpty())) {
335             Number JavaDoc res = processOperation(exp1, exp2, null, null, value1, value2, operator);
336             //if (retType.equals(NODE_TYPE)) {
337
SimpleType st = getSimpleType((Comparable JavaDoc) res, schemamanager.getDoubleType());
338             TypedNode text = (TypedNode) docimpl.createTypedValue(res, st);
339             text.setTypedValue(res);
340             text.setType(st);
341             ArrayList tmplist = new ArrayList(1);
342             tmplist.add(text);
343             setResnodes(tmplist);
344             // }
345
// else if (retType.equals(VALUE_TYPE)) {
346
// setValue(new Double(res));
347
// }
348
// else
349
// clear();
350
return;
351         }
352
353         if ((trees1 == null || trees1.isEmpty()) && (trees2 != null) && (!trees2.isEmpty())) {
354             ArrayList tmplist = new ArrayList(trees2.size());
355             for (int j = 0; j < trees2.size(); j++) {
356                 TypedNode tree2 = (TypedNode) trees2.get(j);
357                 Number JavaDoc res = processOperation(exp1, exp2, null, tree2, value1, value2, operator);
358                 SimpleType st = getSimpleType((Comparable JavaDoc) res, schemamanager.getDoubleType());
359                 TypedNode text = (TypedNode) docimpl.createTypedValue(res, st);
360                 text.setTypedValue(res);
361                 text.setType(st);
362                 tmplist.add(text);
363             }
364             // if (retType.equals(NODE_TYPE)) {
365
setResnodes(tmplist);
366             // }
367
// else
368
// clear();
369
return;
370         }
371
372         if ((trees1 != null) && (!trees1.isEmpty()) && (trees2 == null) || (trees2.isEmpty())) {
373             ArrayList tmplist = new ArrayList(trees1.size());
374             for (int i = 0; i < trees1.size(); i++) {
375                 TypedNode tree1 = (TypedNode) trees1.get(i);
376                 Number JavaDoc res = processOperation(exp1, exp2, tree1, null, value1, value2, operator);
377                 SimpleType st = getSimpleType((Comparable JavaDoc) res, schemamanager.getDoubleType());
378                 TypedNode text = (TypedNode) docimpl.createTypedValue(res, st);
379                 text.setTypedValue(res);
380                 text.setType(st);
381                 tmplist.add(text);
382             }
383             // if (retType.equals(NODE_TYPE)) {
384
setResnodes(tmplist);
385             // }
386
// else
387
// clear();
388
return;
389         }
390
391         ArrayList tmplist = new ArrayList(trees1.size() * trees2.size());
392         for (int i = 0; i < trees1.size(); i++) {
393             TypedNode tree1 = (TypedNode) trees1.get(i);
394             for (int j = 0; j < trees2.size(); j++) {
395                 TypedNode tree2 = (TypedNode) trees2.get(j);
396                 Number JavaDoc res = processOperation(exp1, exp2, tree1, tree2, value1, value2, operator);
397                 SimpleType st = getSimpleType((Comparable JavaDoc) res, schemamanager.getDoubleType());
398                 TypedNode text = (TypedNode) docimpl.createTypedValue(res, st);
399                 text.setTypedValue(res);
400                 text.setType(st);
401                 tmplist.add(text);
402             }
403         }
404         // if (retType.equals(NODE_TYPE)) {
405
setResnodes(tmplist);
406         // }
407
// else
408
// clear();
409
}
410
411     // public void visit(ListOpBEFOREExpression arg) throws XQueryException
412
public void visit(ListOpCompExpression arg) throws XQueryException {
413         XQueryExpression exp1 = arg.getExpression1();
414         XQueryExpression exp2 = arg.getExpression2();
415         int operator = arg.getOperator();
416
417         returnType.push(EvaluationVisitor.NODE_TYPE);
418         resnodes = null;
419         resvalue = null;
420         exp1.accept(this);
421         //returnType.pop();
422
ArrayList trees1 = resnodes;
423         if (trees1 != null && trees1.isEmpty())
424             trees1 = null;
425         Comparable JavaDoc value1 = resvalue;
426         //returnType.push(EvaluationVisitor.NODE_TYPE);
427
resnodes = null;
428         resvalue = null;
429         exp2.accept(this);
430         returnType.pop();
431         ArrayList trees2 = resnodes;
432         if (trees2 != null && trees2.isEmpty())
433             trees2 = null;
434         Comparable JavaDoc value2 = resvalue;
435
436         if (value1 != null && value2 != null) {
437             processComparison(null, null, null, null, value1, value2, operator);
438             setVerdict(verdict);
439             return;
440         }
441
442         if (trees1 == null && trees2 == null) {
443             processComparison(exp1, exp2, null, null, value1, value2, operator);
444             return;
445         }
446
447         if (trees1 == null && trees2 != null) {
448             for (int j = 0; j < trees2.size(); j++) {
449                 TypedNode tree2 = (TypedNode) trees2.get(j);
450                 processComparison(exp1, exp2, null, tree2, value1, value2, operator);
451                 if (verdict == true) {
452                     setVerdict(true);
453                     return;
454                 }
455             }
456             setVerdict(false);
457             return;
458         }
459
460         if (trees1 != null && trees2 == null) {
461             for (int i = 0; i < trees1.size(); i++) {
462                 TypedNode tree1 = (TypedNode) trees1.get(i);
463                 processComparison(exp1, exp2, tree1, null, value1, value2, operator);
464                 if (verdict == true) {
465                     setVerdict(true);
466                     return;
467                 }
468             }
469             setVerdict(false);
470             return;
471         }
472
473         for (int i = 0; i < trees1.size(); i++) {
474             TypedNode tree1 = (TypedNode) trees1.get(i);
475             for (int j = 0; j < trees2.size(); j++) {
476                 TypedNode tree2 = (TypedNode) trees2.get(j);
477                 processComparison(exp1, exp2, tree1, tree2, value1, value2, operator);
478                 if (verdict == true) {
479                     setVerdict(true);
480                     return;
481                 }
482             }
483             setVerdict(false);
484         }
485     }
486
487     // public void visit(ListOpEXCEPTExpression arg) throws XQueryException
488
// public void visit(ListOpINTERSECTExpression arg) throws XQueryException
489

490     public void visit(ListOpUNIONExpression arg) throws XQueryException {
491         XQueryExpression exp1 = arg.getExpression1();
492         XQueryExpression exp2 = arg.getExpression2();
493
494         returnType.push(NODE_TYPE);
495         resnodes = null;
496         exp1.accept(this);
497         ArrayList trees = resnodes;
498         resnodes = null;
499         exp2.accept(this);
500         returnType.pop();
501         if (resnodes != null) {
502             if (trees == null)
503                 trees = resnodes;
504             else
505                 trees.addAll(resnodes);
506         }
507         setResnodes(trees);
508     }
509
510     public void visit(LocatedExpression arg) throws XQueryException {
511         ArrayList steps = arg.getSteps();
512         int nodeAccessor = arg.getNodeAccessor();
513         boolean hasSpecialStep = false;
514         if (nodeAccessor == Step.NONE) {
515             int lastPosition = steps.size() - 1;
516             Step lastStep = (Step) steps.get(lastPosition);
517             if (lastStep.getStepKind()%16 != 0) {
518                 arg.setNodeAccessor(lastStep.getStepKind());
519                 nodeAccessor = arg.getNodeAccessor();
520                 steps.remove(lastPosition);
521             }
522         }
523 // ArrayList steps = arg.getSteps();
524
// int position = steps.size() - 1;
525
// Step stepText = (Step) steps.get(position);
526
// XQueryExpression stepTextExpr = stepText.getExpression();
527
// boolean hasSpecialStep = false;
528
// int nodeAccessor = 0;
529
// if (stepTextExpr instanceof NodeTest) {
530
// switch (((NodeTest) stepTextExpr).getKind()) {
531
// case NodeKind.NODE :
532
// if (stepText.getAxis() == Axis.CHILD) {
533
// nodeAccessor = XDBCResultSetInterface.NODE_ACCESSOR_NODE;
534
// steps.remove(position);
535
// hasSpecialStep = true;
536
// } else if (stepText.getAxis() == Axis.SELF) {
537
// nodeAccessor = XDBCResultSetInterface.NODE_ACCESSOR_SELF_NODE;
538
// steps.remove(position);
539
// hasSpecialStep = true;
540
// }
541
// break;
542
// case NodeKind.TEXT :
543
// if (stepText.getAxis() == Axis.CHILD) {
544
// nodeAccessor = XDBCResultSetInterface.NODE_ACCESSOR_TEXT;
545
// steps.remove(position);
546
// hasSpecialStep = true;
547
// } else if (stepText.getAxis() == Axis.SELF) {
548
// nodeAccessor = XDBCResultSetInterface.NODE_ACCESSOR_SELF_TEXT;
549
// steps.remove(position);
550
// hasSpecialStep = true;
551
// }
552
// break;
553
// }
554
// }
555
clear();
556         String JavaDoc str = null;
557         try {
558             str = resultSet.fetch(arg.getStringValue(), nodeAccessor);
559         } catch (XMLDBCException xe) {
560             throw new XQueryException(xe.getMessage(), xe);
561         }
562 // if (hasSpecialStep) {
563
// steps.add(stepText);
564
// }
565
Integer JavaDoc rettype = returnType.isEmpty() ? UNKNOWN_TYPE : (Integer JavaDoc) returnType.peek();
566         if (rettype == NODE_TYPE) {
567             ArrayList nodes = null;
568             if (str != null) {
569                 nodes = new ArrayList(1);
570                 Text JavaDoc text = docimpl.createTextNode(str);
571                 nodes.add(text);
572             }
573             setResnodes(nodes);
574             return;
575         } else { // rettype == VALUE_TYPE
576
setValue(str);
577             return;
578         }
579     }
580     // public void visit(NodeType arg) throws XQueryException
581
// public void visit(Parameter arg) throws XQueryException
582
// public void visit(PrimitiveFunctionCall arg) throws XQueryException
583
public void visit(QName arg) throws XQueryException {
584         String JavaDoc str = arg.getStringValue();
585         Integer JavaDoc rettype = returnType.isEmpty() ? UNKNOWN_TYPE : (Integer JavaDoc) returnType.peek();
586         if (rettype == NODE_TYPE) {
587             ArrayList nodes = null;
588             if (str != null) {
589                 nodes = new ArrayList(1);
590                 Text JavaDoc text = docimpl.createTextNode(str);
591                 nodes.add(text);
592             }
593             setResnodes(nodes);
594             return;
595         } else { // rettype == VALUE_TYPE
596
setValue(str);
597             return;
598         }
599     }
600     // public void visit(QuantifiedExpression arg) throws XQueryException
601
// public void visit(RangeExpression arg) throws XQueryException
602
// public void visit(RootNodeFunctionCall arg) throws XQueryException
603
// public void visit(SortedExpression arg) throws XQueryException
604
// public void visit(Step arg) throws XQueryException
605
// public void visit(TypeSwitchExpression arg) throws XQueryException
606

607     private Comparable JavaDoc getMinus(Comparable JavaDoc obj) {
608         Comparable JavaDoc retObj = null;
609         if (obj instanceof Number JavaDoc) {
610             //BigDecimal, BigInteger, Byte, Double, Float, Integer, Long, Short
611
if (obj instanceof Double JavaDoc) {
612                 retObj = new Double JavaDoc(- ((Double JavaDoc) obj).doubleValue());
613             } else if (obj instanceof Float JavaDoc) {
614                 retObj = new Float JavaDoc(- ((Float JavaDoc) obj).floatValue());
615             } else if (obj instanceof BigDecimal JavaDoc) {
616                 retObj = new BigDecimal JavaDoc(((BigDecimal JavaDoc) obj).unscaledValue().negate(), ((BigDecimal JavaDoc) obj).scale());
617             } else if (obj instanceof Integer JavaDoc) {
618                 retObj = new Integer JavaDoc(- ((Integer JavaDoc) obj).intValue());
619             } else if (obj instanceof Long JavaDoc) {
620                 retObj = new Long JavaDoc(- ((Long JavaDoc) obj).longValue());
621             }
622         } else if (obj instanceof String JavaDoc) {
623             try {
624                 retObj = new Double JavaDoc(-Double.parseDouble((String JavaDoc) obj));
625             } catch (NumberFormatException JavaDoc e) {
626                 // do nothing
627
}
628         }
629         return retObj;
630     }
631
632     public void visit(UnOpMinusExpression arg) throws XQueryException {
633         returnType.push(UNKNOWN_TYPE);
634         arg.getExpression().accept(this);
635         returnType.pop();
636         Integer JavaDoc rettype = (Integer JavaDoc) returnType.peek();
637         if (resvalue != null) {
638             if (!arg.getMinus()) {
639                 if (rettype == NODE_TYPE) {
640                     ArrayList nodes = new ArrayList(1);
641                     TypedValue text = null;
642                     if (resvalue instanceof Long JavaDoc)
643                         text = docimpl.createTypedValue(resvalue, this.schemamanager.getIntegerType());
644                     else if (resvalue instanceof BigDecimal JavaDoc)
645                         text = docimpl.createTypedValue(resvalue, this.schemamanager.getDecimalType());
646                     else if (resvalue instanceof Double JavaDoc)
647                         text = docimpl.createTypedValue(resvalue, this.schemamanager.getDoubleType());
648                     else
649                         throw new XQueryException("UnOpMinusExpression could not cast resvalue");
650                     nodes.add(text);
651                     setResnodes(nodes);
652                     return;
653                 } else { //(rettype == VALUE_TYPE) {
654
setValue(resvalue);
655                     return;
656                 }
657             }
658             Comparable JavaDoc comp = getMinus(resvalue);
659             if (comp != null) {
660                 if (rettype == NODE_TYPE) {
661                     ArrayList nodes = new ArrayList(1);
662                     TypedValue text = null;
663                     if (comp instanceof Long JavaDoc)
664                         text = docimpl.createTypedValue(comp, this.schemamanager.getIntegerType());
665                     else if (resvalue instanceof BigDecimal JavaDoc)
666                         text = docimpl.createTypedValue(comp, this.schemamanager.getDecimalType());
667                     else if (comp instanceof Double JavaDoc)
668                         text = docimpl.createTypedValue(comp, this.schemamanager.getDoubleType());
669                     else
670                         throw new XQueryException("UnOpMinusExpression could not cast comp");
671                     nodes.add(text);
672                     setResnodes(nodes);
673                     return;
674                 } else { //(rettype == VALUE_TYPE) {
675
setValue(comp);
676                     return;
677                 }
678             } else
679                 throw new XQueryException("UnOpMinusExpression could not cast operator to Number");
680         } else if (resnodes != null) {
681             if (rettype == VALUE_TYPE && resnodes.size() != 1) {
682                 throw new XQueryException("UnOpMinusExpression could not get value from node list");
683             }
684             if (!arg.getMinus()) {
685                 if (rettype == NODE_TYPE) {
686                     ArrayList tmplist = new ArrayList(resnodes.size());
687                     for (int i = 0; i < resnodes.size(); i++) {
688                         TypedNode tmpnode = (TypedNode) ((TypedNode) resnodes.get(0)).getFirstChild();
689                         if (tmpnode == null)
690                             tmpnode = (TypedNode) resnodes.get(0);
691                         tmplist.add(docimpl.createTypedValue((Comparable JavaDoc) tmpnode.getTypedValue(), (SimpleType) tmpnode.getType()));
692                     }
693                     setResnodes(tmplist);
694                     return;
695                 } else { // (rettype == VALUE_TYPE) {
696
TypedNode tmpnode = (TypedNode) ((TypedNode) resnodes.get(0)).getFirstChild();
697                     if (tmpnode == null)
698                         tmpnode = (TypedNode) resnodes.get(0);
699                     setValue((Comparable JavaDoc) tmpnode.getTypedValue());
700                     return;
701                 }
702             }
703             ArrayList tmplist = new ArrayList(resnodes.size());
704             for (int i = 0; i < resnodes.size(); i++) {
705                 TypedNode tmpnode = (TypedNode) ((TypedNode) resnodes.get(0)).getFirstChild();
706                 if (tmpnode == null)
707                     tmpnode = (TypedNode) resnodes.get(0);
708                 Comparable JavaDoc comp = getMinus((Comparable JavaDoc) tmpnode.getTypedValue());
709                 if (comp != null) {
710                     TypedValue text = docimpl.createTypedValue(comp, (SimpleType) tmpnode.getType());
711                     tmplist.add(text);
712                 }
713             }
714             if (rettype == NODE_TYPE) {
715                 setResnodes(tmplist);
716                 return;
717             } else { // (rettype == VALUE_TYPE) {
718
if (tmplist.size() == 1) {
719                     setValue((Comparable JavaDoc) ((TypedValue) tmplist.get(0)).getTypedValue());
720                     return;
721                 }
722             }
723         }
724         clear();
725     }
726
727     public void visit(Value arg) throws XQueryException {
728         clear();
729         String JavaDoc str = null;
730         try {
731             str = resultSet.fetch(arg.getStringValue(), 0);
732
733         } catch (XMLDBCException xe) {
734             throw new XQueryException(xe.getMessage(), xe);
735         }
736         Integer JavaDoc rettype = returnType.isEmpty() ? UNKNOWN_TYPE : (Integer JavaDoc) returnType.peek();
737         ArrayList nodes = null;
738         if (rettype == NODE_TYPE) {
739             if (str != null) {
740                 nodes = new ArrayList(1);
741                 Text JavaDoc text = docimpl.createTextNode(str);
742                 nodes.add(text);
743             }
744             setResnodes(nodes);
745             return;
746         } else { // rettype == VALUE_TYPE
747
setValue(str);
748             return;
749         }
750     }
751     // public void visit(ValueBoolean arg) throws XQueryException {
752
public void visit(ValueDecimal arg) throws XQueryException {
753         Integer JavaDoc rettype = returnType.isEmpty() ? UNKNOWN_TYPE : (Integer JavaDoc) returnType.peek();
754         if (rettype == NODE_TYPE) {
755             ArrayList nodes = new ArrayList(1);
756             TypedValue text = docimpl.createTypedValue(arg.getDecimalValue(), this.schemamanager.getDecimalType());
757             nodes.add(text);
758             setResnodes(nodes);
759             return;
760         } else { // rettype == VALUE_TYPE
761
setValue(arg.getDecimalValue());
762             return;
763         }
764     }
765     public void visit(ValueDouble arg) throws XQueryException {
766         Integer JavaDoc rettype = returnType.isEmpty() ? UNKNOWN_TYPE : (Integer JavaDoc) returnType.peek();
767         if (rettype == NODE_TYPE) {
768             ArrayList nodes = new ArrayList(1);
769             TypedValue text = docimpl.createTypedValue(arg.getDoubleValue(), this.schemamanager.getDoubleType());
770             nodes.add(text);
771             setResnodes(nodes);
772             return;
773         } else { // rettype == VALUE_TYPE
774
setValue(arg.getDoubleValue());
775             return;
776         }
777     }
778     public void visit(ValueFloat arg) throws XQueryException {
779         Integer JavaDoc rettype = returnType.isEmpty() ? UNKNOWN_TYPE : (Integer JavaDoc) returnType.peek();
780         if (rettype == NODE_TYPE) {
781             ArrayList nodes = new ArrayList(1);
782             TypedValue text = docimpl.createTypedValue(arg.getFloatValue(), this.schemamanager.getFloatType());
783             nodes.add(text);
784             setResnodes(nodes);
785             return;
786         } else { // rettype == VALUE_TYPE
787
setValue(arg.getFloatValue());
788             return;
789         }
790     }
791     public void visit(ValueInteger arg) throws XQueryException {
792         Integer JavaDoc rettype = returnType.isEmpty() ? UNKNOWN_TYPE : (Integer JavaDoc) returnType.peek();
793         if (rettype == NODE_TYPE) {
794             ArrayList nodes = new ArrayList(1);
795             TypedValue text = docimpl.createTypedValue(new Long JavaDoc(arg.getIntValue().longValue()), this.schemamanager.getIntegerType());
796             nodes.add(text);
797             setResnodes(nodes);
798             return;
799         } else { // rettype == VALUE_TYPE
800
setValue(new Long JavaDoc(arg.getIntValue().longValue()));
801             return;
802         }
803     }
804     public void visit(ValueString arg) throws XQueryException {
805         Integer JavaDoc rettype = returnType.isEmpty() ? UNKNOWN_TYPE : (Integer JavaDoc) returnType.peek();
806         if (rettype == NODE_TYPE) {
807             ArrayList nodes = new ArrayList(1);
808             TypedValue text = docimpl.createTypedValue(arg.getStringValue(), this.schemamanager.getStringType());
809             nodes.add(text);
810             setResnodes(nodes);
811             return;
812         } else { // rettype == VALUE_TYPE
813
setValue(arg.getStringValue());
814             return;
815         }
816     }
817     public void visit(ValueText arg) throws XQueryException {
818         Integer JavaDoc rettype = returnType.isEmpty() ? UNKNOWN_TYPE : (Integer JavaDoc) returnType.peek();
819         if (rettype == NODE_TYPE) {
820             ArrayList nodes = new ArrayList(1);
821             TypedValue text = docimpl.createTypedValue(arg.getTextValue(), this.schemamanager.getStringType());
822             nodes.add(text);
823             setResnodes(nodes);
824             return;
825         } else { // rettype == VALUE_TYPE
826
setValue(arg.getTextValue());
827             return;
828         }
829     }
830     public void visit(Variable arg) throws XQueryException {
831         clear();
832         String JavaDoc str = null;
833         try {
834             str = resultSet.fetch(arg.getStringValue(), 0);
835
836         } catch (XMLDBCException xe) {
837             throw new XQueryException(xe.getMessage(), xe);
838         }
839         Integer JavaDoc rettype = returnType.isEmpty() ? UNKNOWN_TYPE : (Integer JavaDoc) returnType.peek();
840         if (rettype == NODE_TYPE) {
841             ArrayList nodes = null;
842             if (str != null) {
843                 nodes = new ArrayList(1);
844                 Text JavaDoc text = docimpl.createTextNode(str);
845                 nodes.add(text);
846             }
847             setResnodes(nodes);
848             return;
849         } else { // rettype == VALUE_TYPE
850
setValue(str);
851             return;
852         }
853     }
854     // public void visit (XQueryBinaryOperatorExpression arg) throws XQueryException
855
// public void visit(XQueryBooleanOperatorExpression arg) throws XQueryException
856
public void visit(XQueryExpression arg) throws XQueryException {
857         throw new XQueryException("Class " + arg.getClass().getName() + " not supported in EvaluationVisitor");
858     }
859     public void visit(XQueryExpressionSequence arg) throws XQueryException {
860         if (arg.getSubExpressions().size() == 1)
861              ((XQueryExpression) arg.getSubExpressions().get(0)).accept(this);
862         else {
863             ArrayList expressions = arg.getSubExpressions();
864             Integer JavaDoc rettype = returnType.isEmpty() ? UNKNOWN_TYPE : (Integer JavaDoc) returnType.peek();
865             if (rettype == VALUE_TYPE) {
866                 StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
867                 returnType.push(VALUE_TYPE);
868                 for (int i = 0; i < expressions.size(); i++) {
869                     XQueryExpression expri = (XQueryExpression) expressions.get(i);
870                     expri.accept(this);
871                     if (resvalue != null) {
872                         if (buf.length() != 0)
873                             buf.append(' ');
874                         buf.append(resvalue.toString());
875                     }
876                 }
877                 setValue(buf.toString());
878                 returnType.pop();
879             } else {
880                 ArrayList tmpnodes = new ArrayList();
881                 returnType.push(NODE_TYPE);
882                 for (int i = 0; i < expressions.size(); i++) {
883                     XQueryExpression expri = (XQueryExpression) expressions.get(i);
884                     expri.accept(this);
885                     if (resnodes != null)
886                         tmpnodes.addAll(resnodes);
887                 }
888                 setResnodes(tmpnodes);
889                 returnType.pop();
890             }
891             //throw new XQueryException("Class " + arg.getClass().getName() + " with more than one expression not supported in EvaluationVisitor");
892
}
893     }
894     // public void visit(XQueryListBinaryOperatorExpression arg) throws XQueryException
895
// public void visit(XQueryListUnaryOperatorExpression arg) throws XQueryException
896
// public void visit (XQueryUnaryOperatorExpression arg) throws XQueryException
897

898     //-----------------------------------------------------------
899
// BOOLEAN FUNCTIONS
900
//-----------------------------------------------------------
901
public void visit(FunctionFALSE arg) throws XQueryException {
902         setVerdict(false);
903     }
904
905     public void visit(FunctionTRUE arg) throws XQueryException {
906         setVerdict(true);
907     }
908
909     //-----------------------------------------------------------
910
// AGGREGATE FUNCTIONS
911
//-----------------------------------------------------------
912

913     //public void visit(FunctionAVG arg) throws XQueryException;
914
//public void visit(FunctionSUM arg) throws XQueryException;
915
//public void visit(FunctionMAX arg) throws XQueryException;
916
//public void visit(FunctionMIN arg) throws XQueryException;
917
//public void visit(FunctionCOUNT arg) throws XQueryException;
918

919     //-----------------------------------------------------------
920
// DATE/TIME FUNCTIONS
921
//-----------------------------------------------------------
922
// private int[] parseDate(String date) {
923
// if (date == null)
924
// return null;
925
// int[] retval = new int[3];
926
// retval[0] = Integer.parseInt(date.substring(0, 4));
927
// retval[1] = Integer.parseInt(date.substring(5, 7));
928
// retval[2] = Integer.parseInt(date.substring(8, 10));
929
// return retval;
930
// }
931
Calendar cal = Calendar.getInstance();
932
933     public void visit(FunctionCURRENT_DATETIME arg) throws XQueryException {
934         resvalue = Calendar.getInstance().getTime();
935         Integer JavaDoc rettype = (Integer JavaDoc) returnType.peek();
936         if (rettype == NODE_TYPE) {
937             ArrayList nodes = new ArrayList(1);
938             nodes.add(docimpl.createTypedValue(resvalue, this.schemamanager.getDateTimeType()));
939             setResnodes(nodes);
940             return;
941         } else { //if (rettype == VALUE_TYPE) {
942
setValue(resvalue);
943             return;
944         }
945         // clear();
946
}
947
948     public void visit(FunctionDATE arg) throws XQueryException {
949         returnType.push(VALUE_TYPE);
950         arg.getArgument(0).accept(this);
951         returnType.pop();
952         if (resvalue instanceof Date) { // do nothing
953
cal.setTime((Date) resvalue);
954             cal.set(Calendar.HOUR, 0);
955             cal.set(Calendar.MINUTE, 0);
956             cal.set(Calendar.SECOND, 0);
957             resvalue = cal.getTime();
958         } else if (resvalue instanceof String JavaDoc) {
959             try {
960                 resvalue = (Comparable JavaDoc) this.schemamanager.getDateType().convert((String JavaDoc) resvalue, true, null);
961             } catch (SchemaException se) {
962                 throw new XQueryException("Argument of function date is not a valid date");
963             }
964         } else
965             throw new XQueryException("Argument of function date cannot be converted");
966         Integer JavaDoc rettype = (Integer JavaDoc) returnType.peek();
967         if (rettype == NODE_TYPE) {
968             ArrayList nodes = new ArrayList(1);
969             nodes.add(docimpl.createTypedValue(resvalue, this.schemamanager.getDateType()));
970             setResnodes(nodes);
971             return;
972         } else { //if (rettype == VALUE_TYPE) {
973
setValue(resvalue);
974             return;
975         }
976         //clear();
977
}
978
979     public void visit(FunctionDATETIME arg) throws XQueryException {
980         returnType.push(VALUE_TYPE);
981         arg.getArgument(0).accept(this);
982         returnType.pop();
983         if (resvalue instanceof Date) { // do nothing
984
} else if (resvalue instanceof String JavaDoc) {
985             try {
986                 resvalue = (Comparable JavaDoc) this.schemamanager.getDateTimeType().convert((String JavaDoc) resvalue, true, null);
987             } catch (SchemaException se) {
988                 throw new XQueryException("Argument of function datetime is not a valid date");
989             }
990         } else
991             throw new XQueryException("Argument of function datetime cannot be converted");
992         Integer JavaDoc rettype = (Integer JavaDoc) returnType.peek();
993         if (rettype == NODE_TYPE) {
994             ArrayList nodes = new ArrayList(1);
995             nodes.add(docimpl.createTypedValue(resvalue, this.schemamanager.getDateTimeType()));
996             setResnodes(nodes);
997             return;
998         } else { //if (rettype == VALUE_TYPE) {
999
setValue(resvalue);
1000            return;
1001        }
1002        //clear();
1003
}
1004
1005    public void visit(FunctionTIME arg) throws XQueryException {
1006        returnType.push(VALUE_TYPE);
1007        arg.getArgument(0).accept(this);
1008        returnType.pop();
1009        if (resvalue instanceof Date) { // do nothing
1010
} else if (resvalue instanceof String JavaDoc) {
1011            try {
1012                resvalue = (Comparable JavaDoc) this.schemamanager.getTimeType().convert((String JavaDoc) resvalue, true, null);
1013            } catch (SchemaException se) {
1014                throw new XQueryException("Argument of function time is not a valid date");
1015            }
1016        } else
1017            throw new XQueryException("Argument of function time cannot be converted");
1018        /*
1019        StringBuffer buf = new StringBuffer();
1020        buf.append(cal.get(Calendar.HOUR));
1021        buf.append(":");
1022        buf.append(cal.get(Calendar.MINUTE));
1023        buf.append(":");
1024        buf.append(cal.get(Calendar.SECOND));
1025        */

1026        cal.setTime((Date) resvalue);
1027        cal.set(Calendar.YEAR, 0);
1028        cal.set(Calendar.MONTH, 0);
1029        cal.set(Calendar.DAY_OF_MONTH, 0);
1030        resvalue = cal.getTime();
1031        Integer JavaDoc rettype = (Integer JavaDoc) returnType.peek();
1032        if (rettype == NODE_TYPE) {
1033            ArrayList nodes = new ArrayList(1);
1034            nodes.add(docimpl.createTypedValue(resvalue, this.schemamanager.getTimeType()));
1035            setResnodes(nodes);
1036            return;
1037        } else { //if (rettype == VALUE_TYPE) {
1038
setValue(resvalue);
1039            return;
1040        }
1041        //clear();
1042
}
1043
1044    public void visit(FunctionGET_YEAR_FROM_DATE arg) throws XQueryException {
1045        returnType.push(VALUE_TYPE);
1046        arg.getArgument(0).accept(this);
1047        returnType.pop();
1048        if (resvalue == null) {
1049            clear();
1050            return;
1051        }
1052        if (resvalue instanceof Date)
1053            throw new XQueryException("Argument of function get-year-from-date is not a date");
1054        cal.setTime((Date) resvalue);
1055        resvalue = new Long JavaDoc(cal.get(Calendar.YEAR));
1056        Integer JavaDoc rettype = (Integer JavaDoc) returnType.peek();
1057        if (rettype == NODE_TYPE) {
1058            ArrayList nodes = new ArrayList(1);
1059            nodes.add(docimpl.createTypedValue(resvalue, this.getSimpleType(resvalue, schemamanager.getIntegerType())));
1060            setResnodes(nodes);
1061            return;
1062        } else { //if (rettype == VALUE_TYPE) {
1063
setValue(resvalue);
1064            return;
1065        }
1066        //clear();
1067
}
1068
1069    public void visit(FunctionGET_MONTH_FROM_DATE arg) throws XQueryException {
1070        returnType.push(VALUE_TYPE);
1071        arg.getArgument(0).accept(this);
1072        returnType.pop();
1073        if (resvalue == null) {
1074            clear();
1075            return;
1076        }
1077        if (resvalue instanceof Date)
1078            throw new XQueryException("Argument of function get-month-from-date is not a date");
1079        cal.setTime((Date) resvalue);
1080        resvalue = new Long JavaDoc(cal.get(Calendar.MONTH));
1081        Integer JavaDoc rettype = (Integer JavaDoc) returnType.peek();
1082        if (rettype == NODE_TYPE) {
1083            ArrayList nodes = new ArrayList(1);
1084            nodes.add(docimpl.createTypedValue(resvalue, this.getSimpleType(resvalue, schemamanager.getIntegerType())));
1085            setResnodes(nodes);
1086            return;
1087        } else { //if (rettype == VALUE_TYPE) {
1088
setValue(resvalue);
1089            return;
1090        }
1091        //clear();
1092
}
1093
1094    //-----------------------------------------------------------
1095
// STRING FUNCTIONS
1096
//-----------------------------------------------------------
1097

1098    private Comparable JavaDoc c0 = null;
1099    private Comparable JavaDoc c1 = null;
1100
1101    private void getComparables(XQueryExpression arg0, XQueryExpression arg1) throws XQueryException {
1102        resnodes = null;
1103        c0 = null;
1104        c1 = null;
1105        if (arg0 instanceof Value)
1106            c0 = (((Value) arg0).getValue());
1107        if (arg1 instanceof Value)
1108            c1 = (((Value) arg1).getValue());
1109        if (c0 == null) {
1110            returnType.push(VALUE_TYPE);
1111            arg0.accept(this);
1112            returnType.pop();
1113            c0 = this.resvalue;
1114            if (c0 == null && resnodes != null && resnodes.size() == 1) {
1115                TypedNode node = (TypedNode) resnodes.get(0);
1116                if (node instanceof TypedValueImpl) {
1117                    c0 = (Comparable JavaDoc) node.getTypedValue();
1118                } else if (node instanceof TypedElementImpl) {
1119                    StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
1120                    getStringValue(node, sb);
1121                    c0 = sb.toString();
1122                }
1123            }
1124        }
1125        if (c1 == null) {
1126            returnType.push(VALUE_TYPE);
1127            arg1.accept(this);
1128            returnType.pop();
1129            c1 = this.resvalue;
1130            if (c1 == null && resnodes != null && resnodes.size() == 1) {
1131                TypedNode node = (TypedNode) resnodes.get(0);
1132                if (node instanceof TypedValueImpl) {
1133                    c1 = (Comparable JavaDoc) node.getTypedValue();
1134                } else if (node instanceof TypedElementImpl) {
1135                    StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
1136                    getStringValue(node, sb);
1137                    c1 = sb.toString();
1138                }
1139            }
1140        }
1141
1142    }
1143
1144    public void visit(FunctionLOWER_CASE arg) throws XQueryException {
1145        returnType.push(UNKNOWN_TYPE);
1146        arg.getArgument(0).accept(this);
1147        returnType.pop();
1148        if (resvalue != null) { // do nothing
1149
} else if (resnodes != null && resnodes.size() == 1) {
1150            TypedNode tmpnode = (TypedNode) ((TypedNode) resnodes.get(0)).getFirstChild();
1151            if (tmpnode == null)
1152                tmpnode = (TypedNode) resnodes.get(0);
1153            resvalue = (Comparable JavaDoc) tmpnode.getTypedValue();
1154        }
1155        if (resvalue instanceof String JavaDoc) {
1156            resvalue = ((String JavaDoc) resvalue).toLowerCase();
1157        } else {
1158            throw new XQueryException("Argument of function lower-case is not a string");
1159        }
1160        Integer JavaDoc rettype = (Integer JavaDoc) returnType.peek();
1161        if (rettype == VALUE_TYPE) {
1162            setValue(resvalue);
1163            return;
1164        } else if (rettype == NODE_TYPE) {
1165            ArrayList nodes = new ArrayList(1);
1166            nodes.add(docimpl.createTypedValue(resvalue, this.getSimpleType(resvalue, schemamanager.getStringType())));
1167            setResnodes(nodes);
1168            return;
1169        }
1170    }
1171
1172    public void visit(FunctionUPPER_CASE arg) throws XQueryException {
1173        returnType.push(UNKNOWN_TYPE);
1174        arg.getArgument(0).accept(this);
1175        returnType.pop();
1176        if (resvalue != null) { // do nothing
1177
} else if (resnodes != null && resnodes.size() == 1) {
1178            TypedNode tmpnode = (TypedNode) ((TypedNode) resnodes.get(0)).getFirstChild();
1179            if (tmpnode == null)
1180                tmpnode = (TypedNode) resnodes.get(0);
1181            resvalue = (Comparable JavaDoc) tmpnode.getTypedValue();
1182        }
1183        if (resvalue instanceof String JavaDoc) {
1184            resvalue = ((String JavaDoc) resvalue).toUpperCase();
1185        } else {
1186            throw new XQueryException("Argument of function upper-case is not a string");
1187        }
1188        Integer JavaDoc rettype = (Integer JavaDoc) returnType.peek();
1189        if (rettype == VALUE_TYPE) {
1190            setValue(resvalue);
1191            return;
1192        } else if (rettype == NODE_TYPE) {
1193            ArrayList nodes = new ArrayList(1);
1194            nodes.add(docimpl.createTypedValue(resvalue, this.getSimpleType(resvalue, schemamanager.getStringType())));
1195            setResnodes(nodes);
1196            return;
1197        }
1198    }
1199
1200    public void visit(FunctionCONCAT arg) throws XQueryException {
1201        StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
1202        for (int i = 0; i < arg.getArguments().size(); i++) {
1203            returnType.push(UNKNOWN_TYPE);
1204            arg.getArgument(i).accept(this);
1205            returnType.pop();
1206            if (resvalue != null) { // do nothing
1207
if (resvalue instanceof String JavaDoc)
1208                    buf.append(resvalue);
1209                else
1210                    buf.append(resvalue.toString());
1211            } else if (resnodes == null || resnodes.isEmpty()) { // do nothing
1212
} else if (resnodes != null && resnodes.size() == 1) {
1213                StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
1214                getStringValue((TypedNode) resnodes.get(0), sb);
1215                buf.append(sb.toString());
1216            } else if (resnodes != null && resnodes.size() > 1) {
1217                throw new XQueryException("Evaluation : incorrect argument for function concat");
1218            }
1219        }
1220        Integer JavaDoc rettype = (Integer JavaDoc) returnType.peek();
1221        if (rettype == NODE_TYPE) {
1222            ArrayList nodes = new ArrayList(1);
1223            nodes.add(docimpl.createTypedValue(buf.toString(), this.schemamanager.getStringType()));
1224            setResnodes(nodes);
1225            return;
1226        } else { // if (rettype == VALUE_TYPE) {
1227
setValue(buf.toString());
1228            return;
1229        }
1230        // clear();
1231
}
1232
1233    public void visit(FunctionCONTAINS arg) throws XQueryException {
1234        getComparables(arg.getArgument(0), arg.getArgument(1));
1235        if (c0 != null && c1 != null) {
1236            setVerdict(((String JavaDoc) c0).indexOf((String JavaDoc) c1) != -1);
1237            return;
1238        }
1239        clear();
1240    }
1241
1242    public void visit(FunctionENDS_WITH arg) throws XQueryException {
1243        getComparables(arg.getArgument(0), arg.getArgument(1));
1244        if (c0 != null && c1 != null) {
1245            setVerdict(((String JavaDoc) c0).endsWith((String JavaDoc) c1));
1246            return;
1247        }
1248        clear();
1249    }
1250
1251    public void visit(FunctionSTARTS_WITH arg) throws XQueryException {
1252        getComparables(arg.getArgument(0), arg.getArgument(1));
1253        if (c0 != null && c1 != null) {
1254            setVerdict(((String JavaDoc) c0).startsWith((String JavaDoc) c1));
1255            return;
1256        }
1257        clear();
1258    }
1259
1260    public void visit(FunctionLOCAL_NAME arg) throws XQueryException {
1261        returnType.push(NODE_TYPE);
1262        arg.getArgument(0).accept(this);
1263        returnType.pop();
1264        Integer JavaDoc rettype = (Integer JavaDoc) returnType.peek();
1265        //if (rettype == VALUE_TYPE) {
1266
if (this.resnodes != null && resnodes.size() == 1) {
1267            this.setValue(((TypedNode) resnodes.get(0)).getLocalName());
1268            return;
1269        }
1270        //}
1271
clear();
1272    }
1273
1274    public void visit(FunctionNAMESPACE_URI arg) throws XQueryException {
1275        returnType.push(NODE_TYPE);
1276        arg.getArgument(0).accept(this);
1277        returnType.pop();
1278        Integer JavaDoc rettype = (Integer JavaDoc) returnType.peek();
1279        //if (rettype == VALUE_TYPE) {
1280
if (this.resnodes != null && resnodes.size() == 1) {
1281            this.setValue(((TypedNode) resnodes.get(0)).getNamespaceURI());
1282            return;
1283        }
1284        //}
1285
clear();
1286    }
1287
1288    /*
1289    2.3 fn:string
1290    fn:string() as xs:string
1291    fn:string($srcval as item?) as xs:string
1292    Returns the value of $srcval represented as a xs:string. If no argument is supplied, $srcval defaults to the context item (.).
1293    
1294    If $srcval is the empty sequence, the zero-length string is returned.
1295    
1296    If $srcval is a node, the function returns the string-value of the node, as obtained using the string-value accessor defined in the [XQuery 1.0 and XPath 2.0 Data Model].
1297    
1298    If $srcval is an atomic value, then the function returns the same string as is returned by the expression cast as xs:string ($srcval), except in the cases listed below:
1299    
1300    If the type of $srcval is xs:anyURI, the URI is converted to a string without any escaping of special characters.
1301    
1302    Note:
1303    
1304    The reason for the special rule for xs:anyURI is that, although XML Schema strongly discourages the use of spaces within URI values,
1305    the escaping of spaces can cause problems with legacy applications (for example, this applies to spaces within fragment identifiers
1306    in many HTML browsers), and should therefore be under user control.
1307    
1308    Note:
1309    
1310    The string representation of xs:double values is not backwards-compatible with the representation of number values in [XPath 1.0].
1311    Ordinary xs:double values are now represented using scientific notation; the representations of positive and negative infinity are
1312    now 'INF' and '-INF' rather than 'Infinity' and '-Infinity'. (It should be observed that '+INF' is not supported as a lexical form
1313    of infinity in [XML Schema Part 2: Datatypes] and is thus not supported by this specification; if that lexical form is added in a
1314    future version of [XML Schema Part 2: Datatypes], then it will be supported by a future version of this specification that aligns
1315    with that future version of [XML Schema Part 2: Datatypes].)
1316    However, most expressions that would have produced a number in [XPath 1.0] will produce a decimal (or integer) in [XPath 2.0],
1317    so unless there is a loss of precision caused by numeric approximation, the result of the expression will in most simple cases be
1318    the same after conversion to a string.
1319    */

1320    public void visit(FunctionSTRING arg) throws XQueryException {
1321        returnType.push(UNKNOWN_TYPE);
1322        arg.getArgument(0).accept(this);
1323        returnType.pop();
1324        if (resvalue != null) { // do nothing
1325
if (!(resvalue instanceof String JavaDoc))
1326                resvalue = resvalue.toString();
1327        } else if (resnodes == null || resnodes.isEmpty()) {
1328            resvalue = new String JavaDoc("");
1329        } else if (resnodes != null && resnodes.size() == 1) {
1330            StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
1331            getStringValue((TypedNode) resnodes.get(0), sb);
1332            resvalue = sb.toString();
1333        } else if (resnodes != null && resnodes.size() > 1) {
1334            throw new XQueryException("Evaluation : incorrect argument for function string");
1335        }
1336        Integer JavaDoc rettype = (Integer JavaDoc) returnType.peek();
1337        if (rettype == NODE_TYPE) {
1338            ArrayList nodes = new ArrayList(1);
1339            TypedValue text = docimpl.createTypedValue(resvalue, this.schemamanager.getStringType());
1340            nodes.add(text);
1341            setResnodes(nodes);
1342            return;
1343        } else { //if (rettype == VALUE_TYPE) {
1344
setValue(resvalue);
1345            return;
1346        }
1347        //clear();
1348
}
1349
1350    /*
1351    7.4.7 fn:string-length
1352    fn:string-length() as xs:integer?
1353    fn:string-length($srcval as xs:string?) as xs:integer?
1354    Returns an xs:integer equal to the length in characters of the value of $srcval. If the value of $srcval is the empty sequence,
1355    the empty sequence is returned. If no argument is supplied, $srcval defaults to the string value (calculated using fn:string()) of the context item (.).
1356    
1357    Note:
1358    
1359    The value returned is the number of XML characters in the string (or equivalently, the number of Unicode code points).
1360    Some implementations may represent a code point above xFFFF using two 16-bit values known as a surrogate pair.
1361    A surrogate pair counts as one character, not two.
1362    */

1363    public void visit(FunctionSTRING_LENGTH arg) throws XQueryException {
1364        returnType.push(UNKNOWN_TYPE);
1365        arg.getArgument(0).accept(this);
1366        returnType.pop();
1367        if (resvalue != null) { // do nothing
1368
if (resvalue instanceof String JavaDoc)
1369                resvalue = new Long JavaDoc(((String JavaDoc) resvalue).length());
1370            else
1371                resvalue = new Long JavaDoc(resvalue.toString().length());
1372        } else if (resnodes == null || resnodes.isEmpty()) {
1373            resvalue = new Long JavaDoc(0);
1374        } else if (resnodes != null && resnodes.size() == 1) {
1375            StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
1376            getStringValue((TypedNode) resnodes.get(0), sb);
1377            resvalue = new Long JavaDoc(sb.length());
1378        } else if (resnodes != null && resnodes.size() > 1) {
1379            throw new XQueryException("Evaluation : incorrect argument for function string-length");
1380        }
1381        Integer JavaDoc rettype = (Integer JavaDoc) returnType.peek();
1382        if (rettype == NODE_TYPE) {
1383            ArrayList nodes = new ArrayList(1);
1384            TypedValue text = docimpl.createTypedValue(resvalue, this.schemamanager.getIntegerType());
1385            nodes.add(text);
1386            setResnodes(nodes);
1387            return;
1388        } else { //if (rettype == VALUE_TYPE) {
1389
setValue(resvalue);
1390            return;
1391        }
1392        //clear();
1393
}
1394
1395    /*
1396    7.4.6 fn:substring
1397    fn:substring( $sourceString as xs:string?,
1398    $startingLoc as xs:double) as xs:string?
1399    
1400    fn:substring( $sourceString as xs:string?,
1401    $startingLoc as xs:double,
1402    $length as xs:double) as xs:string?
1403    
1404    If the value of $sourceString is the empty sequence, the empty sequence is returned.
1405    
1406    Otherwise, returns the portion of the value of $sourceString beginning at the position indicated by the value of $startingLoc and continuing
1407    for the number of characters indicated by the value of $length. More specifically, returns the characters in $sourceString whose position $p obeys:
1408    
1409    fn:round($startingLoc) <= $p < fn:round($startingLoc) + fn:round($length)
1410    
1411    In the above computation, the rules for op:numeric-less-than() and op:numeric-greater-than() apply.
1412    
1413    If $startingLoc is zero or negative, the substring includes characters from the beginning of the $sourceString.
1414    
1415    If $length is not specified, the substring includes characters to the end of $sourceString.
1416    
1417    If $length is greater than the number of characters in the value of $sourceString following $startingLoc, the substring includes characters to the end of $sourceString.
1418    
1419    The first character of a string is located at position 1, not position 0.
1420    
1421    Note:
1422    
1423    The position and length given in the second and (optional) third argument relate to the number of XML characters in the string
1424    (or equivalently, the number of Unicode code points). Some implementations may represent a code point above xFFFF using two 16-bit
1425    values known as a surrogate pair. A surrogate pair counts as one character, not two.
1426    */

1427    public void visit(FunctionSUBSTRING arg) throws XQueryException {
1428        boolean hasLength = (arg.getArguments().size() == 3) ? true : false;
1429        String JavaDoc sourceString = null;
1430        returnType.push(UNKNOWN_TYPE);
1431        arg.getArgument(0).accept(this);
1432        if (resvalue != null) {
1433            if (resvalue instanceof String JavaDoc)
1434                sourceString = (String JavaDoc) resvalue;
1435            else
1436                sourceString = resvalue.toString();
1437        } else if (resnodes != null && resnodes.size() == 1) {
1438            StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
1439            getStringValue((TypedNode) resnodes.get(0), sb);
1440            sourceString = sb.toString();
1441        } else if (resnodes != null && resnodes.size() > 1) {
1442            throw new XQueryException("Evaluation : incorrect first argument for function substring");
1443        }
1444        if (sourceString == null) {
1445            clear();
1446            return;
1447        }
1448        double startingLoc = 0;
1449        arg.getArgument(1).accept(this);
1450        if (resvalue != null) { // do nothing
1451
} else if (resnodes != null && resnodes.size() == 1) {
1452            TypedNode tmpnode = (TypedNode) ((TypedNode) resnodes.get(0)).getFirstChild();
1453            if (tmpnode == null)
1454                tmpnode = (TypedNode) resnodes.get(0);
1455            resvalue = (Comparable JavaDoc) tmpnode.getTypedValue();
1456        } else
1457            throw new XQueryException("Evaluation : incorrect second argument for function substring");
1458        if (resvalue instanceof Number JavaDoc) {
1459            startingLoc = ((Number JavaDoc) resvalue).doubleValue();
1460        } else if (resvalue instanceof String JavaDoc) {
1461            try {
1462                startingLoc = Double.parseDouble((String JavaDoc) resvalue);
1463            } catch (NumberFormatException JavaDoc e) {
1464                // do nothing
1465
}
1466        } else
1467            throw new XQueryException("Evaluation : incorrect second argument for function substring");
1468        if (startingLoc < 1)
1469            startingLoc = 1;
1470        double length = sourceString.length();
1471        if (hasLength) {
1472            arg.getArgument(2).accept(this);
1473            if (resvalue != null) { // do nothing
1474
} else if (resnodes != null && resnodes.size() == 1) {
1475                TypedNode tmpnode = (TypedNode) ((TypedNode) resnodes.get(0)).getFirstChild();
1476                if (tmpnode == null)
1477                    tmpnode = (TypedNode) resnodes.get(0);
1478                resvalue = (Comparable JavaDoc) tmpnode.getTypedValue();
1479            } else
1480                throw new XQueryException("Evaluation : incorrect third argument for function substring");
1481            if (resvalue instanceof Number JavaDoc) {
1482                length = ((Number JavaDoc) resvalue).doubleValue();
1483            } else if (resvalue instanceof String JavaDoc) {
1484                try {
1485                    length = Double.parseDouble((String JavaDoc) resvalue);
1486                } catch (NumberFormatException JavaDoc e) {
1487                    // do nothing
1488
}
1489            } else
1490                throw new XQueryException("Evaluation : incorrect third argument for function substring");
1491            if (startingLoc + length > sourceString.length())
1492                hasLength = false;
1493        }
1494        returnType.pop();
1495        if (hasLength)
1496            resvalue = sourceString.substring((int) Math.round(startingLoc) - 1, (int) (Math.round(startingLoc) + Math.round(length)) - 1);
1497        else
1498            resvalue = sourceString.substring((int) Math.round(startingLoc) - 1);
1499        Integer JavaDoc rettype = (Integer JavaDoc) returnType.peek();
1500        if (rettype == NODE_TYPE) {
1501            ArrayList nodes = new ArrayList(1);
1502            TypedValue text = docimpl.createTypedValue(resvalue, this.schemamanager.getStringType());
1503            nodes.add(text);
1504            setResnodes(nodes);
1505            return;
1506        } else { //if (rettype == VALUE_TYPE) {
1507
setValue(resvalue);
1508            return;
1509        }
1510        //clear();
1511
}
1512
1513    //-----------------------------------------------------------
1514
// MATHEMATICAL FUNCTIONS
1515
//-----------------------------------------------------------
1516
public void visit(FunctionABS arg) throws XQueryException {
1517        returnType.push(UNKNOWN_TYPE);
1518        arg.getArgument(0).accept(this);
1519        returnType.pop();
1520        if (resvalue != null) { // do nothing
1521
} else if (resnodes != null && resnodes.size() == 1) {
1522            TypedNode tmpnode = (TypedNode) ((TypedNode) resnodes.get(0)).getFirstChild();
1523            if (tmpnode == null)
1524                tmpnode = (TypedNode) resnodes.get(0);
1525            resvalue = (Comparable JavaDoc) tmpnode.getTypedValue();
1526            if (!(resvalue instanceof Number JavaDoc))
1527                throw new XQueryException("Could not apply function abs");
1528        } else
1529            throw new XQueryException("Could not apply function abs");
1530
1531        if (resvalue instanceof Long JavaDoc)
1532            resvalue = new Long JavaDoc(Math.abs(((Long JavaDoc) resvalue).longValue()));
1533        else if (resvalue instanceof BigDecimal JavaDoc)
1534            resvalue = ((BigDecimal JavaDoc) resvalue).abs();
1535        else if (resvalue instanceof Float JavaDoc)
1536            resvalue = new Float JavaDoc(Math.abs(((Float JavaDoc) resvalue).floatValue()));
1537        else if (resvalue instanceof Double JavaDoc)
1538            resvalue = new Double JavaDoc(Math.abs(((Double JavaDoc) resvalue).doubleValue()));
1539
1540        Integer JavaDoc rettype = (Integer JavaDoc) returnType.peek();
1541        if (rettype == VALUE_TYPE) {
1542            setValue(resvalue);
1543            return;
1544        } else { // (rettype == NODE_TYPE) {
1545
ArrayList nodes = new ArrayList(1);
1546            TypedValue text = docimpl.createTypedValue(resvalue, this.getSimpleType(resvalue, schemamanager.getDoubleType()));
1547            nodes.add(text);
1548            setResnodes(nodes);
1549            return;
1550        }
1551        // clear();
1552
}
1553    public void visit(FunctionCEILING arg) throws XQueryException {
1554        returnType.push(UNKNOWN_TYPE);
1555        arg.getArgument(0).accept(this);
1556        returnType.pop();
1557        if (resvalue != null) { // do nothing
1558
} else if (resnodes != null && resnodes.size() == 1) {
1559            TypedNode tmpnode = (TypedNode) ((TypedNode) resnodes.get(0)).getFirstChild();
1560            if (tmpnode == null)
1561                tmpnode = (TypedNode) resnodes.get(0);
1562            resvalue = (Comparable JavaDoc) tmpnode.getTypedValue();
1563            if (!(resvalue instanceof Number JavaDoc))
1564                throw new XQueryException("Could not apply function ceiling");
1565        } else
1566            throw new XQueryException("Could not apply function ceiling");
1567
1568        if (resvalue instanceof Long JavaDoc) { // do nothing
1569
} else if (resvalue instanceof BigDecimal JavaDoc)
1570            resvalue = ((BigDecimal JavaDoc) resvalue).setScale(0, BigDecimal.ROUND_CEILING);
1571        else if (resvalue instanceof Float JavaDoc)
1572            resvalue = new Float JavaDoc(Math.ceil(((Float JavaDoc) resvalue).floatValue()));
1573        else if (resvalue instanceof Double JavaDoc)
1574            resvalue = new Double JavaDoc(Math.ceil(((Double JavaDoc) resvalue).doubleValue()));
1575
1576        Integer JavaDoc rettype = (Integer JavaDoc) returnType.peek();
1577        if (rettype == VALUE_TYPE) {
1578            setValue(resvalue);
1579            return;
1580        } else { // (rettype == NODE_TYPE) {
1581
ArrayList nodes = new ArrayList(1);
1582            TypedValue text = docimpl.createTypedValue(resvalue, this.getSimpleType(resvalue, schemamanager.getDoubleType()));
1583            nodes.add(text);
1584            setResnodes(nodes);
1585            return;
1586        }
1587        // clear();
1588
}
1589    public void visit(FunctionFLOOR arg) throws XQueryException {
1590        returnType.push(UNKNOWN_TYPE);
1591        arg.getArgument(0).accept(this);
1592        returnType.pop();
1593        if (resvalue != null) { // do nothing
1594
} else if (resnodes != null && resnodes.size() == 1) {
1595            TypedNode tmpnode = (TypedNode) ((TypedNode) resnodes.get(0)).getFirstChild();
1596            if (tmpnode == null)
1597                tmpnode = (TypedNode) resnodes.get(0);
1598            resvalue = (Comparable JavaDoc) tmpnode.getTypedValue();
1599            if (!(resvalue instanceof Number JavaDoc))
1600                throw new XQueryException("Could not apply function floor");
1601        } else
1602            throw new XQueryException("Could not apply function floor");
1603
1604        if (resvalue instanceof Long JavaDoc) { // do nothing
1605
} else if (resvalue instanceof BigDecimal JavaDoc)
1606            resvalue = ((BigDecimal JavaDoc) resvalue).setScale(0, BigDecimal.ROUND_FLOOR);
1607        else if (resvalue instanceof Float JavaDoc)
1608            resvalue = new Float JavaDoc(Math.floor(((Float JavaDoc) resvalue).floatValue()));
1609        else if (resvalue instanceof Double JavaDoc)
1610            resvalue = new Double JavaDoc(Math.floor(((Double JavaDoc) resvalue).doubleValue()));
1611
1612        Integer JavaDoc rettype = (Integer JavaDoc) returnType.peek();
1613        if (rettype == VALUE_TYPE) {
1614            setValue(resvalue);
1615            return;
1616        } else { // (rettype == NODE_TYPE) {
1617
ArrayList nodes = new ArrayList(1);
1618            TypedValue text = docimpl.createTypedValue(resvalue, this.getSimpleType(resvalue, schemamanager.getDoubleType()));
1619            nodes.add(text);
1620            setResnodes(nodes);
1621            return;
1622        }
1623        // clear();
1624
}
1625    public void visit(FunctionROUND arg) throws XQueryException {
1626        returnType.push(UNKNOWN_TYPE);
1627        arg.getArgument(0).accept(this);
1628        returnType.pop();
1629        if (resvalue != null) { // do nothing
1630
} else if (resnodes != null && resnodes.size() == 1) {
1631            TypedNode tmpnode = (TypedNode) ((TypedNode) resnodes.get(0)).getFirstChild();
1632            if (tmpnode == null)
1633                tmpnode = (TypedNode) resnodes.get(0);
1634            resvalue = (Comparable JavaDoc) tmpnode.getTypedValue();
1635            if (!(resvalue instanceof Number JavaDoc))
1636                throw new XQueryException("Could not apply function round");
1637        } else
1638            throw new XQueryException("Could not apply function round");
1639
1640        if (resvalue instanceof Long JavaDoc) { // do nothing
1641
} else if (resvalue instanceof BigDecimal JavaDoc)
1642            resvalue = ((BigDecimal JavaDoc) resvalue).setScale(0, BigDecimal.ROUND_UP);
1643        else if (resvalue instanceof Float JavaDoc)
1644            resvalue = new BigDecimal JavaDoc(Math.round(((Float JavaDoc) resvalue).floatValue()));
1645        else if (resvalue instanceof Double JavaDoc)
1646            resvalue = new BigDecimal JavaDoc(Math.round(((Double JavaDoc) resvalue).doubleValue()));
1647
1648        Integer JavaDoc rettype = (Integer JavaDoc) returnType.peek();
1649        if (rettype == VALUE_TYPE) {
1650            setValue(resvalue);
1651            return;
1652        } else { // (rettype == NODE_TYPE) {
1653
ArrayList nodes = new ArrayList(1);
1654            TypedValue text = docimpl.createTypedValue(resvalue, this.getSimpleType(resvalue, schemamanager.getDoubleType()));
1655            nodes.add(text);
1656            setResnodes(nodes);
1657            return;
1658        }
1659        // clear();
1660
}
1661
1662    /*
1663    14.1.4 fn:number
1664    fn:number() as xs:double
1665    fn:number($srcval as item?) as xs:double
1666    Returns the value indicated by $srcval or, if $srcval is not specified, the context node, converted to an xs:double. If there is no context node (that is, if there is no context item, or if the context item is not a node), NaN is returned.
1667    
1668    If $srcval is the empty sequence, returns the xs:double value NaN.
1669    
1670    If $srcval is atomic, returns the value obtained by converting it to xs:double following the rules of 17.8 Casting to numeric types.
1671    
1672    If $srcval is a node with an atomic type, returns that value converted to xs:double following the rules of 17.8 Casting to numeric types.
1673    
1674    Otherwise, converts $srcval to an xs:string as if by a call to the fn:string() function and then converts the result to an xs:double following the rules of 17.8 Casting to numeric types.
1675    
1676    If the conversion to xs:double fails because the lexical representation is not a valid lexical representation of a numeric simple type as defined in [XML Schema Part 2: Datatypes], returns the xs:double value NaN.
1677    */

1678    public void visit(FunctionNUMBER arg) throws XQueryException {
1679        returnType.push(UNKNOWN_TYPE);
1680        arg.getArgument(0).accept(this);
1681        returnType.pop();
1682        if (resvalue != null) { // do nothing
1683
} else if (resnodes != null && resnodes.size() == 1) {
1684            TypedNode tmpnode = (TypedNode) ((TypedNode) resnodes.get(0)).getFirstChild();
1685            if (tmpnode == null)
1686                tmpnode = (TypedNode) resnodes.get(0);
1687            resvalue = (Comparable JavaDoc) tmpnode.getTypedValue();
1688            if (resvalue instanceof Number JavaDoc) {
1689                resvalue = new Double JavaDoc(((Number JavaDoc) resvalue).doubleValue());
1690            } else if (resvalue instanceof String JavaDoc) {
1691                try {
1692                    resvalue = new Double JavaDoc(Double.parseDouble((String JavaDoc) resvalue));
1693                } catch (NumberFormatException JavaDoc e) {
1694                    // do nothing
1695
}
1696            }
1697        } else if (resnodes != null && resnodes.size() > 1) {
1698            throw new XQueryException("Evaluation : incorrect argument for function number");
1699        }
1700        if (resvalue == null) {
1701            resvalue = new Double JavaDoc(Double.NaN);
1702        }
1703        Integer JavaDoc rettype = (Integer JavaDoc) returnType.peek();
1704        if (rettype == NODE_TYPE) {
1705            ArrayList nodes = new ArrayList(1);
1706            TypedValue text = docimpl.createTypedValue(resvalue, this.schemamanager.getDoubleType());
1707            nodes.add(text);
1708            setResnodes(nodes);
1709            return;
1710        } else { // (rettype == VALUE_TYPE) {
1711
setValue(resvalue);
1712            return;
1713        }
1714        // clear();
1715
}
1716
1717    //-----------------------------------------------------------
1718
// CAST/CONSTRUCTOR FUNCTIONS
1719
//-----------------------------------------------------------
1720
public void visit(FunctionDOUBLE arg) throws XQueryException {
1721        returnType.push(UNKNOWN_TYPE);
1722        arg.getArgument(0).accept(this);
1723        returnType.pop();
1724        if (resvalue != null) { // do nothing
1725
} else if (resnodes != null && resnodes.size() == 1) {
1726            TypedNode tmpnode = (TypedNode) ((TypedNode) resnodes.get(0)).getFirstChild();
1727            if (tmpnode == null)
1728                tmpnode = (TypedNode) resnodes.get(0);
1729            resvalue = (Comparable JavaDoc) tmpnode.getTypedValue();
1730        } else
1731            throw new XQueryException("Could not create double");
1732
1733        if (resvalue instanceof Double JavaDoc) { // do nothing
1734
} else if (resvalue instanceof Number JavaDoc) {
1735            resvalue = new Double JavaDoc(((Number JavaDoc) resvalue).doubleValue());
1736        } else if (resvalue instanceof String JavaDoc) {
1737            try {
1738                resvalue = new Double JavaDoc(Double.parseDouble((String JavaDoc) resvalue));
1739            } catch (NumberFormatException JavaDoc e) {
1740                // do nothing
1741
}
1742        } else
1743            throw new XQueryException("Could not create double");
1744        Integer JavaDoc rettype = (Integer JavaDoc) returnType.peek();
1745        if (rettype == VALUE_TYPE) {
1746            setValue(resvalue);
1747            return;
1748        } else { // (rettype == NODE_TYPE) {
1749
ArrayList nodes = new ArrayList(1);
1750            TypedValue text = docimpl.createTypedValue(resvalue, this.schemamanager.getDoubleType());
1751            nodes.add(text);
1752            setResnodes(nodes);
1753            return;
1754        }
1755        //clear();
1756
}
1757
1758    public void visit(FunctionINTEGER arg) throws XQueryException {
1759        returnType.push(UNKNOWN_TYPE);
1760        arg.getArgument(0).accept(this);
1761        returnType.pop();
1762        if (resvalue != null) { // do nothing
1763
} else if (resnodes != null && resnodes.size() == 1) {
1764            TypedNode tmpnode = (TypedNode) ((TypedNode) resnodes.get(0)).getFirstChild();
1765            if (tmpnode == null)
1766                tmpnode = (TypedNode) resnodes.get(0);
1767            resvalue = (Comparable JavaDoc) tmpnode.getTypedValue();
1768        } else
1769            throw new XQueryException("Could not create integer");
1770
1771        if (resvalue instanceof Long JavaDoc) { // do nothing
1772
} else if (resvalue instanceof Number JavaDoc) {
1773            resvalue = new Long JavaDoc(((Number JavaDoc) resvalue).longValue());
1774        } else if (resvalue instanceof String JavaDoc) {
1775            try {
1776                resvalue = new Long JavaDoc((String JavaDoc) resvalue);
1777            } catch (NumberFormatException JavaDoc e) {
1778                // do nothing
1779
}
1780        } else
1781            throw new XQueryException("Could not create integer");
1782        Integer JavaDoc rettype = (Integer JavaDoc) returnType.peek();
1783        if (rettype == VALUE_TYPE) {
1784            setValue(resvalue);
1785            return;
1786        } else { // (rettype == NODE_TYPE) {
1787
ArrayList nodes = new ArrayList(1);
1788            TypedValue text = docimpl.createTypedValue(resvalue, this.schemamanager.getIntegerType());
1789            nodes.add(text);
1790            setResnodes(nodes);
1791            return;
1792        }
1793        //clear();
1794
}
1795
1796    public void visit(FunctionDECIMAL arg) throws XQueryException {
1797        returnType.push(UNKNOWN_TYPE);
1798        arg.getArgument(0).accept(this);
1799        returnType.pop();
1800        if (resvalue != null) { // do nothing
1801
} else if (resnodes != null && resnodes.size() == 1) {
1802            TypedNode tmpnode = (TypedNode) ((TypedNode) resnodes.get(0)).getFirstChild();
1803            if (tmpnode == null)
1804                tmpnode = (TypedNode) resnodes.get(0);
1805            resvalue = (Comparable JavaDoc) tmpnode.getTypedValue();
1806        } else
1807            throw new XQueryException("Could not create decimal");
1808
1809        if (resvalue instanceof BigDecimal JavaDoc) { // do nothing
1810
} else if (resvalue instanceof Number JavaDoc) {
1811            resvalue = new BigDecimal JavaDoc(((Number JavaDoc) resvalue).doubleValue());
1812        } else if (resvalue instanceof String JavaDoc) {
1813            try {
1814                resvalue = new BigDecimal JavaDoc((String JavaDoc) resvalue);
1815            } catch (NumberFormatException JavaDoc e) {
1816                // do nothing
1817
}
1818        } else
1819            throw new XQueryException("Could not create decimal");
1820        Integer JavaDoc rettype = (Integer JavaDoc) returnType.peek();
1821        if (rettype == VALUE_TYPE) {
1822            setValue(resvalue);
1823            return;
1824        } else { // (rettype == NODE_TYPE) {
1825
ArrayList nodes = new ArrayList(1);
1826            TypedValue text = docimpl.createTypedValue(resvalue, this.schemamanager.getDecimalType());
1827            nodes.add(text);
1828            setResnodes(nodes);
1829            return;
1830        }
1831        //clear();
1832
}
1833
1834    //-----------------------------------------------------------
1835
// OTHER FUNCTIONS
1836
//-----------------------------------------------------------
1837

1838    public void visit(FunctionDATA arg) throws XQueryException {
1839        returnType.push(UNKNOWN_TYPE);
1840        arg.getArgument(0).accept(this);
1841        returnType.pop();
1842        Integer JavaDoc rettype = (Integer JavaDoc) returnType.peek();
1843        if (resvalue != null) {
1844            if (rettype == VALUE_TYPE) {
1845                setValue(resvalue);
1846                return;
1847            } else if (rettype == BOOLEAN_TYPE) {
1848                setVerdict(true);
1849                return;
1850            } else { // (rettype == NODE_TYPE) {
1851
ArrayList nodes = new ArrayList(1);
1852                TypedValue text = docimpl.createTypedValue(resvalue, this.getSimpleType(resvalue, schemamanager.getAnySimpleType()));
1853                nodes.add(text);
1854                setResnodes(nodes);
1855                return;
1856            }
1857        } else if (resnodes != null) {
1858            ArrayList tmplist = new ArrayList(resnodes.size());
1859            for (int i = 0; i < resnodes.size(); i++) {
1860                TypedNode tmpnode = (TypedNode) ((TypedNode) resnodes.get(i)).getFirstChild();
1861                // change 02/09/2003
1862
if (tmpnode == null || tmpnode.getTypedValue() == null)
1863                    tmpnode = (TypedNode) resnodes.get(i);
1864                Comparable JavaDoc comp = (Comparable JavaDoc) tmpnode.getTypedValue();
1865                if (comp != null)
1866                    tmplist.add(docimpl.createTypedValue(comp, this.getSimpleType(comp, schemamanager.getAnySimpleType())));
1867// else
1868
// throw new XQueryException("Could not apply function data");
1869
}
1870            if (rettype == VALUE_TYPE) {
1871                if (tmplist.size() == 1) {
1872                    TypedNode tmpnode = (TypedNode) ((TypedNode) tmplist.get(0)).getFirstChild();
1873                    if (tmpnode == null)
1874                        tmpnode = (TypedNode) tmplist.get(0);
1875                    setValue((Comparable JavaDoc) tmpnode.getTypedValue());
1876                    return;
1877                }
1878            } else if (rettype == BOOLEAN_TYPE) {
1879                if (tmplist.size() > 0)
1880                    setVerdict(true);
1881                else
1882                    setVerdict(false);
1883                return;
1884            } else { // (rettype == NODE_TYPE) {
1885
setResnodes(tmplist);
1886                return;
1887            }
1888        }
1889// else
1890
// throw new XQueryException("Could not apply function data");
1891
// clear();
1892
}
1893
1894    public void visit(FunctionEXISTS arg) throws XQueryException {
1895        returnType.push(NODE_TYPE);
1896        arg.getArgument(0).accept(this);
1897        returnType.pop();
1898        setVerdict(resnodes != null && !resnodes.isEmpty());
1899    }
1900
1901    public void visit(FunctionEMPTY arg) throws XQueryException {
1902        // if (buffertuple != null && !buffertuple.isEmpty()) {
1903
// setVerdict(false);
1904
// return;
1905
// }
1906
returnType.push(NODE_TYPE);
1907        arg.getArgument(0).accept(this);
1908        returnType.pop();
1909        setVerdict(resnodes == null || resnodes.isEmpty());
1910    }
1911
1912    public void visit(FunctionNOT arg) throws XQueryException {
1913        arg.getArgument(0).accept(this);
1914        setVerdict(!verdict);
1915    }
1916
1917    //public void visit(FunctionDISTINCT_VALUES arg) throws XQueryException;
1918

1919    public void visit(FunctionDEEP_EQUALS arg) throws XQueryException {
1920        resnodes = null;
1921        XQueryExpression arg0 = arg.getArgument(0);
1922        XQueryExpression arg1 = arg.getArgument(1);
1923        if (arg0 instanceof Value && arg1 instanceof Value)
1924            processComparison(arg0, arg1, null, null, null, null, Constants.EQ_COMPOP);
1925        else {
1926            if (arg0 instanceof Value) {
1927            } else if (arg1 instanceof Value) {
1928            } else {
1929            }
1930        }
1931    }
1932
1933
1934    //-----------------------------------------------------------
1935
// QNAME FUNCTIONS
1936
//-----------------------------------------------------------
1937

1938    public void visit(FunctionEXPANDED_QNAME arg) throws XQueryException {
1939        returnType.push(VALUE_TYPE);
1940        arg.getArgument(0).accept(this);
1941        if (resvalue == null)
1942            throw new XQueryException("Could not evaluate " + arg.getArgument(0));
1943        String JavaDoc prefix = resvalue.toString();
1944        String JavaDoc namespace = context.getNamespaceURI(prefix);
1945        if (namespace == null)
1946            throw new XQueryException("Could not find prefix : " + prefix);
1947        resvalue = null;
1948        arg.getArgument(1).accept(this);
1949        returnType.pop();
1950        if (resvalue == null)
1951            throw new XQueryException("Could not evaluate " + arg.getArgument(1));
1952        String JavaDoc localname = resvalue.toString();
1953        setValue((namespace.length() == 0)?localname:namespace+":"+localname);
1954    }
1955
1956    public void visit(FunctionQNAME arg) throws XQueryException {
1957        returnType.push(VALUE_TYPE);
1958        arg.getArgument(0).accept(this);
1959        if (resvalue == null)
1960            throw new XQueryException("Could not evaluate " + arg.getArgument(0));
1961        String JavaDoc qname = resvalue.toString();
1962        int index = qname.indexOf(":");
1963        String JavaDoc prefix = null;
1964        String JavaDoc namespace = null;
1965        if (index != -1) {
1966            prefix = qname.substring(0,index);
1967            namespace = context.getNamespaceURI(prefix);
1968            if (namespace == null)
1969                throw new XQueryException("Could not find prefix : " + prefix);
1970        }
1971        String JavaDoc localname = qname.substring(index+1);
1972        setValue((namespace == null || namespace.length() == 0)?localname:namespace+":"+localname);
1973    }
1974
1975    //-----------------------------------------------------------
1976
// PRIVATE METHODS
1977
//-----------------------------------------------------------
1978

1979    private SimpleType getSimpleType(Comparable JavaDoc obj, SimpleType defaultType) {
1980        if (obj instanceof Long JavaDoc)
1981            return this.schemamanager.getIntegerType();
1982        else if (obj instanceof BigDecimal JavaDoc)
1983            return this.schemamanager.getDecimalType();
1984        else if (obj instanceof Float JavaDoc)
1985            return this.schemamanager.getFloatType();
1986        else if (obj instanceof Double JavaDoc)
1987            return this.schemamanager.getDoubleType();
1988        else if (obj instanceof String JavaDoc)
1989            return this.schemamanager.getStringType();
1990        else if (obj instanceof Date)
1991            return this.schemamanager.getDateTimeType();
1992        return defaultType;
1993    }
1994
1995    private void processComparison(XQueryExpression exp1, XQueryExpression exp2, TypedNode tree1, TypedNode tree2, Comparable JavaDoc value1, Comparable JavaDoc value2, int operator) {
1996        //Comparable value1 = null;
1997
boolean doublecompare = false;
1998        double value1double = 0;
1999        if (value1 == null) {
2000            if (exp1 instanceof ValueInteger) {
2001                value1 = new Long JavaDoc(((ValueInteger) exp1).getIntValue().longValue());
2002            } else if (exp1 instanceof ValueDecimal) {
2003                value1 = ((ValueDecimal) exp1).getDecimalValue();
2004            } else if (exp1 instanceof ValueFloat) {
2005                value1 = ((ValueFloat) exp1).getFloatValue();
2006            } else if (exp1 instanceof ValueDouble) {
2007                value1 = ((ValueDouble) exp1).getDoubleValue();
2008            } else if (exp1 instanceof ValueString) {
2009                value1 = ((ValueString) exp1).getValue();
2010            } else if (tree1 != null) {
2011                if (tree1.getTypedValue() != null)
2012                    value1 = (Comparable JavaDoc) tree1.getTypedValue();
2013                else
2014                    value1 = (Comparable JavaDoc) getTextLeaf(tree1);
2015            }
2016        }
2017        if (value1 != null && !(value1 instanceof String JavaDoc) && !(value1 instanceof Timestamp JavaDoc) && !(value1 instanceof Date)) {
2018            value1double = ((Number JavaDoc) value1).doubleValue();
2019            doublecompare = true;
2020        }
2021        //Comparable value2 = null;
2022
double value2double = 0;
2023        if (value2 == null) {
2024            if (exp2 instanceof ValueInteger) {
2025                value2 = new Long JavaDoc(((ValueInteger) exp2).getIntValue().longValue());
2026            } else if (exp2 instanceof ValueDecimal) {
2027                value2 = ((ValueDecimal) exp2).getDecimalValue();
2028            } else if (exp2 instanceof ValueFloat) {
2029                value2 = ((ValueFloat) exp2).getFloatValue();
2030            } else if (exp2 instanceof ValueDouble) {
2031                value2 = ((ValueDouble) exp2).getDoubleValue();
2032            } else if (exp2 instanceof ValueString)
2033                value2 = ((ValueString) exp2).getValue();
2034            else if (tree2 != null) {
2035                if (tree2.getTypedValue() != null)
2036                    value2 = (Comparable JavaDoc) tree2.getTypedValue();
2037                else
2038                    value2 = (Comparable JavaDoc) getTextLeaf(tree2);
2039            }
2040        }
2041        if (value2 != null && !(value2 instanceof String JavaDoc) && !(value2 instanceof Timestamp JavaDoc) && !(value2 instanceof Date)) {
2042            value2double = ((Number JavaDoc) value2).doubleValue();
2043        } else
2044            doublecompare = false;
2045        boolean stringcomp = false;
2046        if (value1 == null) {
2047            if (value2 != null) {
2048                setVerdict(false);
2049                return;
2050            }
2051        } else {
2052            if (value2 == null) {
2053                setVerdict(false);
2054                return;
2055            } else {
2056                if (value1 instanceof String JavaDoc) {
2057                    if (!(value2 instanceof String JavaDoc)) {
2058                        value2 = value2.toString();
2059                        if (value2 == null) {
2060                            setVerdict(false);
2061                            return;
2062                        }
2063                        stringcomp = true;
2064                    }
2065                } else if (value2 instanceof String JavaDoc) {
2066                    value1 = value1.toString();
2067                    if (value1 == null) {
2068                        setVerdict(false);
2069                        return;
2070                    }
2071                    stringcomp = true;
2072                }
2073            }
2074        }
2075        switch (operator) {
2076            case Constants.LT_VALUECOMP :
2077            case Constants.LT_COMPOP :
2078                if ((value1 == null) && (value2 == null))
2079                    setVerdict(false);
2080                else if (stringcomp || !doublecompare)
2081                    setVerdict((value1.compareTo(value2) < 0));
2082                else
2083                    setVerdict((value1double < value2double));
2084                return;
2085            case Constants.GT_VALUECOMP :
2086            case Constants.GT_COMPOP :
2087                if ((value1 == null) && (value2 == null))
2088                    setVerdict(false);
2089                else if (stringcomp || !doublecompare)
2090                    setVerdict((value1.compareTo(value2) > 0));
2091                else
2092                    setVerdict((value1double > value2double));
2093                return;
2094            case Constants.GE_VALUECOMP :
2095            case Constants.GEQ_COMPOP :
2096                if ((value1 == null) && (value2 == null))
2097                    setVerdict(true);
2098                else if (stringcomp || !doublecompare)
2099                    setVerdict((value1.compareTo(value2) >= 0));
2100                else
2101                    setVerdict((value1double >= value2double));
2102                return;
2103            case Constants.LE_VALUECOMP :
2104            case Constants.LEQ_COMPOP :
2105                if ((value1 == null) && (value2 == null))
2106                    setVerdict(true);
2107                else if (stringcomp || !doublecompare)
2108                    setVerdict((value1.compareTo(value2) <= 0));
2109                else
2110                    setVerdict((value1double <= value2double));
2111                return;
2112            case Constants.EQ_VALUECOMP :
2113            case Constants.EQ_COMPOP :
2114                if ((value1 == null) && (value2 == null))
2115                    setVerdict(true);
2116                else if (stringcomp || !doublecompare)
2117                    setVerdict((value1.compareTo(value2) == 0));
2118                else
2119                    setVerdict((value1double == value2double));
2120                return;
2121            case Constants.NE_VALUECOMP :
2122            case Constants.NEQ_COMPOP :
2123                if ((value1 == null) && (value2 == null))
2124                    setVerdict(false);
2125                else if (stringcomp || !doublecompare)
2126                    setVerdict((value1.compareTo(value2) != 0));
2127                else
2128                    setVerdict((value1double != value2double));
2129                return;
2130                /*
2131                case Constants.EQQ_COMPOP :
2132                    setVerdict(Tuple.compareTree(tree1, tree2));
2133                    return;
2134                 */

2135        }
2136        clear();
2137    }
2138
2139    private Number JavaDoc processOperation(XQueryExpression exp1, XQueryExpression exp2, TypedNode tree1, TypedNode tree2, Number JavaDoc value1, Number JavaDoc value2, int operator) throws XQueryException {
2140        if (value1 == null) {
2141            if (exp1 instanceof ValueInteger)
2142                value1 = new Long JavaDoc(((ValueInteger) exp1).getIntValue().longValue());
2143            else if (exp1 instanceof ValueDecimal)
2144                value1 = ((ValueDecimal) exp1).getDecimalValue();
2145            else if (exp1 instanceof ValueFloat)
2146                value1 = ((ValueFloat) exp1).getFloatValue();
2147            else if (exp1 instanceof ValueDouble)
2148                value1 = ((ValueDouble) exp1).getDoubleValue();
2149            else if (tree1 != null)
2150                if (tree1.getTypedValue() != null)
2151                    value1 = (Number JavaDoc) tree1.getTypedValue();
2152                else
2153                    value1 = (Number JavaDoc) getTextLeaf(tree1);
2154        }
2155        if (value2 == null) {
2156            if (exp2 instanceof ValueInteger)
2157                value2 = new Long JavaDoc(((ValueInteger) exp2).getIntValue().longValue());
2158            else if (exp2 instanceof ValueDecimal)
2159                value2 = ((ValueDecimal) exp2).getDecimalValue();
2160            else if (exp2 instanceof ValueFloat)
2161                value2 = ((ValueFloat) exp2).getFloatValue();
2162            else if (exp2 instanceof ValueDouble)
2163                value2 = ((ValueDouble) exp2).getDoubleValue();
2164            else if (tree2 != null)
2165                if (tree2.getTypedValue() != null)
2166                    value2 = (Number JavaDoc) tree2.getTypedValue();
2167                else
2168                    value2 = (Number JavaDoc) getTextLeaf(tree2);
2169        }
2170
2171        boolean integerOp = false;
2172        boolean decimalOp = false;
2173        boolean floatOp = false;
2174        if (value1 instanceof Long JavaDoc) {
2175            if (value2 instanceof Long JavaDoc)
2176                integerOp = true;
2177            else if (value2 instanceof BigDecimal JavaDoc) {
2178                value1 = new BigDecimal JavaDoc(value1.longValue());
2179                decimalOp = true;
2180            }
2181        } else if (value1 instanceof BigDecimal JavaDoc) {
2182            if (value2 instanceof BigDecimal JavaDoc)
2183                decimalOp = true;
2184            else if (value2 instanceof Long JavaDoc) {
2185                value2 = new BigDecimal JavaDoc(value2.longValue());
2186                decimalOp = true;
2187            }
2188        } else if (value1 instanceof Float JavaDoc) {
2189            if (value2 instanceof Float JavaDoc)
2190                floatOp = true;
2191            if (!(value2 instanceof Double JavaDoc)) {
2192                value2 = new Float JavaDoc(value2.doubleValue());
2193                floatOp = true;
2194            }
2195        }
2196
2197        switch (operator) {
2198            case Constants.DIVIDE_ARITHMETICS :
2199                //if (integerOp) {
2200
// try {
2201
// return value1.intValue() / value2.intValue();
2202
// } catch (ArithmeticException ae) {
2203
// throw new XQueryException("Division by zero");
2204
// }
2205
// } else
2206
if (decimalOp) {
2207                    try {
2208                        return ((BigDecimal JavaDoc) value1).divide((BigDecimal JavaDoc) value2, 38, BigDecimal.ROUND_UP);
2209                    } catch (ArithmeticException JavaDoc ae) {
2210                        throw new XQueryException("Division by zero");
2211                    }
2212                } else if (floatOp)
2213                    return new Float JavaDoc(value1.floatValue() / value2.floatValue());
2214                return new Double JavaDoc(value1.doubleValue() / value2.doubleValue());
2215            case Constants.MINUS_ARITHMETICS :
2216                if (integerOp)
2217                    return new Long JavaDoc(value1.longValue() - value2.longValue());
2218                else if (decimalOp)
2219                    return ((BigDecimal JavaDoc) value1).subtract((BigDecimal JavaDoc) value2);
2220                else if (floatOp)
2221                    return new Float JavaDoc(value1.floatValue() - value2.floatValue());
2222                return new Double JavaDoc(value1.doubleValue() - value2.doubleValue());
2223            case Constants.MODULO_ARITHMETICS :
2224                if (integerOp)
2225                    return new Long JavaDoc(value1.longValue() % value2.longValue());
2226                else if (floatOp)
2227                    return new Float JavaDoc(value1.floatValue() % value2.floatValue());
2228                return new Double JavaDoc(value1.doubleValue() % value2.doubleValue());
2229            case Constants.MULTIPLY_ARITHMETICS :
2230                if (integerOp)
2231                    return new Long JavaDoc(value1.longValue() * value2.longValue());
2232                else if (decimalOp)
2233                    return ((BigDecimal JavaDoc) value1).multiply((BigDecimal JavaDoc) value2);
2234                else if (floatOp)
2235                    return new Float JavaDoc(value1.floatValue() * value2.floatValue());
2236                return new Double JavaDoc(value1.doubleValue() * value2.doubleValue());
2237            case Constants.PLUS_ARITHMETICS :
2238                if (integerOp)
2239                    return new Long JavaDoc(value1.longValue() + value2.longValue());
2240                else if (decimalOp)
2241                    return ((BigDecimal JavaDoc) value1).add((BigDecimal JavaDoc) value2);
2242                else if (floatOp)
2243                    return new Float JavaDoc(value1.floatValue() + value2.floatValue());
2244                return new Double JavaDoc(value1.doubleValue() + value2.doubleValue());
2245        }
2246        throw new XQueryException("Could not process operation");
2247    }
2248
2249    private void getStringValue(Node JavaDoc node, StringBuffer JavaDoc sb) {
2250        if (node == null)
2251            return;
2252        if (node.getNodeType() == Node.TEXT_NODE) {
2253            sb.append(node.getNodeValue());
2254        }
2255        org.w3c.dom.NodeList JavaDoc nl = node.getChildNodes();
2256        for (int i = 0; i < nl.getLength(); i++) {
2257            getStringValue(nl.item(i), sb);
2258        }
2259    }
2260
2261    private Object JavaDoc getTextLeaf(TypedNode node) {
2262        if (node == null)
2263            return null;
2264        if (node instanceof TypedValue) {
2265            return ((TypedValue) node).getData();
2266        }
2267        if (node instanceof TypedAttributeImpl) {
2268            return ((TypedAttributeImpl) node).getNodeValue();
2269        }
2270        org.w3c.dom.NodeList JavaDoc nl = node.getChildNodes();
2271        if (nl.getLength() != 1)
2272            return null;
2273        TypedNode n = (TypedNode) nl.item(0);
2274        return n.getTypedValue();
2275    }
2276
2277}
2278
Popular Tags