KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > ojb > jdo > jdoql > QueryTreeResolver


1 package org.apache.ojb.jdo.jdoql;
2
3 /* Copyright 2003-2005 The Apache Software Foundation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18 import java.math.BigDecimal JavaDoc;
19 import java.math.BigInteger JavaDoc;
20 import java.util.Collection JavaDoc;
21 import java.util.Date JavaDoc;
22 import java.util.HashMap JavaDoc;
23 import java.util.Iterator JavaDoc;
24 import java.util.Map JavaDoc;
25
26 import javax.jdo.JDOUserException;
27
28 import org.apache.ojb.broker.metadata.*;
29 import org.apache.ojb.broker.util.ClassHelper;
30 import org.apache.ojb.jdo.QueryImpl;
31
32 /**
33  * Resolves and checks the query trees. This involves the following things:<br/>
34  * <ul>
35  * <li>Replace {@link NameExpression NameExpression} with {@link LocalVariableAccess VariableAccess},
36  * {@link FieldAccess FieldAccess}, or {@link TypeAccess TypeAccess}</li>
37  * <li>Resolve types referenced by {@link Type Type} and {@link TypeAccess TypeAccess}</li>
38  * <li>Resolve features/variables referenced by {@link LocalVariableAccess VariableAccess},
39  * {@link FieldAccess FieldAccess}, and {@link MethodInvocation MethodInvocation}</li>
40  * <li>Check that expression types are valid, e.g. that the types of the two sides of a binary
41  * expression are compatible to each other and that this binary operator can be applied
42  * to them</li>
43  * <li>Check that the accessed methods are allowed to be accessed as per JDO spec (or
44  * extensions allowed by OJB)</li>
45  * <li>Check that for each accessed variable there is a variable or parameter defined</li>
46  * <li>Check that each accessed field is persistent</li>
47  * </ul>
48  *
49  * @author <a HREF="mailto:tomdz@apache.org">Thomas Dudziak</a>
50  */

