rt/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/reflect/AnnotationImpl.java
2 * Back 2 Browser Bytecode Translator
3 * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, version 2 of the License.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. Look for COPYING file in the top folder.
16 * If not, see http://opensource.org/licenses/GPL-2.0.
18 package org.apidesign.bck2brwsr.emul.reflect;
20 import java.lang.annotation.Annotation;
21 import java.lang.reflect.Method;
22 import java.lang.reflect.Modifier;
23 import org.apidesign.bck2brwsr.core.JavaScriptBody;
27 * @author Jaroslav Tulach <jtulach@netbeans.org>
29 public final class AnnotationImpl implements Annotation {
30 private final Class<? extends Annotation> type;
32 public AnnotationImpl(Class<? extends Annotation> type) {
36 public Class<? extends Annotation> annotationType() {
40 @JavaScriptBody(args = { "a", "n", "arr", "values" }, body = ""
41 + "function r(anno, val, prop, m) {\n"
42 + " var v = val[prop];\n"
43 + " if (typeof v === 'undefined') {\n"
44 + " var cls = anno['fld_org_apidesign_bck2brwsr_emul_reflect_AnnotationImpl_type'].cnstr;\n"
45 + " v = cls.prototype[m]();\n"
49 + "function f(val, prop, clazz, m) {\n"
50 + " return function() {\n"
51 + " if (clazz == null) return r(this, val, prop, m);\n"
52 + " if (clazz.isArray__Z()) {\n"
53 + " var valarr = r(this, val, prop, m);\n"
54 + " var cmp = clazz.getComponentType__Ljava_lang_Class_2();\n"
55 + " var retarr = vm.java_lang_reflect_Array(false).newInstance__Ljava_lang_Object_2Ljava_lang_Class_2I(cmp, valarr.length);\n"
56 + " for (var i = 0; i < valarr.length; i++) {\n"
57 + " retarr[i] = CLS.prototype.c__Ljava_lang_Object_2Ljava_lang_Class_2Ljava_lang_Object_2(cmp, valarr[i]);\n"
61 + " return CLS.prototype.c__Ljava_lang_Object_2Ljava_lang_Class_2Ljava_lang_Object_2(clazz, r(this, val, prop, m));\n"
64 + "for (var i = 0; i < arr.length; i += 3) {\n"
65 + " var m = arr[i];\n"
66 + " var p = arr[i + 1];\n"
67 + " var c = arr[i + 2];\n"
68 + " a[m] = f(values, p, c, m);\n"
70 + "a['$instOf_' + n] = true;\n"
73 private static native <T extends Annotation> T create(
74 AnnotationImpl a, String n, Object[] methodsAndProps, Object values
77 private static Object c(Class<? extends Annotation> a, Object v) {
81 public static <T extends Annotation> T create(Class<T> annoClass, Object values) {
82 return create(new AnnotationImpl(annoClass),
83 annoClass.getName().replace('.', '_'),
84 findProps(annoClass), values
88 public static Annotation[] create(Object anno) {
89 String[] names = findNames(anno);
90 Annotation[] ret = new Annotation[names.length];
91 for (int i = 0; i < names.length; i++) {
92 String annoNameSlash = names[i].substring(1, names[i].length() - 1);
93 Class<? extends Annotation> annoClass;
95 annoClass = (Class<? extends Annotation>)Class.forName(annoNameSlash.replace('/', '.'));
96 } catch (ClassNotFoundException ex) {
97 throw new IllegalStateException("Can't find annotation class " + annoNameSlash);
100 new AnnotationImpl(annoClass),
101 annoNameSlash.replace('/', '_'),
102 findProps(annoClass),
103 findData(anno, names[i])
108 @JavaScriptBody(args = "anno", body =
109 "var arr = new Array();"
110 + "var props = Object.getOwnPropertyNames(anno);\n"
111 + "for (var i = 0; i < props.length; i++) {\n"
112 + " var p = props[i];\n"
117 private static native String[] findNames(Object anno);
119 @JavaScriptBody(args={ "anno", "p"}, body="return anno[p];")
120 private static native Object findData(Object anno, String p);
122 private static Object[] findProps(Class<?> annoClass) {
123 final Method[] marr = MethodImpl.findMethods(annoClass, Modifier.PUBLIC);
124 Object[] arr = new Object[marr.length * 3];
126 for (Method m : marr) {
127 arr[pos++] = MethodImpl.toSignature(m);
128 arr[pos++] = m.getName();
129 final Class<?> rt = m.getReturnType();
131 arr[pos++] = rt.getComponentType().isAnnotation() ? rt : null;
133 arr[pos++] = rt.isAnnotation() ? rt : null;