KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > compiler > apt > model > Factory


1 /*******************************************************************************
2  * Copyright (c) 2007 BEA Systems, Inc.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * wharley@bea.com - initial API and implementation
10  *
11  *******************************************************************************/

12
13 package org.eclipse.jdt.internal.compiler.apt.model;
14
15 import java.lang.reflect.Array JavaDoc;
16 import java.util.ArrayList JavaDoc;
17 import java.util.Collections JavaDoc;
18 import java.util.EnumSet JavaDoc;
19 import java.util.List JavaDoc;
20 import java.util.Set JavaDoc;
21
22 import javax.lang.model.element.AnnotationMirror;
23 import javax.lang.model.element.Element;
24 import javax.lang.model.element.ElementKind;
25 import javax.lang.model.element.Modifier;
26 import javax.lang.model.element.PackageElement;
27 import javax.lang.model.element.TypeParameterElement;
28 import javax.lang.model.type.DeclaredType;
29 import javax.lang.model.type.ErrorType;
30 import javax.lang.model.type.NoType;
31 import javax.lang.model.type.NullType;
32 import javax.lang.model.type.TypeKind;
33 import javax.lang.model.type.TypeMirror;
34
35 import org.eclipse.jdt.internal.compiler.apt.dispatch.BaseProcessingEnvImpl;
36 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
37 import org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding;
38 import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
39 import org.eclipse.jdt.internal.compiler.lookup.BaseTypeBinding;
40 import org.eclipse.jdt.internal.compiler.lookup.Binding;
41 import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
42 import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
43 import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding;
44 import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
45 import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
46 import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
47 import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
48 import org.eclipse.jdt.internal.compiler.lookup.VariableBinding;
49 import org.eclipse.jdt.internal.compiler.lookup.WildcardBinding;
50
51 /**
52  * Creates javax.lang.model wrappers around JDT internal compiler bindings.
53  */