51 public class QueryTreeResolver extends VisitorBase
52 {
53     // TODO: Integrate position info into the exceptions
54

55     /** Defines the ordering of primitive types */
56     private static HashMap JavaDoc _primitiveTypes = new HashMap JavaDoc();
57
58     static
59     {
60         _primitiveTypes.put(byte.class, new Integer JavaDoc(0));
61         _primitiveTypes.put(char.class, new Integer JavaDoc(1));
62         _primitiveTypes.put(short.class, new Integer JavaDoc(2));
63         _primitiveTypes.put(int.class, new Integer JavaDoc(3));
64         _primitiveTypes.put(long.class, new Integer JavaDoc(4));
65         _primitiveTypes.put(BigInteger JavaDoc.class, new Integer JavaDoc(5));
66         _primitiveTypes.put(float.class, new Integer JavaDoc(6));
67         _primitiveTypes.put(double.class, new Integer JavaDoc(7));
68         _primitiveTypes.put(BigDecimal JavaDoc.class, new Integer JavaDoc(8));
69     }
70     
71     /** The currently resolved query */
72     private QueryImpl _query;
73
74     /**
75      * Resolves and checks the given query. Results from a previous resolving are
76      * overwritten.
77      *
78      * @param query The query
79      * @exception JDOUserException If the query is invalid
80      */

81     public void resolveAndCheck(QueryImpl query) throws JDOUserException
82     {
83         _query = query;
84         try
85         {
86             checkImports(query.getImports());
87             visit(query.getVariables());
88             visit(query.getParameters());
89             if (query.getFilterExpression() != null)
90             {
91                 query.getFilterExpression().accept(this);
92             }
93             visit(query.getOrderings());
94         }
95         finally
96         {
97             _query = null;
98         }
99     }
100
101     /**
102      * Checks the imports. We're a bit more foregiving as the JDO Spec because
103      * we don't demand that all imported types/packages exists as long as they
104      * are not used.
105      *
106      * @param imports The imports to check
107      * @throws JDOUserException If two direct imports imports types with the same
108      * short name
109      */

110     private void checkImports(Collection JavaDoc imports) throws JDOUserException
111     {
112         // It is an error if two direct imports import classes with the same short name
113
HashMap JavaDoc directlyImportedClasses = new HashMap JavaDoc();
114         Import importDecl;
115         String JavaDoc shortName;
116
117         for (Iterator JavaDoc it = imports.iterator(); it.hasNext();)
118         {
119             importDecl = (Import)it.next();
120             if (!importDecl.isOnDemand())
121             {
122                 shortName = importDecl.getSpec().substring(importDecl.getSpec().lastIndexOf('.'));
123                 if (directlyImportedClasses.containsKey(shortName))
124                 {
125                     throw new JDOUserException("Multiple direct imports of classes with the same unqualified name "+shortName);
126                 }
127                 else
128                 {
129                     directlyImportedClasses.put(shortName, null);
130                 }
131             }
132         }
133     }
134     
135     /**
136      * Visits all elements of the given map.
137      *
138      * @param objects The objects
139      * @exception JDOUserException If one of the elements is invalid
140      */

141     private void visit(Map JavaDoc objects) throws JDOUserException
142     {
143         if (objects != null)
144         {
145             for (Iterator JavaDoc it = objects.values().iterator(); it.hasNext();)
146             {
147                 ((Acceptor)it.next()).accept(this);
148             }
149         }
150     }
151     
152     /**
153      * Visits all elements of the given collection.
154      *
155      * @param objects The objects
156      * @exception JDOUserException If one of the elements is invalid
157      */

158     private void visit(Collection JavaDoc objects) throws JDOUserException
159     {
160         if (objects != null)
161         {
162             for (Iterator JavaDoc it = objects.iterator(); it.hasNext();)
163             {
164                 ((Acceptor)it.next()).accept(this);
165             }
166         }
167     }
168
169     /* (non-Javadoc)
170      * @see org.apache.ojb.jdo.jdoql.Visitor#visit(org.apache.ojb.jdo.jdoql.BinaryExpression)
171      */

172     public void visit(BinaryExpression binExpr) throws JDOUserException
173     {
174         super.visit(binExpr);
175
176         // for the types of the left and right expressions one of the following must hold:
177
// * the operator is '+' and both are String
178
// * the operator is arithmethic and both are numeric (Character, Long or Double)
179
// * the operator is bitwise and both are Character or Long
180
// * the operator is logic and both are Boolean
181
// * the operator is comparative and the both are String, or both are Date, or both are Numeric
182
Class JavaDoc leftType = binExpr.getLeftSide().getType();
183         Class JavaDoc rightType = binExpr.getRightSide().getType();
184         boolean typeWasSet = false;
185
186         switch (binExpr.getOperator())
187         {
188             case BinaryExpression.OPERATOR_MULTIPLY :
189             case BinaryExpression.OPERATOR_DIVIDE :
190             case BinaryExpression.OPERATOR_PLUS :
191             case BinaryExpression.OPERATOR_MINUS :
192                 if (binExpr.getOperator() == BinaryExpression.OPERATOR_PLUS)
193                 {
194                     if ((leftType == String JavaDoc.class) && (rightType == String JavaDoc.class))
195                     {
196                         binExpr.setType(String JavaDoc.class);
197                         typeWasSet = true;
198                         break;
199                     }
200                 }
201                 if (isNumeric(leftType) && isNumeric(rightType))
202                 {
203                     binExpr.setType(getBroaderType(leftType, rightType));
204                     typeWasSet = true;
205                 }
206                 break;
207             case BinaryExpression.OPERATOR_BITWISE_AND :
208             case BinaryExpression.OPERATOR_BITWISE_XOR :
209             case BinaryExpression.OPERATOR_BITWISE_OR :
210                 if (isInteger(leftType) && isInteger(rightType))
211                 {
212                     binExpr.setType(getBroaderType(leftType, rightType));
213                     typeWasSet = true;
214                 }
215                 else if ((leftType == boolean.class) && (rightType == boolean.class))
216                 {
217                     binExpr.setType(boolean.class);
218                     typeWasSet = true;
219                 }
220                 break;
221             case BinaryExpression.OPERATOR_LOWER :
222             case BinaryExpression.OPERATOR_GREATER :
223             case BinaryExpression.OPERATOR_LOWER_OR_EQUAL :
224             case BinaryExpression.OPERATOR_GREATER_OR_EQUAL :
225                 if (isNumeric(leftType) && isNumeric(rightType))
226                 {
227                     binExpr.setType(boolean.class);
228                     typeWasSet = true;
229                 }
230                 else if ((leftType == String JavaDoc.class) && (rightType == String JavaDoc.class))
231                 {
232                     binExpr.setType(boolean.class);
233                     typeWasSet = true;
234                 }
235                 else if ((leftType == Date JavaDoc.class) && (rightType == Date JavaDoc.class))
236                 {
237                     binExpr.setType(boolean.class);
238                     typeWasSet = true;
239                 }
240                 break;
241             case BinaryExpression.OPERATOR_EQUAL :
242             case BinaryExpression.OPERATOR_NOT_EQUAL :
243                 if (isNumeric(leftType) && isNumeric(rightType))
244                 {
245                     binExpr.setType(boolean.class);
246                     typeWasSet = true;
247                 }
248                 else if ((leftType == boolean.class) && (rightType == boolean.class))
249                 {
250                     binExpr.setType(boolean.class);
251                     typeWasSet = true;
252                 }
253                 else if (!leftType.isPrimitive() && !rightType.isPrimitive())
254                 {
255                     binExpr.setType(boolean.class);
256                     typeWasSet = true;
257                 }
258                 break;
259             case BinaryExpression.OPERATOR_AND :
260             case BinaryExpression.OPERATOR_OR :
261                 if ((leftType == boolean.class) && (rightType == boolean.class))
262                 {
263                     binExpr.setType(boolean.class);
264                     typeWasSet = true;
265                 }
266                 break;
267         }
268         if (!typeWasSet)
269         {
270             throw new JDOUserException("Binary expression cannot be applied to expressions of types "+leftType.getName()+" and "+rightType.getName());
271         }
272     }
273
274     /* (non-Javadoc)
275      * @see org.apache.ojb.jdo.jdoql.Visitor#visit(org.apache.ojb.jdo.jdoql.MethodInvocation)
276      */

277     public void visit(MethodInvocation methodInvoc) throws JDOUserException
278     {
279         super.visit(methodInvoc);
280
281         Class JavaDoc type = methodInvoc.getBaseExpression().getType();
282         String JavaDoc name = methodInvoc.getName();
283
284         if (Collection JavaDoc.class.isAssignableFrom(type))
285         {
286             if ("contains".equals(name))
287             {
288                 if (methodInvoc.getArguments().size() != 1)
289                 {
290                     throw new JDOUserException("Illegal number of arguments to method Collection.contains");
291                 }
292             }
293             else if ("isEmpty".equals(name))
294             {
295                 if (!methodInvoc.getArguments().isEmpty())
296                 {
297                     throw new JDOUserException("Illegal number of arguments to method Collection.isEmpty");
298                 }
299             }
300             else
301             {
302                 throw new JDOUserException("Only methods 'contains' and 'isEmpty' are allowed to be called at collection objects");
303             }
304             methodInvoc.setType(boolean.class);
305         }
306         else if (type == String JavaDoc.class)
307         {
308             if (!"startsWith".equals(name) && !"endsWith".equals(name))
309             {
310                 throw new JDOUserException("Only methods 'contains' and 'isEmpty' are allowed to be called at collection objects");
311             }
312             if (methodInvoc.getArguments().size() != 1)
313             {
314                 throw new JDOUserException("Illegal number of arguments to method String."+name);
315             }
316             if (((Expression)methodInvoc.getArguments().get(0)).getType() != String JavaDoc.class)
317             {
318                 throw new JDOUserException("Illegal argument to method Collection."+name);
319             }
320             methodInvoc.setType(boolean.class);
321         }
322         else
323         {
324             throw new JDOUserException("Invocation of method "+methodInvoc.getName()+" at type "+type.getName()+" is not allowed");
325         }
326     }
327
328     /* (non-Javadoc)
329      * @see org.apache.ojb.jdo.jdoql.Visitor#visit(org.apache.ojb.jdo.jdoql.NameExpression)
330      */

331     public void visit(NameExpression nameExpr) throws JDOUserException
332     {
333         super.visit(nameExpr);
334
335         Expression newExpr = null;
336         Class JavaDoc baseType = null;
337
338         // we search in this order (which corresponds to Java's name resolution order):
339
// * variables (only if without base expression)
340
// * parameters (only if without base expression)
341
// * fields/references/collections (at searched type if without base expression)
342
// types are currently not searched for as they are not allowed to appear directly
343
// except in casts
344
if (!nameExpr.hasBaseExpression())
345         {
346             // no base expressiom
347
LocalVariable var = _query.getVariable(nameExpr.getName());
348
349             if (var == null)
350             {
351                 var = _query.getParameter(nameExpr.getName());
352             }
353             if (var != null)
354             {
355                 LocalVariableAccess varAccess = new LocalVariableAccess(nameExpr.getName());
356
357                 varAccess.setAccessedVariable(var);
358                 newExpr = varAccess;
359             }
360             else
361             {
362                 // neither a variable nor parameter, so we must search in the class
363
// whose objects the query searches for
364
baseType = _query.getSearchedClass();
365             }
366         }
367         else
368         {
369             // we have a base expression which means that we follow a reference
370
baseType = nameExpr.getBaseExpression().getType();
371         }
372         if (newExpr == null)
373         {
374             // so we determine the persistent type of the base expression
375
ClassDescriptor classDesc = findClassDescriptorFor(baseType);
376             
377             if (classDesc == null)
378             {
379                 throw new JDOUserException("Access to type "+baseType.getName()+" is not allowed because the type is not persistent");
380             }
381
382             FieldAccess fieldAccess = new FieldAccess(nameExpr.getBaseExpression(), nameExpr.getName());
383             
384             // it may be either a field, reference or collection descriptor -
385
// this depends on whether the name expression is a base expression
386
// to another name expression (not a method invocation or other expression)
387
ObjectReferenceDescriptor refDesc = classDesc.getObjectReferenceDescriptorByName(nameExpr.getName());
388             
389             if (refDesc != null)
390             {
391                 fieldAccess.setFieldDescriptor(refDesc);
392             }
393             else if (nameExpr.hasParent() && (nameExpr.getParent() instanceof NameExpression))
394             {
395                 // if we are the base expression of another name expression, then it must be a reference
396
throw new JDOUserException("Cannot find reference "+nameExpr.getName()+" in type "+baseType.getName()+" because it is not defined, not persistent or not a reference");
397             }
398             else
399             {
400                 // it can be a field or collection
401
CollectionDescriptor collDesc = classDesc.getCollectionDescriptorByName(nameExpr.getName());
402                 if (collDesc != null)
403                 {
404                     fieldAccess.setFieldDescriptor(collDesc);
405                 }
406                 else
407                 {
408                     FieldDescriptor fieldDesc = classDesc.getFieldDescriptorByName(nameExpr.getName());
409     
410                     if (fieldDesc == null)
411                     {
412                         throw new JDOUserException("Cannot find feature "+nameExpr.getName()+" in type "+baseType.getName()+" because it is not defined or not persistent");
413                     }
414                     fieldAccess.setFieldDescriptor(fieldDesc);
415                 }
416             }
417             newExpr = fieldAccess;
418         }
419
420         if (nameExpr.hasParent())
421         {
422             nameExpr.getParent().replaceChild(nameExpr, newExpr);
423         }
424     }
425
426     /* (non-Javadoc)
427      * @see org.apache.ojb.jdo.jdoql.Visitor#visit(org.apache.ojb.jdo.jdoql.NullLiteral)
428      */

429     public void visit(NullLiteral nullLit)
430     {
431         Expression parent = nullLit.getParent();
432
433         if (parent == null)
434         {
435             return;
436         }
437
438         // the only interesting case is if the parent is a binary expression (e.g.
439
// a '==' expression) in which case the null literal shall have the same
440
// type as the other operand
441
if (parent instanceof BinaryExpression)
442         {
443             Class JavaDoc type = null;
444
445             if (((BinaryExpression)parent).getLeftSide() == nullLit)
446             {
447                 type = ((BinaryExpression)parent).getRightSide().getType();
448             }
449             else
450             {
451                 type = ((BinaryExpression)parent).getLeftSide().getType();
452             }
453             if (type.isPrimitive())
454             {
455                 throw new JDOUserException("Illegal binary expression with a 'null' and a primitive operand");
456             }
457             nullLit.setType(type);
458         }
459     }
460
461     /* (non-Javadoc)
462      * @see org.apache.ojb.jdo.jdoql.Visitor#visit(org.apache.ojb.jdo.jdoql.ThisExpression)
463      */

464     public void visit(ThisExpression thisExpr)
465     {
466         super.visit(thisExpr);
467         thisExpr.setType(_query.getSearchedClass());
468     }
469
470     /* (non-Javadoc)
471      * @see org.apache.ojb.jdo.jdoql.Visitor#visit(org.apache.ojb.jdo.jdoql.Type)
472      */

473     public void visit(Type type) throws JDOUserException
474     {
475         ClassLoader JavaDoc loader = ClassHelper.getClassLoader();
476         Class JavaDoc result = null;
477         String JavaDoc name = type.getName();
478         int pos = name.indexOf('.');
479
480         if (pos >= 0)
481         {
482             // its either a qualified name or refers to an inner class
483
// we ignore inner classes here as they are handled by the import
484
// resolution below
485
// [tomdz] we might have to resolve inner/nested classes manually
486
// if the query should be executed in the scope of the
487
// searched class (which makes private/protected/friendly
488
// inner/nested classes visible)
489
// for now we assume that this is not the case
490
try
491             {
492                 result = Class.forName(name, true, loader);
493             }
494             catch (ClassNotFoundException JavaDoc ex)
495             {
496                 // ignored
497
}
498         }
499         if (result == null)
500         {
501             result = resolveUnqualifiedClassName(loader, name);
502         }
503         if (result == null)
504         {
505             throw new JDOUserException("No such class "+name);
506         }
507         else
508         {
509             type.setType(result);
510         }
511     }
512
513     /**
514      * Resolves the given unqualified class name against the imports of the query.
515      *
516      * @param loader The class loader to use
517      * @param unqualifiedName The unqualified class name
518      * @return The class if it has been found
519      * @exception JDOUserException If a direct import declaration is invalid
520      */

521     private Class JavaDoc resolveUnqualifiedClassName(ClassLoader JavaDoc loader, String JavaDoc unqualifiedName) throws JDOUserException
522     {
523         // A direct import has precedence over on-demand imports of packages that contain
524
// a class of the same short name (JLS 7.5.1)
525
// If multiple on-demand imports import packages that have a class with a given
526
// short name, then the last such import defines the class to be used
527
Import importDecl;
528         Class JavaDoc result = null;
529         int pos;
530
531         // we first try to resolve it against java.lang
532
try
533         {
534             result = Class.forName("java.lang." + unqualifiedName, true, loader);
535         }
536         catch (ClassNotFoundException JavaDoc ex)
537         {
538             // ignored
539
}
540         for (Iterator JavaDoc it = _query.getImports().iterator(); it.hasNext();)
541         {
542             importDecl = (Import)it.next();
543             if (importDecl.isOnDemand())
544             {
545                 try
546                 {
547                     result = Class.forName(importDecl.getSpec() + "." + unqualifiedName, true, loader);
548                 }
549                 catch (ClassNotFoundException JavaDoc ex)
550                 {
551                     // ignored
552
}
553             }
554             else
555             {
556                 pos = importDecl.getSpec().lastIndexOf('.');
557                 if (unqualifiedName.equals(importDecl.getSpec().substring(pos + 1)))
558                 {
559                     try
560                     {
561                         // there can only be one direct import of a class with this
562
// unqualified name (imports have already been checked), and
563
// no on-demand import can shadow it, so we can simply return it
564
return Class.forName(importDecl.getSpec() + "." + unqualifiedName, true, loader);
565                     }
566                     catch (ClassNotFoundException JavaDoc ex)
567                     {
568                         // we have a direct import for the class but the import is invalid
569
throw new JDOUserException("The import "+importDecl.getSpec()+" is invalid");
570                     }
571                 }
572             }
573         }
574         return result;
575     }
576
577     /* (non-Javadoc)
578      * @see org.apache.ojb.jdo.jdoql.Visitor#visit(org.apache.ojb.jdo.jdoql.UnaryExpression)
579      */

580     public void visit(UnaryExpression unaryExpr) throws JDOUserException
581     {
582         super.visit(unaryExpr);
583
584         // one of the following must hold:
585
// * the operator is arithmetic and the inner type is numeric
586
// * the operator is bitwise and the inner type is Character or Long
587
// * the operator is logic and the inner type is Boolean
588
// * it is a cast and the cast type is assignment compatible to the inner type
589
Class JavaDoc innerType = unaryExpr.getInnerExpression().getType();
590         boolean typeWasSet = false;
591
592         switch (unaryExpr.getOperator())
593         {
594             case UnaryExpression.OPERATOR_PLUS :
595             case UnaryExpression.OPERATOR_MINUS :
596                 if (isNumeric(innerType))
597                 {
598                     unaryExpr.setType(innerType);
599                     typeWasSet = true;
600                 }
601                 break;
602             case UnaryExpression.OPERATOR_BITWISE_COMPLEMENT :
603                 if (isInteger(innerType))
604                 {
605                     unaryExpr.setType(innerType);
606                     typeWasSet = true;
607                 }
608                 break;
609             case UnaryExpression.OPERATOR_NOT :
610                 if (innerType == boolean.class)
611                 {
612                     unaryExpr.setType(innerType);
613                     typeWasSet = true;
614                 }
615                 break;
616             case UnaryExpression.OPERATOR_CAST :
617                 Class JavaDoc castType = unaryExpr.getCastType().getType();
618
619                 if (isNumeric(castType) && isNumeric(innerType))
620                 {
621                     unaryExpr.setType(castType);
622                     typeWasSet = true;
623                 }
624                 else
625                 {
626                     // check for narrowing or widening reference conversion
627
if (castType.isAssignableFrom(innerType) || innerType.isAssignableFrom(castType))
628                     {
629                         unaryExpr.setType(castType);
630                         typeWasSet = true;
631                     }
632                 }
633                 break;
634
635         }
636         if (!typeWasSet)
637         {
638             if (unaryExpr.getOperator() == UnaryExpression.OPERATOR_CAST)
639             {
640                 throw new JDOUserException("Invalid cast expression because inner expression of type "+innerType.getName()+" cannot be cast to "+unaryExpr.getCastType().getName());
641             }
642             else
643             {
644                 throw new JDOUserException("Invalid unary expression");
645             }
646         }
647     }
648
649     // Helper methods
650

651     /**
652      * Retrieves OJB's class descriptor for the given type.
653      *
654      * @param The type to lookup
655      * @return The class descriptor or <code>null</code> if the class is not persistent
656      */

657     private ClassDescriptor findClassDescriptorFor(Class JavaDoc type)
658     {
659         return MetadataManager.getInstance().getRepository().getDescriptorFor(type);
660     }
661
662     /**
663      * Determines whether the given class denotes an integer primitive type.
664      *
665      * @param type The type
666      * @return <code>true</code> if the type is an integer type
667      */

668     private static boolean isInteger(Class JavaDoc type)
669     {
670         if (type.isPrimitive())
671         {
672             return (type != boolean.class) && (type != float.class) && (type != double.class);
673         }
674         else
675         {
676             return type == BigInteger JavaDoc.class;
677         }
678     }
679
680     /**
681      * Determines whether the given class denotes a floating point primitive type.
682      *
683      * @param type The type
684      * @return <code>true</code> if the type is a floating point type
685      */

686     private static boolean isFloatingPoint(Class JavaDoc type)
687     {
688         if (type.isPrimitive())
689         {
690             return (type == float.class) || (type == double.class);
691         }
692         else
693         {
694             return type == BigDecimal JavaDoc.class;
695         }
696     }
697
698     /**
699      * Determines whether the given class denotes a numeric primitive type.
700      *
701      * @param type The type
702      * @return <code>true</code> if the type is a numeric type
703      */

704     private static boolean isNumeric(Class JavaDoc type)
705     {
706         if (type.isPrimitive())
707         {
708             return type != boolean.class;
709         }
710         else
711         {
712             return (type == BigDecimal JavaDoc.class) || (type == BigInteger JavaDoc.class);
713         }
714     }
715
716     /**
717      * Determines the broader of the two given numeric types.
718      *
719      * @param typeA The first type
720      * @param typeB The seconf type
721      * @return The broader of the two types
722      */

723     private static Class JavaDoc getBroaderType(Class JavaDoc typeA, Class JavaDoc typeB)
724     {
725         Integer JavaDoc numA = (Integer JavaDoc)_primitiveTypes.get(typeA);
726         Integer JavaDoc numB = (Integer JavaDoc)_primitiveTypes.get(typeB);
727
728         return numA.intValue() < numB.intValue() ? typeB : typeA;
729     }
730 }
731
Popular Tags