Source Code Cross Referenced for AnnotationMirrorImpl.java in  » IDE-Eclipse » jdt » org » eclipse » jdt » internal » compiler » apt » model » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Eclipse » jdt » org.eclipse.jdt.internal.compiler.apt.model 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*******************************************************************************
002:         * Copyright (c) 2005, 2007 IBM Corporation and others.
003:         * All rights reserved. This program and the accompanying materials
004:         * are made available under the terms of the Eclipse Public License v1.0
005:         * which accompanies this distribution, and is available at
006:         * http://www.eclipse.org/legal/epl-v10.html
007:         *
008:         * Contributors:
009:         *     IBM Corporation - initial API and implementation
010:         *******************************************************************************/package org.eclipse.jdt.internal.compiler.apt.model;
011:
012:        import java.lang.reflect.Array;
013:        import java.lang.reflect.Field;
014:        import java.lang.reflect.InvocationHandler;
015:        import java.lang.reflect.Method;
016:        import java.lang.reflect.Proxy;
017:        import java.util.ArrayList;
018:        import java.util.Collections;
019:        import java.util.HashMap;
020:        import java.util.List;
021:        import java.util.Map;
022:
023:        import javax.lang.model.element.AnnotationMirror;
024:        import javax.lang.model.element.AnnotationValue;
025:        import javax.lang.model.element.ExecutableElement;
026:        import javax.lang.model.type.DeclaredType;
027:        import javax.lang.model.type.MirroredTypeException;
028:        import javax.lang.model.type.MirroredTypesException;
029:        import javax.lang.model.type.TypeMirror;
030:
031:        import org.eclipse.jdt.internal.compiler.apt.dispatch.BaseProcessingEnvImpl;
032:        import org.eclipse.jdt.internal.compiler.impl.Constant;
033:        import org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding;
034:        import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
035:        import org.eclipse.jdt.internal.compiler.lookup.ElementValuePair;
036:        import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
037:        import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
038:        import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
039:        import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
040:        import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
041:
042:        public class AnnotationMirrorImpl implements  AnnotationMirror,
043:                InvocationHandler {
044:
045:            public final BaseProcessingEnvImpl _env;
046:            public final AnnotationBinding _binding;
047:
048:            /* package */AnnotationMirrorImpl(BaseProcessingEnvImpl env,
049:                    AnnotationBinding binding) {
050:                _env = env;
051:                _binding = binding;
052:            }
053:
054:            @Override
055:            public boolean equals(Object obj) {
056:                if (obj instanceof  AnnotationMirrorImpl) {
057:                    if (this ._binding == null) {
058:                        return ((AnnotationMirrorImpl) obj)._binding == null;
059:                    }
060:                    return equals(this ._binding,
061:                            ((AnnotationMirrorImpl) obj)._binding);
062:                }
063:                return false;
064:            }
065:
066:            private static boolean equals(AnnotationBinding annotationBinding,
067:                    AnnotationBinding annotationBinding2) {
068:                if (annotationBinding.getAnnotationType() != annotationBinding2
069:                        .getAnnotationType())
070:                    return false;
071:                final ElementValuePair[] elementValuePairs = annotationBinding
072:                        .getElementValuePairs();
073:                final ElementValuePair[] elementValuePairs2 = annotationBinding2
074:                        .getElementValuePairs();
075:                final int length = elementValuePairs.length;
076:                if (length != elementValuePairs2.length)
077:                    return false;
078:                loop: for (int i = 0; i < length; i++) {
079:                    ElementValuePair pair = elementValuePairs[i];
080:                    // loop on the given pair to make sure one will match
081:                    for (int j = 0; j < length; j++) {
082:                        ElementValuePair pair2 = elementValuePairs2[j];
083:                        if (pair.binding == pair2.binding) {
084:                            if (pair.value == null) {
085:                                if (pair2.value == null) {
086:                                    continue loop;
087:                                }
088:                                return false;
089:                            } else {
090:                                if (pair2.value == null
091:                                        || !pair2.value.equals(pair.value)) {
092:                                    return false;
093:                                }
094:                            }
095:                            continue loop;
096:                        }
097:                    }
098:                    return false;
099:                }
100:                return true;
101:            }
102:
103:            public DeclaredType getAnnotationType() {
104:                if (this ._binding == null) {
105:                    return _env.getFactory().getErrorType();
106:                }
107:                ReferenceBinding annoType = _binding.getAnnotationType();
108:                return _env.getFactory().newDeclaredType(annoType);
109:            }
110:
111:            /**
112:             * @return all the members of this annotation mirror that have explicit values.
113:             * Default values are not included.
114:             */
115:            public Map<? extends ExecutableElement, ? extends AnnotationValue> getElementValues() {
116:                if (this ._binding == null) {
117:                    return Collections.emptyMap();
118:                }
119:                ElementValuePair[] pairs = _binding.getElementValuePairs();
120:                Map<ExecutableElement, AnnotationValue> valueMap = new HashMap<ExecutableElement, AnnotationValue>(
121:                        pairs.length);
122:                for (ElementValuePair pair : pairs) {
123:                    MethodBinding method = pair.getMethodBinding();
124:                    if (method == null) {
125:                        // ideally we should be able to create a fake ExecuableElementImpl
126:                        continue;
127:                    }
128:                    ExecutableElement e = new ExecutableElementImpl(_env,
129:                            method);
130:                    AnnotationValue v = new AnnotationValueImpl(_env, pair
131:                            .getValue(), method.returnType);
132:                    valueMap.put(e, v);
133:                }
134:                return Collections.unmodifiableMap(valueMap);
135:            }
136:
137:            /**
138:             * {@see Elements#getElementValuesWithDefaults()}
139:             * @return all the members of this annotation mirror that have explicit or default
140:             * values.
141:             */
142:            public Map<? extends ExecutableElement, ? extends AnnotationValue> getElementValuesWithDefaults() {
143:                if (this ._binding == null) {
144:                    return Collections.emptyMap();
145:                }
146:                ElementValuePair[] pairs = _binding.getElementValuePairs();
147:                ReferenceBinding annoType = _binding.getAnnotationType();
148:                Map<ExecutableElement, AnnotationValue> valueMap = new HashMap<ExecutableElement, AnnotationValue>();
149:                for (MethodBinding method : annoType.methods()) {
150:                    // if binding is in ElementValuePair list, then get value from there
151:                    boolean foundExplicitValue = false;
152:                    for (int i = 0; i < pairs.length; ++i) {
153:                        MethodBinding explicitBinding = pairs[i]
154:                                .getMethodBinding();
155:                        if (method == explicitBinding) {
156:                            ExecutableElement e = new ExecutableElementImpl(
157:                                    _env, explicitBinding);
158:                            AnnotationValue v = new AnnotationValueImpl(_env,
159:                                    pairs[i].getValue(),
160:                                    explicitBinding.returnType);
161:                            valueMap.put(e, v);
162:                            foundExplicitValue = true;
163:                            break;
164:                        }
165:                    }
166:                    // else get default value if one exists
167:                    if (!foundExplicitValue) {
168:                        Object defaultVal = method.getDefaultValue();
169:                        if (null != defaultVal) {
170:                            ExecutableElement e = new ExecutableElementImpl(
171:                                    _env, method);
172:                            AnnotationValue v = new AnnotationValueImpl(_env,
173:                                    defaultVal, method.returnType);
174:                            valueMap.put(e, v);
175:                        }
176:                    }
177:                }
178:                return Collections.unmodifiableMap(valueMap);
179:            }
180:
181:            public int hashCode() {
182:                if (this ._binding == null)
183:                    return this ._env.hashCode();
184:                return this ._binding.hashCode();
185:            }
186:
187:            /*
188:             * Used by getAnnotation(), which returns a reflective proxy of the annotation class.  When processors then
189:             * invoke methods such as value() on the annotation proxy, this method is called.
190:             * <p>
191:             * A challenge here is that the processor was not necessarily compiled against the same annotation
192:             * definition that the compiler is looking at right now, not to mention that the annotation itself
193:             * may be defective in source.  So the actual type of the value may be quite different than the
194:             * type expected by the caller, which will result in a ClassCastException, which is ugly for the
195:             * processor to try to catch.  So we try to catch and correct this type mismatch where possible.
196:             * <p>
197:             * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
198:             */
199:            @Override
200:            public Object invoke(Object proxy, Method method, Object[] args)
201:                    throws Throwable {
202:                if (this ._binding == null)
203:                    return null;
204:                final String methodName = method.getName();
205:                if (args == null || args.length == 0) {
206:                    if (methodName.equals("hashCode")) { //$NON-NLS-1$
207:                        return new Integer(hashCode());
208:                    } else if (methodName.equals("toString")) { //$NON-NLS-1$
209:                        return toString();
210:                    } else if (methodName.equals("annotationType")) { //$NON-NLS-1$
211:                        return proxy.getClass().getInterfaces()[0];
212:                    }
213:                } else if (args.length == 1 && methodName.equals("equals")) { //$NON-NLS-1$
214:                    return new Boolean(equals(args[0]));
215:                }
216:
217:                // If it's not one of the above methods, it must be an annotation member, so it cannot take any arguments
218:                if (args != null && args.length != 0) {
219:                    throw new NoSuchMethodException(
220:                            "method " + method.getName() + formatArgs(args) + " does not exist on annotation " + toString()); //$NON-NLS-1$ //$NON-NLS-2$
221:                }
222:                final MethodBinding methodBinding = getMethodBinding(methodName);
223:                if (methodBinding == null) {
224:                    throw new NoSuchMethodException(
225:                            "method " + method.getName() + "() does not exist on annotation" + toString()); //$NON-NLS-1$ //$NON-NLS-2$
226:                }
227:
228:                Object actualValue = null;
229:                boolean foundMethod = false;
230:                ElementValuePair[] pairs = _binding.getElementValuePairs();
231:                for (ElementValuePair pair : pairs) {
232:                    if (methodName.equals(new String(pair.getName()))) {
233:                        actualValue = pair.getValue();
234:                        foundMethod = true;
235:                        break;
236:                    }
237:                }
238:                if (!foundMethod) {
239:                    // couldn't find explicit value; see if there's a default
240:                    actualValue = methodBinding.getDefaultValue();
241:                }
242:                Class<?> expectedType = method.getReturnType();
243:                TypeBinding actualType = methodBinding.returnType;
244:                return getReflectionValue(actualValue, actualType, expectedType);
245:            }
246:
247:            /*
248:             * (non-Javadoc)
249:             * Sun implementation shows the values.  We avoid that here,
250:             * because getting the values is not idempotent.
251:             */
252:            @Override
253:            public String toString() {
254:                if (this ._binding == null) {
255:                    return "@any()"; //$NON-NLS-1$
256:                }
257:                return "@" + _binding.getAnnotationType().debugName(); //$NON-NLS-1$
258:            }
259:
260:            /**
261:             * Used for constructing exception message text.
262:             * @return a string like "(a, b, c)".
263:             */
264:            private String formatArgs(final Object[] args) {
265:                // estimate that each class name (plus the separators) is 10 characters long plus 2 for "()".
266:                final StringBuilder builder = new StringBuilder(
267:                        args.length * 8 + 2);
268:                builder.append('(');
269:                for (int i = 0; i < args.length; i++) {
270:                    if (i > 0)
271:                        builder.append(", "); //$NON-NLS-1$
272:                    builder.append(args[i].getClass().getName());
273:                }
274:                builder.append(')');
275:                return builder.toString();
276:            }
277:
278:            /**
279:             * Find a particular annotation member by name.
280:             * @return a compiler method binding, or null if no member was found.
281:             */
282:            private MethodBinding getMethodBinding(String name) {
283:                ReferenceBinding annoType = _binding.getAnnotationType();
284:                MethodBinding[] methods = annoType.getMethods(name
285:                        .toCharArray());
286:                for (MethodBinding method : methods) {
287:                    // annotation members have no parameters
288:                    if (method.parameters.length == 0) {
289:                        return method;
290:                    }
291:                }
292:                return null;
293:            }
294:
295:            /**
296:             * Convert an annotation member value from JDT into Reflection, and from whatever its actual type
297:             * is into whatever type the reflective invoker of a method is expecting.
298:             * <p>
299:             * Only certain types are permitted as member values.  Specifically, a member must be a constant,
300:             * and must be either a primitive type, String, Class, an enum constant, an annotation, or an
301:             * array of any of those.  Multidimensional arrays are not permitted.
302:             * 
303:             * @param annoValue the value as represented by {@link ElementValuePair#getValue()}
304:             * @param actualType the return type of the corresponding {@link MethodBinding}
305:             * @param expectedType the type that the reflective method invoker is expecting
306:             * @return an object of the expected type representing the annotation member value, 
307:             * or an appropriate dummy value (such as null) if no value is available
308:             */
309:            private Object getReflectionValue(Object actualValue,
310:                    TypeBinding actualType, Class<?> expectedType) {
311:                if (null == expectedType) {
312:                    // With no expected type, we can't even guess at a conversion
313:                    return null;
314:                }
315:                if (null == actualValue) {
316:                    // Return a type-appropriate equivalent of null
317:                    return Factory.getMatchingDummyValue(expectedType);
318:                }
319:                if (expectedType.isArray()) {
320:                    if (Class.class.equals(expectedType.getComponentType())) {
321:                        // package Class[]-valued return as a MirroredTypesException
322:                        if (actualType.isArrayType()
323:                                && actualValue instanceof  Object[]
324:                                && ((ArrayBinding) actualType).leafComponentType
325:                                        .erasure().id == TypeIds.T_JavaLangClass) {
326:                            Object[] bindings = (Object[]) actualValue;
327:                            List<TypeMirror> mirrors = new ArrayList<TypeMirror>(
328:                                    bindings.length);
329:                            for (int i = 0; i < bindings.length; ++i) {
330:                                if (bindings[i] instanceof  TypeBinding) {
331:                                    mirrors.add(_env.getFactory()
332:                                            .newTypeMirror(
333:                                                    (TypeBinding) bindings[i]));
334:                                }
335:                            }
336:                            throw new MirroredTypesException(mirrors);
337:                        }
338:                        // TODO: actual value is not a TypeBinding[].  Should we return a TypeMirror[] around an ErrorType?
339:                        return null;
340:                    }
341:                    // Handle arrays of types other than Class, e.g., int[], MyEnum[], ...
342:                    return convertJDTArrayToReflectionArray(actualValue,
343:                            actualType, expectedType);
344:                } else if (Class.class.equals(expectedType)) {
345:                    // package the Class-valued return as a MirroredTypeException
346:                    if (actualValue instanceof  TypeBinding) {
347:                        TypeMirror mirror = _env.getFactory().newTypeMirror(
348:                                (TypeBinding) actualValue);
349:                        throw new MirroredTypeException(mirror);
350:                    } else {
351:                        // TODO: actual value is not a TypeBinding.  Should we return a TypeMirror around an ErrorType?
352:                        return null;
353:                    }
354:                } else {
355:                    // Handle unitary values of type other than Class, e.g., int, MyEnum, ...
356:                    return convertJDTValueToReflectionType(actualValue,
357:                            actualType, expectedType);
358:                }
359:            }
360:
361:            /**
362:             * Convert an array of JDT types as obtained from ElementValuePair.getValue()
363:             * (e.g., an Object[] containing IntConstant elements) to the type expected by
364:             * a reflective method invocation (e.g., int[]).
365:             * <p>
366:             * This does not handle arrays of Class, but it does handle primitives, enum constants,
367:             * and types such as String.
368:             * @param jdtValue the actual value returned by ElementValuePair.getValue() or MethodBinding.getDefault()
369:             * @param jdtType the return type of the annotation method binding
370:             * @param expectedType the type that the invoker of the method is expecting; must be an array type
371:             * @return an Object which is, e.g., an int[]; or null, if an array cannot be created.
372:             */
373:            private Object convertJDTArrayToReflectionArray(Object jdtValue,
374:                    TypeBinding jdtType, Class<?> expectedType) {
375:                assert null != expectedType && expectedType.isArray();
376:                if (!jdtType.isArrayType() || !(jdtValue instanceof  Object[])) {
377:                    // TODO: wrap solo element into one-length array
378:                    return null;
379:                }
380:                TypeBinding jdtLeafType = jdtType.leafComponentType();
381:                Object[] jdtArray = (Object[]) jdtValue;
382:                Class<?> expectedLeafType = expectedType.getComponentType();
383:                final int length = jdtArray.length;
384:                final Object returnArray = Array.newInstance(expectedLeafType,
385:                        length);
386:                for (int i = 0; i < length; ++i) {
387:                    Object jdtElementValue = jdtArray[i];
388:                    if (expectedLeafType.isPrimitive()
389:                            || String.class.equals(expectedLeafType)) {
390:                        if (jdtElementValue instanceof  Constant) {
391:                            if (boolean.class.equals(expectedLeafType)) {
392:                                Array.setBoolean(returnArray, i,
393:                                        ((Constant) jdtElementValue)
394:                                                .booleanValue());
395:                            } else if (byte.class.equals(expectedLeafType)) {
396:                                Array.setByte(returnArray, i,
397:                                        ((Constant) jdtElementValue)
398:                                                .byteValue());
399:                            } else if (char.class.equals(expectedLeafType)) {
400:                                Array.setChar(returnArray, i,
401:                                        ((Constant) jdtElementValue)
402:                                                .charValue());
403:                            } else if (double.class.equals(expectedLeafType)) {
404:                                Array.setDouble(returnArray, i,
405:                                        ((Constant) jdtElementValue)
406:                                                .doubleValue());
407:                            } else if (float.class.equals(expectedLeafType)) {
408:                                Array.setFloat(returnArray, i,
409:                                        ((Constant) jdtElementValue)
410:                                                .floatValue());
411:                            } else if (int.class.equals(expectedLeafType)) {
412:                                Array
413:                                        .setInt(returnArray, i,
414:                                                ((Constant) jdtElementValue)
415:                                                        .intValue());
416:                            } else if (long.class.equals(expectedLeafType)) {
417:                                Array.setLong(returnArray, i,
418:                                        ((Constant) jdtElementValue)
419:                                                .longValue());
420:                            } else if (short.class.equals(expectedLeafType)) {
421:                                Array.setShort(returnArray, i,
422:                                        ((Constant) jdtElementValue)
423:                                                .shortValue());
424:                            } else if (String.class.equals(expectedLeafType)) {
425:                                Array.set(returnArray, i,
426:                                        ((Constant) jdtElementValue)
427:                                                .stringValue());
428:                            }
429:                        } else {
430:                            // Primitive or string is expected, but our actual value cannot be coerced into one.
431:                            // TODO: if the actual value is an array of primitives, should we unpack the first one?
432:                            Factory.setArrayMatchingDummyValue(returnArray, i,
433:                                    expectedLeafType);
434:                        }
435:                    } else if (expectedLeafType.isEnum()) {
436:                        Object returnVal = null;
437:                        if (jdtLeafType != null && jdtLeafType.isEnum()
438:                                && jdtElementValue instanceof  FieldBinding) {
439:                            FieldBinding binding = (FieldBinding) jdtElementValue;
440:                            try {
441:                                Field returnedField = null;
442:                                returnedField = expectedLeafType
443:                                        .getField(new String(binding.name));
444:                                if (null != returnedField) {
445:                                    returnVal = returnedField.get(null);
446:                                }
447:                            } catch (NoSuchFieldException nsfe) {
448:                                // return null
449:                            } catch (IllegalAccessException iae) {
450:                                // return null
451:                            }
452:                        }
453:                        Array.set(returnArray, i, returnVal);
454:                    } else if (expectedLeafType.isAnnotation()) {
455:                        // member value is expected to be an annotation type.  Wrap it in an Annotation proxy.
456:                        Object returnVal = null;
457:                        if (jdtLeafType.isAnnotationType()
458:                                && jdtElementValue instanceof  AnnotationBinding) {
459:                            AnnotationMirrorImpl annoMirror = (AnnotationMirrorImpl) _env
460:                                    .getFactory()
461:                                    .newAnnotationMirror(
462:                                            (AnnotationBinding) jdtElementValue);
463:                            returnVal = Proxy.newProxyInstance(expectedLeafType
464:                                    .getClassLoader(),
465:                                    new Class[] { expectedLeafType },
466:                                    annoMirror);
467:                        }
468:                        Array.set(returnArray, i, returnVal);
469:                    } else {
470:                        Array.set(returnArray, i, null);
471:                    }
472:                }
473:                return returnArray;
474:            }
475:
476:            /**
477:             * Convert a JDT annotation value as obtained from ElementValuePair.getValue()
478:             * (e.g., IntConstant, FieldBinding, etc.) to the type expected by a reflective
479:             * method invocation (e.g., int, an enum constant, etc.).
480:             * @return a value of type {@code expectedType}, or a dummy value of that type if
481:             * the actual value cannot be converted.
482:             */
483:            private Object convertJDTValueToReflectionType(Object jdtValue,
484:                    TypeBinding actualType, Class<?> expectedType) {
485:                if (expectedType.isPrimitive()
486:                        || String.class.equals(expectedType)) {
487:                    if (jdtValue instanceof  Constant) {
488:                        if (boolean.class.equals(expectedType)) {
489:                            return ((Constant) jdtValue).booleanValue();
490:                        } else if (byte.class.equals(expectedType)) {
491:                            return ((Constant) jdtValue).byteValue();
492:                        } else if (char.class.equals(expectedType)) {
493:                            return ((Constant) jdtValue).charValue();
494:                        } else if (double.class.equals(expectedType)) {
495:                            return ((Constant) jdtValue).doubleValue();
496:                        } else if (float.class.equals(expectedType)) {
497:                            return ((Constant) jdtValue).floatValue();
498:                        } else if (int.class.equals(expectedType)) {
499:                            return ((Constant) jdtValue).intValue();
500:                        } else if (long.class.equals(expectedType)) {
501:                            return ((Constant) jdtValue).longValue();
502:                        } else if (short.class.equals(expectedType)) {
503:                            return ((Constant) jdtValue).shortValue();
504:                        } else if (String.class.equals(expectedType)) {
505:                            return ((Constant) jdtValue).stringValue();
506:                        }
507:                    }
508:                    // Primitive or string is expected, but our actual value cannot be coerced into one.
509:                    // TODO: if the actual value is an array of primitives, should we unpack the first one?
510:                    return Factory.getMatchingDummyValue(expectedType);
511:                } else if (expectedType.isEnum()) {
512:                    Object returnVal = null;
513:                    if (actualType != null && actualType.isEnum()
514:                            && jdtValue instanceof  FieldBinding) {
515:
516:                        FieldBinding binding = (FieldBinding) jdtValue;
517:                        try {
518:                            Field returnedField = null;
519:                            returnedField = expectedType.getField(new String(
520:                                    binding.name));
521:                            if (null != returnedField) {
522:                                returnVal = returnedField.get(null);
523:                            }
524:                        } catch (NoSuchFieldException nsfe) {
525:                            // return null
526:                        } catch (IllegalAccessException iae) {
527:                            // return null
528:                        }
529:                    }
530:                    return null == returnVal ? Factory
531:                            .getMatchingDummyValue(expectedType) : returnVal;
532:                } else if (expectedType.isAnnotation()) {
533:                    // member value is expected to be an annotation type.  Wrap it in an Annotation proxy.
534:                    if (actualType.isAnnotationType()
535:                            && jdtValue instanceof  AnnotationBinding) {
536:                        AnnotationMirrorImpl annoMirror = (AnnotationMirrorImpl) _env
537:                                .getFactory().newAnnotationMirror(
538:                                        (AnnotationBinding) jdtValue);
539:                        return Proxy.newProxyInstance(expectedType
540:                                .getClassLoader(),
541:                                new Class[] { expectedType }, annoMirror);
542:                    } else {
543:                        // No way to cast a non-annotation value to an annotation type; return null to caller
544:                        return null;
545:                    }
546:                } else {
547:                    return Factory.getMatchingDummyValue(expectedType);
548:                }
549:            }
550:
551:        }
w_w__w.__j__a__v___a2_s_.__c_o___m___ | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.