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