54 public class Factory {
55     
56     // using auto-boxing to take advantage of caching, if any.
57
// the dummy value picked here falls within the caching range.
58
public static final Byte JavaDoc DUMMY_BYTE = 0;
59     public static final Character JavaDoc DUMMY_CHAR = '0';
60     public static final Double JavaDoc DUMMY_DOUBLE = 0d;
61     public static final Float JavaDoc DUMMY_FLOAT = 0f;
62     public static final Integer JavaDoc DUMMY_INTEGER = 0;
63     public static final Long JavaDoc DUMMY_LONG = 0l;
64     public static final Short JavaDoc DUMMY_SHORT = 0;
65
66     private final BaseProcessingEnvImpl _env;
67     
68     /**
69      * This object should only be constructed by the BaseProcessingEnvImpl.
70      */

71     public Factory(BaseProcessingEnvImpl env) {
72         _env = env;
73     }
74
75     /**
76      * Convert an array of compiler annotation bindings into a list of AnnotationMirror
77      * @return a non-null, possibly empty, unmodifiable list.
78      */

79     public List JavaDoc<? extends AnnotationMirror> getAnnotationMirrors(AnnotationBinding[] annotations) {
80         if (null == annotations || 0 == annotations.length) {
81             return Collections.emptyList();
82         }
83         List JavaDoc<AnnotationMirror> list = new ArrayList JavaDoc<AnnotationMirror>(annotations.length);
84         for (AnnotationBinding annotation : annotations) {
85             if (annotation == null) continue;
86             list.add(newAnnotationMirror(annotation));
87         }
88         return Collections.unmodifiableList(list);
89     }
90     
91     private static void appendModifier(Set JavaDoc<Modifier> result, int modifiers, int modifierConstant, Modifier modifier) {
92         if ((modifiers & modifierConstant) != 0) {
93             result.add(modifier);
94         }
95     }
96     
97     private static void decodeModifiers(Set JavaDoc<Modifier> result, int modifiers, int[] checkBits) {
98         if (checkBits == null) return;
99         for (int i = 0, max = checkBits.length; i < max; i++) {
100             switch(checkBits[i]) {
101                 case ClassFileConstants.AccPublic :
102                     appendModifier(result, modifiers, checkBits[i], Modifier.PUBLIC);
103                     break;
104                 case ClassFileConstants.AccProtected:
105                     appendModifier(result, modifiers, checkBits[i], Modifier.PROTECTED);
106                     break;
107                 case ClassFileConstants.AccPrivate :
108                     appendModifier(result, modifiers, checkBits[i], Modifier.PRIVATE);
109                     break;
110                 case ClassFileConstants.AccAbstract :
111                     appendModifier(result, modifiers, checkBits[i], Modifier.ABSTRACT);
112                     break;
113                 case ClassFileConstants.AccStatic :
114                     appendModifier(result, modifiers, checkBits[i], Modifier.STATIC);
115                     break;
116                 case ClassFileConstants.AccFinal :
117                     appendModifier(result, modifiers, checkBits[i], Modifier.FINAL);
118                     break;
119                 case ClassFileConstants.AccSynchronized :
120                     appendModifier(result, modifiers, checkBits[i], Modifier.SYNCHRONIZED);
121                     break;
122                 case ClassFileConstants.AccNative :
123                     appendModifier(result, modifiers, checkBits[i], Modifier.NATIVE);
124                     break;
125                 case ClassFileConstants.AccStrictfp :
126                     appendModifier(result, modifiers, checkBits[i], Modifier.STRICTFP);
127                     break;
128                 case ClassFileConstants.AccTransient :
129                     appendModifier(result, modifiers, checkBits[i], Modifier.TRANSIENT);
130                     break;
131                 case ClassFileConstants.AccVolatile :
132                     appendModifier(result, modifiers, checkBits[i], Modifier.VOLATILE);
133                     break;
134             }
135         }
136     }
137     
138     public static Object JavaDoc getMatchingDummyValue(final Class JavaDoc<?> expectedType){
139         if( expectedType.isPrimitive() ){
140             if(expectedType == boolean.class)
141                 return Boolean.FALSE;
142             else if( expectedType == byte.class )
143                 return DUMMY_BYTE;
144             else if( expectedType == char.class )
145                 return DUMMY_CHAR;
146             else if( expectedType == double.class)
147                 return DUMMY_DOUBLE;
148             else if( expectedType == float.class )
149                 return DUMMY_FLOAT;
150             else if( expectedType == int.class )
151                 return DUMMY_INTEGER;
152             else if( expectedType == long.class )
153                 return DUMMY_LONG;
154             else if(expectedType == short.class)
155                 return DUMMY_SHORT;
156             else // expectedType == void.class. can this happen?
157
return DUMMY_INTEGER; // anything would work
158
}
159         else
160             return null;
161     }
162     
163     public static Set JavaDoc<Modifier> getModifiers(int modifiers, ElementKind kind) {
164         return getModifiers(modifiers, kind, false);
165     }
166     /**
167      * Convert from the JDT's ClassFileConstants flags to the Modifier enum.
168      */

169     public static Set JavaDoc<Modifier> getModifiers(int modifiers, ElementKind kind, boolean isFromBinary)
170     {
171         EnumSet JavaDoc<Modifier> result = EnumSet.noneOf(Modifier.class);
172         switch(kind) {
173             case CONSTRUCTOR :
174             case METHOD :
175                 // modifiers for methods
176
decodeModifiers(result, modifiers, new int[] {
177                     ClassFileConstants.AccPublic,
178                     ClassFileConstants.AccProtected,
179                     ClassFileConstants.AccPrivate,
180                     ClassFileConstants.AccAbstract,
181                     ClassFileConstants.AccStatic,
182                     ClassFileConstants.AccFinal,
183                     ClassFileConstants.AccSynchronized,
184                     ClassFileConstants.AccNative,
185                     ClassFileConstants.AccStrictfp
186                 });
187                 break;
188             case FIELD :
189             case ENUM_CONSTANT :
190                 // for fields
191
decodeModifiers(result, modifiers, new int[] {
192                     ClassFileConstants.AccPublic,
193                     ClassFileConstants.AccProtected,
194                     ClassFileConstants.AccPrivate,
195                     ClassFileConstants.AccStatic,
196                     ClassFileConstants.AccFinal,
197                     ClassFileConstants.AccTransient,
198                     ClassFileConstants.AccVolatile
199                 });
200                 break;
201             case ENUM :
202                 if (isFromBinary) {
203                     decodeModifiers(result, modifiers, new int[] {
204                         ClassFileConstants.AccPublic,
205                         ClassFileConstants.AccProtected,
206                         ClassFileConstants.AccFinal,
207                         ClassFileConstants.AccPrivate,
208                         ClassFileConstants.AccAbstract,
209                         ClassFileConstants.AccStatic,
210                         ClassFileConstants.AccStrictfp
211                     });
212                 } else {
213                     // enum from source cannot be explicitly abstract
214
decodeModifiers(result, modifiers, new int[] {
215                         ClassFileConstants.AccPublic,
216                         ClassFileConstants.AccProtected,
217                         ClassFileConstants.AccFinal,
218                         ClassFileConstants.AccPrivate,
219                         ClassFileConstants.AccStatic,
220                         ClassFileConstants.AccStrictfp
221                     });
222                 }
223                 break;
224             case ANNOTATION_TYPE :
225             case INTERFACE :
226             case CLASS :
227                 // for type
228
decodeModifiers(result, modifiers, new int[] {
229                     ClassFileConstants.AccPublic,
230                     ClassFileConstants.AccProtected,
231                     ClassFileConstants.AccAbstract,
232                     ClassFileConstants.AccFinal,
233                     ClassFileConstants.AccPrivate,
234                     ClassFileConstants.AccStatic,
235                     ClassFileConstants.AccStrictfp
236                 });
237         }
238         return Collections.unmodifiableSet(result);
239     }
240
241     public AnnotationMirror newAnnotationMirror(AnnotationBinding binding)
242     {
243         return new AnnotationMirrorImpl(_env, binding);
244     }
245     
246     public Element newElement(Binding binding) {
247         if (binding == null) {
248             return new ErrorTypeElement(this._env);
249         }
250         switch (binding.kind()) {
251         case Binding.FIELD:
252         case Binding.LOCAL:
253         case Binding.VARIABLE:
254             return new VariableElementImpl(_env, (VariableBinding) binding);
255         case Binding.TYPE:
256         case Binding.GENERIC_TYPE:
257             ReferenceBinding referenceBinding = (ReferenceBinding)binding;
258             if (referenceBinding.sourceName == TypeConstants.PACKAGE_INFO_NAME) {
259                 return new PackageElementImpl(_env, referenceBinding.fPackage);
260             }
261             return new TypeElementImpl(_env, referenceBinding);
262         case Binding.METHOD:
263             return new ExecutableElementImpl(_env, (MethodBinding)binding);
264         case Binding.RAW_TYPE:
265         case Binding.PARAMETERIZED_TYPE:
266             return new TypeElementImpl(_env, ((ParameterizedTypeBinding)binding).genericType());
267         case Binding.PACKAGE:
268             return new PackageElementImpl(_env, (PackageBinding)binding);
269         case Binding.TYPE_PARAMETER:
270             return new TypeParameterElementImpl(_env, (TypeVariableBinding)binding);
271         // TODO: fill in the rest of these
272
case Binding.IMPORT:
273         case Binding.ARRAY_TYPE:
274         case Binding.BASE_TYPE:
275         case Binding.WILDCARD_TYPE:
276             throw new UnsupportedOperationException JavaDoc("NYI: binding type " + binding.kind()); //$NON-NLS-1$
277
}
278         return null;
279     }
280     
281     public DeclaredType newDeclaredType(ReferenceBinding binding) {
282         if (binding.kind() == Binding.WILDCARD_TYPE) {
283             // JDT wildcard binding is a subclass of reference binding, but in JSR269 they're siblings
284
throw new IllegalArgumentException JavaDoc("A wildcard binding can't be turned into a DeclaredType"); //$NON-NLS-1$
285
}
286         return new DeclaredTypeImpl(_env, binding);
287     }
288
289     /**
290      * Convenience method - equivalent to {@code (PackageElement)Factory.newElement(binding)}
291      */

292     public PackageElement newPackageElement(PackageBinding binding)
293     {
294         return new PackageElementImpl(_env, binding);
295     }
296     
297     public NullType getNullType() {
298         return NoTypeImpl.NULL_TYPE;
299     }
300
301     public NoType getNoType(TypeKind kind)
302     {
303         switch (kind) {
304         case NONE:
305             return NoTypeImpl.NO_TYPE_NONE;
306         case VOID:
307             return NoTypeImpl.NO_TYPE_VOID;
308         case PACKAGE:
309             return NoTypeImpl.NO_TYPE_PACKAGE;
310         default:
311             throw new IllegalArgumentException JavaDoc();
312         }
313     }
314
315     /**
316      * Get a type mirror object representing the specified primitive type kind.
317      * @throw IllegalArgumentException if a non-primitive TypeKind is requested
318      */

319     public PrimitiveTypeImpl getPrimitiveType(TypeKind kind)
320     {
321         switch (kind) {
322         case BOOLEAN:
323             return PrimitiveTypeImpl.BOOLEAN;
324         case BYTE:
325             return PrimitiveTypeImpl.BYTE;
326         case CHAR:
327             return PrimitiveTypeImpl.CHAR;
328         case DOUBLE:
329             return PrimitiveTypeImpl.DOUBLE;
330         case FLOAT:
331             return PrimitiveTypeImpl.FLOAT;
332         case INT:
333             return PrimitiveTypeImpl.INT;
334         case LONG:
335             return PrimitiveTypeImpl.LONG;
336         case SHORT:
337             return PrimitiveTypeImpl.SHORT;
338         default:
339             throw new IllegalStateException JavaDoc();
340         }
341     }
342     
343     /**
344      * Convenience method to get the PrimitiveTypeImpl corresponding to a particular BaseTypeBinding.
345      */

346     public PrimitiveTypeImpl getPrimitiveType(BaseTypeBinding binding) {
347         return getPrimitiveType(PrimitiveTypeImpl.getKind(binding));
348     }
349
350     /**
351      * Given a binding of uncertain type, try to create the right sort of TypeMirror for it.
352      */

353     public TypeMirror newTypeMirror(Binding binding) {
354         switch (binding.kind()) {
355         case Binding.FIELD:
356         case Binding.LOCAL:
357         case Binding.VARIABLE:
358             // For variables, return the type of the variable
359
return newTypeMirror(((VariableBinding)binding).type);
360             
361         case Binding.PACKAGE:
362             return getNoType(TypeKind.PACKAGE);
363             
364         case Binding.IMPORT:
365             throw new UnsupportedOperationException JavaDoc("NYI: import type " + binding.kind()); //$NON-NLS-1$
366

367         case Binding.METHOD:
368             return new ExecutableTypeImpl(_env, (MethodBinding) binding);
369             
370         case Binding.TYPE:
371         case Binding.RAW_TYPE:
372         case Binding.GENERIC_TYPE:
373         case Binding.PARAMETERIZED_TYPE:
374             return new DeclaredTypeImpl(_env, (ReferenceBinding)binding);
375             
376         case Binding.ARRAY_TYPE:
377             return new ArrayTypeImpl(_env, (ArrayBinding)binding);
378             
379         case Binding.BASE_TYPE:
380             BaseTypeBinding btb = (BaseTypeBinding)binding;
381             switch (btb.id) {
382             case TypeIds.T_void:
383                 return getNoType(TypeKind.VOID);
384             case TypeIds.T_null:
385                 return getNullType();
386             default:
387                 return getPrimitiveType(PrimitiveTypeImpl.getKind((BaseTypeBinding)binding));
388             }
389
390         case Binding.WILDCARD_TYPE:
391             return new WildcardTypeImpl(_env, (WildcardBinding) binding);
392
393         case Binding.TYPE_PARAMETER:
394             return new TypeVariableImpl(_env, (TypeVariableBinding) binding);
395         }
396         return null;
397     }
398
399     /**
400      * @param declaringElement the class, method, etc. that is parameterized by this parameter.
401      */

402     public TypeParameterElement newTypeParameterElement(TypeVariableBinding variable, Element declaringElement)
403     {
404         return new TypeParameterElementImpl(_env, variable, declaringElement);
405     }
406
407     public ErrorType getErrorType() {
408         return new ErrorTypeImpl(this._env);
409     }
410
411     /**
412      * This method is derived from code in org.eclipse.jdt.apt.core.
413      *
414      * This method is designed to be invoked by the invocation handler and anywhere that requires
415      * a AnnotationValue (AnnotationMirror member values and default values from annotation member).
416      *
417      * Regardless of the path, there are common primitive type conversion that needs to take place.
418      * The type conversions respect the type widening and narrowing rules from JLS 5.1.2 and 5.1.2.
419      *
420      * The only question remains is what is the type of the return value when the type conversion fails?
421      * When <code>avoidReflectException</code> is set to <code>true</code>
422      * Return <code>false</code> if the expected type is <code>boolean</code>
423      * Return numeric 0 for all numeric primitive types and '0' for <code>char</code>
424      *
425      * Otherwise:
426      * Return the value unchanged.
427      *
428      * In the invocation handler case:
429      * The value returned by {@link java.lang.reflect.InvocationHandler#invoke}
430      * will be converted into the expected type by the {@link java.lang.reflect.Proxy}.
431      * If the value and the expected type does not agree, and the value is not null,
432      * a ClassCastException will be thrown. A NullPointerException will result if the
433      * expected type is a primitive type and the value is null.
434      * This behavior causes annotation processors a lot of pain and the decision is
435      * to not throw such unchecked exception. In the case where a ClassCastException or
436      * NullPointerException will be thrown return some dummy value. Otherwise, return
437      * the original value.
438      * Chosen dummy values:
439      * Return <code>false</code> if the expected type is <code>boolean</code>
440      * Return numeric 0 for all numeric primitive types and '0' for <code>char</code>
441      *
442      * This behavior is triggered by setting <code>avoidReflectException</code> to <code>true</code>
443      *
444      * Note: the new behavior deviates from what's documented in
445      * {@link java.lang.reflect.InvocationHandler#invoke} and also deviates from
446      * Sun's implementation.
447      *
448      * @param value the current value from the annotation instance.
449      * @param expectedType the expected type of the value.
450      *
451      */

452     public static Object JavaDoc performNecessaryPrimitiveTypeConversion(
453             final Class JavaDoc<?> expectedType,
454             final Object JavaDoc value,
455             final boolean avoidReflectException)
456     {
457         assert expectedType.isPrimitive() : "expectedType is not a primitive type: " + expectedType.getName(); //$NON-NLS-1$
458
if( value == null)
459             return avoidReflectException ? getMatchingDummyValue(expectedType) : null;
460         // apply widening conversion based on JLS 5.1.2 and 5.1.3
461
final String JavaDoc typeName = expectedType.getName();
462         final char expectedTypeChar = typeName.charAt(0);
463         final int nameLen = typeName.length();
464         // widening byte -> short, int, long, float or double
465
// narrowing byte -> char
466
if( value instanceof Byte JavaDoc )
467         {
468             final byte b = ((Byte JavaDoc)value).byteValue();
469             switch( expectedTypeChar )
470             {
471             case 'b':
472                 if(nameLen == 4) // byte
473
return value; // exact match.
474
else
475                     return avoidReflectException ? Boolean.FALSE : value;
476             case 'c':
477                 return new Character JavaDoc((char)b); // narrowing.
478
case 'd':
479                 return new Double JavaDoc(b); // widening.
480
case 'f':
481                 return new Float JavaDoc(b); // widening.
482
case 'i':
483                 return new Integer JavaDoc(b); // widening.
484
case 'l':
485                 return new Long JavaDoc(b); // widening.
486
case 's':
487                 return new Short JavaDoc(b); // widening.
488
default:
489                 throw new IllegalStateException JavaDoc("unknown type " + expectedTypeChar); //$NON-NLS-1$
490
}
491         }
492         // widening short -> int, long, float, or double
493
// narrowing short -> byte or char
494
else if( value instanceof Short JavaDoc )
495         {
496             final short s = ((Short JavaDoc)value).shortValue();
497             switch( expectedTypeChar )
498             {
499             case 'b':
500                 if(nameLen == 4) // byte
501
return new Byte JavaDoc((byte)s); // narrowing.
502
else
503                     return avoidReflectException ? Boolean.FALSE : value; // completely wrong.
504
case 'c':
505                 return new Character JavaDoc((char)s); // narrowing.
506
case 'd':
507                 return new Double JavaDoc(s); // widening.
508
case 'f':
509                 return new Float JavaDoc(s); // widening.
510
case 'i':
511                 return new Integer JavaDoc(s); // widening.
512
case 'l':
513                 return new Long JavaDoc(s); // widening.
514
case 's':
515                 return value; // exact match
516
default:
517                 throw new IllegalStateException JavaDoc("unknown type " + expectedTypeChar); //$NON-NLS-1$
518
}
519         }
520         // widening char -> int, long, float, or double
521
// narrowing char -> byte or short
522
else if( value instanceof Character JavaDoc )
523         {
524             final char c = ((Character JavaDoc)value).charValue();
525             switch( expectedTypeChar )
526             {
527             case 'b':
528                 if(nameLen == 4) // byte
529
return new Byte JavaDoc((byte)c); // narrowing.
530
else
531                     return avoidReflectException ? Boolean.FALSE : value; // completely wrong.
532
case 'c':
533                 return value; // exact match
534
case 'd':
535                 return new Double JavaDoc(c); // widening.
536
case 'f':
537                 return new Float JavaDoc(c); // widening.
538
case 'i':
539                 return new Integer JavaDoc(c); // widening.
540
case 'l':
541                 return new Long JavaDoc(c); // widening.
542
case 's':
543                 return new Short JavaDoc((short)c); // narrowing.
544
default:
545                 throw new IllegalStateException JavaDoc("unknown type " + expectedTypeChar); //$NON-NLS-1$
546
}
547         }
548         
549         // widening int -> long, float, or double
550
// narrowing int -> byte, short, or char
551
else if( value instanceof Integer JavaDoc )
552         {
553             final int i = ((Integer JavaDoc)value).intValue();
554             switch( expectedTypeChar )
555             {
556             case 'b':
557                 if(nameLen == 4) // byte
558
return new Byte JavaDoc((byte)i); // narrowing.
559
else
560                     return avoidReflectException ? Boolean.FALSE : value; // completely wrong.
561
case 'c':
562                 return new Character JavaDoc((char)i); // narrowing
563
case 'd':
564                 return new Double JavaDoc(i); // widening.
565
case 'f':
566                 return new Float JavaDoc(i); // widening.
567
case 'i':
568                 return value; // exact match
569
case 'l':
570                 return new Long JavaDoc(i); // widening.
571
case 's':
572                 return new Short JavaDoc((short)i); // narrowing.
573
default:
574                 throw new IllegalStateException JavaDoc("unknown type " + expectedTypeChar); //$NON-NLS-1$
575
}
576         }
577         // widening long -> float or double
578
else if( value instanceof Long JavaDoc )
579         {
580             final long l = ((Long JavaDoc)value).longValue();
581             switch( expectedTypeChar )
582             {
583             case 'b': // both byte and boolean
584
case 'c':
585             case 'i':
586             case 's':
587                 // completely wrong.
588
return avoidReflectException ? getMatchingDummyValue(expectedType) : value;
589             case 'd':
590                 return new Double JavaDoc(l); // widening.
591
case 'f':
592                 return new Float JavaDoc(l); // widening.
593
case 'l':
594                 return value; // exact match.
595

596             default:
597                 throw new IllegalStateException JavaDoc("unknown type " + expectedTypeChar); //$NON-NLS-1$
598
}
599         }
600         
601         // widening float -> double
602
else if( value instanceof Float JavaDoc )
603         {
604             final float f = ((Float JavaDoc)value).floatValue();
605             switch( expectedTypeChar )
606             {
607             case 'b': // both byte and boolean
608
case 'c':
609             case 'i':
610             case 's':
611             case 'l':
612                 // completely wrong.
613
return avoidReflectException ? getMatchingDummyValue(expectedType) : value;
614             case 'd':
615                 return new Double JavaDoc(f); // widening.
616
case 'f':
617                 return value; // exact match.
618
default:
619                 throw new IllegalStateException JavaDoc("unknown type " + expectedTypeChar); //$NON-NLS-1$
620
}
621         }
622         else if( value instanceof Double JavaDoc ){
623             if(expectedTypeChar == 'd' )
624                 return value; // exact match
625
else{
626                 return avoidReflectException ? getMatchingDummyValue(expectedType) : value; // completely wrong.
627
}
628         }
629         else if( value instanceof Boolean JavaDoc ){
630             if( expectedTypeChar == 'b' && nameLen == 7) // "boolean".length() == 7
631
return value;
632             else
633                 return avoidReflectException ? getMatchingDummyValue(expectedType) : value; // completely wrong.
634
}
635         else // can't convert
636
return avoidReflectException ? getMatchingDummyValue(expectedType) : value;
637     }
638
639     /**
640      * Set an element of an array to the appropriate dummy value type
641      * @param array
642      * @param i
643      * @param expectedLeafType
644      */

645     public static void setArrayMatchingDummyValue(Object JavaDoc array, int i, Class JavaDoc<?> expectedLeafType)
646     {
647         if (boolean.class.equals(expectedLeafType)) {
648             Array.setBoolean(array, i, false);
649         }
650         else if (byte.class.equals(expectedLeafType)) {
651             Array.setByte(array, i, DUMMY_BYTE);
652         }
653         else if (char.class.equals(expectedLeafType)) {
654             Array.setChar(array, i, DUMMY_CHAR);
655         }
656         else if (double.class.equals(expectedLeafType)) {
657             Array.setDouble(array, i, DUMMY_DOUBLE);
658         }
659         else if (float.class.equals(expectedLeafType)) {
660             Array.setFloat(array, i, DUMMY_FLOAT);
661         }
662         else if (int.class.equals(expectedLeafType)) {
663             Array.setInt(array, i, DUMMY_INTEGER);
664         }
665         else if (long.class.equals(expectedLeafType)) {
666             Array.setLong(array, i, DUMMY_LONG);
667         }
668         else if (short.class.equals(expectedLeafType)) {
669             Array.setShort(array, i, DUMMY_SHORT);
670         }
671         else {
672             Array.set(array, i, null);
673         }
674     }
675     
676 }
677
Popular Tags