summaryrefslogtreecommitdiffstats
path: root/sca-java-2.x/tags/2.0.1-RC1/modules/interface-java-jaxws/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxws/BaseBeanGenerator.java
diff options
context:
space:
mode:
Diffstat (limited to 'sca-java-2.x/tags/2.0.1-RC1/modules/interface-java-jaxws/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxws/BaseBeanGenerator.java')
-rw-r--r--sca-java-2.x/tags/2.0.1-RC1/modules/interface-java-jaxws/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxws/BaseBeanGenerator.java569
1 files changed, 569 insertions, 0 deletions
diff --git a/sca-java-2.x/tags/2.0.1-RC1/modules/interface-java-jaxws/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxws/BaseBeanGenerator.java b/sca-java-2.x/tags/2.0.1-RC1/modules/interface-java-jaxws/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxws/BaseBeanGenerator.java
new file mode 100644
index 0000000000..923d13cd5e
--- /dev/null
+++ b/sca-java-2.x/tags/2.0.1-RC1/modules/interface-java-jaxws/src/main/java/org/apache/tuscany/sca/interfacedef/java/jaxws/BaseBeanGenerator.java
@@ -0,0 +1,569 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.interfacedef.java.jaxws;
+
+import java.lang.annotation.Annotation;
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.WeakHashMap;
+
+import javax.xml.bind.annotation.XmlAttachmentRef;
+import javax.xml.bind.annotation.XmlList;
+import javax.xml.bind.annotation.XmlMimeType;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+import javax.xml.ws.Holder;
+
+import org.apache.tuscany.sca.databinding.jaxb.XMLAdapterExtensionPoint;
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+
+public abstract class BaseBeanGenerator implements Opcodes {
+ private static final Map<String, String> COLLECTION_CLASSES = new HashMap<String, String>();
+
+ static {
+ COLLECTION_CLASSES.put("Ljava/util/Collection;", "java/util/ArrayList");
+ COLLECTION_CLASSES.put("Ljava/util/List;", "java/util/ArrayList");
+ COLLECTION_CLASSES.put("Ljava/util/Set;", "java/util/HashSet");
+ COLLECTION_CLASSES.put("Ljava/util/Queue;", "java/util/LinkedList");
+ }
+ private final static Class[] KNOWN_JAXB_ANNOTATIONS =
+ {XmlAttachmentRef.class,
+ XmlMimeType.class,
+ XmlJavaTypeAdapter.class,
+ XmlList.class};
+
+ private static final Map<String, String> JAVA_KEYWORDS = new HashMap<String, String>();
+
+ static {
+ JAVA_KEYWORDS.put("abstract", "_abstract");
+ JAVA_KEYWORDS.put("assert", "_assert");
+ JAVA_KEYWORDS.put("boolean", "_boolean");
+ JAVA_KEYWORDS.put("break", "_break");
+ JAVA_KEYWORDS.put("byte", "_byte");
+ JAVA_KEYWORDS.put("case", "_case");
+ JAVA_KEYWORDS.put("catch", "_catch");
+ JAVA_KEYWORDS.put("char", "_char");
+ JAVA_KEYWORDS.put("class", "_class");
+ JAVA_KEYWORDS.put("const", "_const");
+ JAVA_KEYWORDS.put("continue", "_continue");
+ JAVA_KEYWORDS.put("default", "_default");
+ JAVA_KEYWORDS.put("do", "_do");
+ JAVA_KEYWORDS.put("double", "_double");
+ JAVA_KEYWORDS.put("else", "_else");
+ JAVA_KEYWORDS.put("extends", "_extends");
+ JAVA_KEYWORDS.put("false", "_false");
+ JAVA_KEYWORDS.put("final", "_final");
+ JAVA_KEYWORDS.put("finally", "_finally");
+ JAVA_KEYWORDS.put("float", "_float");
+ JAVA_KEYWORDS.put("for", "_for");
+ JAVA_KEYWORDS.put("goto", "_goto");
+ JAVA_KEYWORDS.put("if", "_if");
+ JAVA_KEYWORDS.put("implements", "_implements");
+ JAVA_KEYWORDS.put("import", "_import");
+ JAVA_KEYWORDS.put("instanceof", "_instanceof");
+ JAVA_KEYWORDS.put("int", "_int");
+ JAVA_KEYWORDS.put("interface", "_interface");
+ JAVA_KEYWORDS.put("long", "_long");
+ JAVA_KEYWORDS.put("native", "_native");
+ JAVA_KEYWORDS.put("new", "_new");
+ JAVA_KEYWORDS.put("null", "_null");
+ JAVA_KEYWORDS.put("package", "_package");
+ JAVA_KEYWORDS.put("private", "_private");
+ JAVA_KEYWORDS.put("protected", "_protected");
+ JAVA_KEYWORDS.put("public", "_public");
+ JAVA_KEYWORDS.put("return", "_return");
+ JAVA_KEYWORDS.put("short", "_short");
+ JAVA_KEYWORDS.put("static", "_static");
+ JAVA_KEYWORDS.put("strictfp", "_strictfp");
+ JAVA_KEYWORDS.put("super", "_super");
+ JAVA_KEYWORDS.put("switch", "_switch");
+ JAVA_KEYWORDS.put("synchronized", "_synchronized");
+ JAVA_KEYWORDS.put("this", "_this");
+ JAVA_KEYWORDS.put("throw", "_throw");
+ JAVA_KEYWORDS.put("throws", "_throws");
+ JAVA_KEYWORDS.put("transient", "_transient");
+ JAVA_KEYWORDS.put("true", "_true");
+ JAVA_KEYWORDS.put("try", "_try");
+ JAVA_KEYWORDS.put("void", "_void");
+ JAVA_KEYWORDS.put("volatile", "_volatile");
+ JAVA_KEYWORDS.put("while", "_while");
+ JAVA_KEYWORDS.put("enum", "_enum");
+ }
+
+ protected static final Map<Object, WeakReference<Class<?>>> generatedClasses =
+ Collections.synchronizedMap(new WeakHashMap<Object, WeakReference<Class<?>>>());
+
+ protected XMLAdapterExtensionPoint xmlAdapters;
+
+ public byte[] defineClass(ClassWriter cw,
+ String classDescriptor,
+ String classSignature,
+ String namespace,
+ String name,
+ BeanProperty[] properties) {
+ // Declare the class
+ declareClass(cw, classDescriptor);
+
+ // Compute the propOrder
+ String[] propOrder = null;
+ if (properties != null && properties.length > 0) {
+ int size = properties.length;
+ propOrder = new String[size];
+ for (int i = 0; i < size; i++) {
+ propOrder[i] = getFieldName(properties[i].getName());
+ }
+ }
+ // Annotate the class
+ annotateClass(cw, name, namespace, propOrder);
+
+ // Declare the default constructor
+ declareConstructor(cw, classSignature);
+ if (properties != null) {
+ for (BeanProperty p : properties) {
+ boolean isElement = p.isElement() && (!Map.class.isAssignableFrom(p.getType()));
+ String xmlAdapterClassSignature = null;
+ if (xmlAdapters != null) {
+ Class<?> adapterClass = xmlAdapters.getAdapter(p.getType());
+ if (adapterClass != null) {
+ xmlAdapterClassSignature = CodeGenerationHelper.getSignature(adapterClass);
+ }
+ }
+ declareProperty(cw, classDescriptor, classSignature, p.getName(), p.getSignature(), p
+ .getGenericSignature(), isElement, p.isNillable(), xmlAdapterClassSignature, p.getJaxbAnnotaions());
+ }
+ }
+
+ // Close the generation
+ cw.visitEnd();
+ return cw.toByteArray();
+ }
+
+ protected static boolean isHolder(java.lang.reflect.Type type) {
+ if (type instanceof ParameterizedType) {
+ Class<?> cls = CodeGenerationHelper.getErasure(type);
+ return cls == Holder.class;
+ }
+ return false;
+ }
+
+ protected static java.lang.reflect.Type getHolderValueType(java.lang.reflect.Type paramType) {
+ if (paramType instanceof ParameterizedType) {
+ ParameterizedType p = (ParameterizedType)paramType;
+ Class<?> cls = CodeGenerationHelper.getErasure(p);
+ if (cls == Holder.class) {
+ return p.getActualTypeArguments()[0];
+ }
+ }
+ return paramType;
+ }
+
+ protected void declareProperty(ClassWriter cw,
+ String classDescriptor,
+ String classSignature,
+ String propName,
+ String propClassSignature,
+ String propTypeSignature,
+ boolean isElement,
+ boolean isNillable,
+ String xmlAdapterClassSignature,
+ List<Annotation> jaxbAnnotations) {
+ if (propClassSignature.equals(propTypeSignature)) {
+ propTypeSignature = null;
+ }
+ declareField(cw,
+ propName,
+ propClassSignature,
+ propTypeSignature,
+ isElement,
+ isNillable,
+ xmlAdapterClassSignature,
+ jaxbAnnotations);
+ decalreGetter(cw, classDescriptor, classSignature, propName, propClassSignature, propTypeSignature);
+ declareSetter(cw, classDescriptor, classSignature, propName, propClassSignature, propTypeSignature);
+ }
+
+ protected String getFieldName(String propName) {
+ String name = JAVA_KEYWORDS.get(propName);
+ return name != null ? name : propName;
+ }
+
+ protected void declareField(ClassWriter cw,
+ String propName,
+ String propClassSignature,
+ String propTypeSignature,
+ boolean isElement,
+ boolean isNillable,
+ String xmlAdapterClassSignature,
+ List<Annotation> jaxbAnnotations) {
+ FieldVisitor fv;
+ AnnotationVisitor av0;
+ fv = cw.visitField(ACC_PROTECTED, getFieldName(propName), propClassSignature, propTypeSignature, null);
+
+ // For Map property, we cannot have the XmlElement annotation
+ if (isElement && xmlAdapterClassSignature == null) {
+ av0 = fv.visitAnnotation("Ljavax/xml/bind/annotation/XmlElement;", true);
+ av0.visit("name", propName);
+ av0.visit("namespace", "");
+ // TUSCANY-3283 - force not nillable if it isn't
+ if (isNillable) {
+ av0.visit("nillable", Boolean.TRUE);
+ } else {
+ av0.visit("nillable", Boolean.FALSE);
+ }
+ // FIXME:
+ // av0.visit("required", Boolean.FALSE);
+ av0.visitEnd();
+ }
+
+ if (xmlAdapterClassSignature != null) {
+ av0 = fv.visitAnnotation("Ljavax/xml/bind/annotation/XmlAnyElement;", true);
+ av0.visit("lax", Boolean.TRUE);
+ av0.visitEnd();
+ av0 = fv.visitAnnotation("Ljavax/xml/bind/annotation/adapters/XmlJavaTypeAdapter;", true);
+ av0.visit("value", org.objectweb.asm.Type.getType(xmlAdapterClassSignature));
+ av0.visitEnd();
+ }
+
+ for (Annotation ann : jaxbAnnotations) {
+ if (ann instanceof XmlMimeType) {
+ AnnotationVisitor mime = fv.visitAnnotation("Ljavax/xml/bind/annotation/XmlMimeType;", true);
+ mime.visit("value", ((XmlMimeType)ann).value());
+ mime.visitEnd();
+ } else if (ann instanceof XmlJavaTypeAdapter) {
+ AnnotationVisitor ada = fv.visitAnnotation("Ljavax/xml/bind/annotation/adapters/XmlJavaTypeAdapter;", true);
+ ada.visit("value", org.objectweb.asm.Type.getType(((XmlJavaTypeAdapter)ann).value()));
+ ada.visit("type", org.objectweb.asm.Type.getType(((XmlJavaTypeAdapter)ann).type()));
+ ada.visitEnd();
+ } else if (ann instanceof XmlAttachmentRef) {
+ AnnotationVisitor att = fv.visitAnnotation("Ljavax/xml/bind/annotation/XmlAttachmentRef;", true);
+ att.visitEnd();
+ } else if (ann instanceof XmlList) {
+ AnnotationVisitor list = fv.visitAnnotation("Ljavax/xml/bind/annotation/XmlList;", true);
+ list.visitEnd();
+ }
+ }
+
+ fv.visitEnd();
+ }
+
+ protected void declareSetter(ClassWriter cw,
+ String classDescriptor,
+ String classSignature,
+ String propName,
+ String propClassSignature,
+ String propTypeSignature) {
+ if ("Ljava/util/List;".equals(propClassSignature)) {
+ return;
+ }
+ MethodVisitor mv =
+ cw.visitMethod(ACC_PUBLIC,
+ "set" + capitalize(propName),
+ "(" + propClassSignature + ")V",
+ propTypeSignature == null ? null : "(" + propTypeSignature + ")V",
+ null);
+ mv.visitCode();
+ Label l0 = new Label();
+ mv.visitLabel(l0);
+ // mv.visitLineNumber(57, l0);
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitVarInsn(CodeGenerationHelper.getLoadOPCode(propClassSignature), 1);
+ mv.visitFieldInsn(PUTFIELD, classDescriptor, getFieldName(propName), propClassSignature);
+ Label l1 = new Label();
+ mv.visitLabel(l1);
+ // mv.visitLineNumber(58, l1);
+ mv.visitInsn(RETURN);
+ Label l2 = new Label();
+ mv.visitLabel(l2);
+ mv.visitLocalVariable("this", classSignature, null, l0, l2, 0);
+ mv.visitLocalVariable(getFieldName(propName), propClassSignature, propTypeSignature, l0, l2, 1);
+ mv.visitMaxs(3, 3);
+ mv.visitEnd();
+
+ }
+
+ protected void decalreGetter(ClassWriter cw,
+ String classDescriptor,
+ String classSignature,
+ String propName,
+ String propClassSignature,
+ String propTypeSignature) {
+ String collectionImplClass = COLLECTION_CLASSES.get(propClassSignature);
+ if (collectionImplClass != null) {
+ decalreCollectionGetter(cw,
+ classDescriptor,
+ classSignature,
+ propName,
+ propClassSignature,
+ propTypeSignature,
+ collectionImplClass);
+ return;
+ }
+
+ String getterName = ("Z".equals(propClassSignature) ? "is" : "get") + capitalize(propName);
+ MethodVisitor mv =
+ cw.visitMethod(ACC_PUBLIC, getterName, "()" + propClassSignature, propTypeSignature == null ? null
+ : "()" + propTypeSignature, null);
+ mv.visitCode();
+ Label l0 = new Label();
+ mv.visitLabel(l0);
+ // mv.visitLineNumber(48, l0);
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitFieldInsn(GETFIELD, classDescriptor, getFieldName(propName), propClassSignature);
+ mv.visitInsn(CodeGenerationHelper.getReturnOPCode(propClassSignature));
+ Label l1 = new Label();
+ mv.visitLabel(l1);
+ mv.visitLocalVariable("this", classSignature, null, l0, l1, 0);
+ mv.visitMaxs(2, 1);
+ mv.visitEnd();
+ }
+
+ protected void decalreCollectionGetter(ClassWriter cw,
+ String classDescriptor,
+ String classSignature,
+ String propName,
+ String propClassSignature,
+ String propTypeSignature,
+ String collectionImplClass) {
+ String getterName = "get" + capitalize(propName);
+ String fieldName = getFieldName(propName);
+ MethodVisitor mv =
+ cw.visitMethod(ACC_PUBLIC, getterName, "()" + propClassSignature, propTypeSignature == null ? null
+ : "()" + propTypeSignature, null);
+ mv.visitCode();
+ Label l0 = new Label();
+ mv.visitLabel(l0);
+ mv.visitLineNumber(63, l0);
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitFieldInsn(GETFIELD, classDescriptor, fieldName, propClassSignature);
+ Label l1 = new Label();
+ mv.visitJumpInsn(IFNONNULL, l1);
+ Label l2 = new Label();
+ mv.visitLabel(l2);
+ mv.visitLineNumber(64, l2);
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitTypeInsn(NEW, collectionImplClass);
+ mv.visitInsn(DUP);
+ mv.visitMethodInsn(INVOKESPECIAL, collectionImplClass, "<init>", "()V");
+ mv.visitFieldInsn(PUTFIELD, classDescriptor, fieldName, propClassSignature);
+ mv.visitLabel(l1);
+ mv.visitLineNumber(66, l1);
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitFieldInsn(GETFIELD, classDescriptor, fieldName, propClassSignature);
+ mv.visitInsn(ARETURN);
+ Label l3 = new Label();
+ mv.visitLabel(l3);
+ mv.visitLocalVariable("this", classSignature, null, l0, l3, 0);
+ mv.visitMaxs(3, 1);
+ mv.visitEnd();
+ }
+
+ protected static String capitalize(String name) {
+ if (name == null || name.length() == 0) {
+ return name;
+ } else {
+ return Character.toUpperCase(name.charAt(0)) + name.substring(1);
+ }
+ }
+
+ protected void declareConstructor(ClassWriter cw, String classSignature) {
+ MethodVisitor mv;
+ mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
+ mv.visitCode();
+ Label l0 = new Label();
+ mv.visitLabel(l0);
+ // mv.visitLineNumber(37, l0);
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
+ mv.visitInsn(RETURN);
+ Label l1 = new Label();
+ mv.visitLabel(l1);
+ mv.visitLocalVariable("this", classSignature, null, l0, l1, 0);
+ mv.visitMaxs(1, 1);
+ mv.visitEnd();
+ }
+
+ protected void declareClass(ClassWriter cw, String classDescriptor) {
+ cw.visit(V1_5, ACC_PUBLIC + ACC_SUPER, classDescriptor, null, "java/lang/Object", null);
+ }
+
+ protected void annotateClass(ClassWriter cw, String name, String namespace, String[] propOrder) {
+ AnnotationVisitor av0;
+ // @XmlRootElement
+ av0 = cw.visitAnnotation("Ljavax/xml/bind/annotation/XmlRootElement;", true);
+ av0.visit("name", name);
+ av0.visit("namespace", namespace);
+ av0.visitEnd();
+ // @XmlAccessorType
+ av0 = cw.visitAnnotation("Ljavax/xml/bind/annotation/XmlAccessorType;", true);
+ av0.visitEnum("value", "Ljavax/xml/bind/annotation/XmlAccessType;", "FIELD");
+ av0.visitEnd();
+ // @XmlType
+ av0 = cw.visitAnnotation("Ljavax/xml/bind/annotation/XmlType;", true);
+ av0.visit("name", name);
+ av0.visit("namespace", namespace);
+ if (propOrder != null) {
+ AnnotationVisitor pv = av0.visitArray("propOrder");
+ for (String p : propOrder) {
+ pv.visit(null, p);
+ }
+ pv.visitEnd();
+ }
+ av0.visitEnd();
+ }
+
+ public Class<?> generate(String classDescriptor,
+ String classSignature,
+ String namespace,
+ String name,
+ BeanProperty[] properties,
+ GeneratedClassLoader classLoader) {
+
+ // The reflection code here allows for toleration of older versions of ASM.
+ ClassWriter cw;
+ try {
+ Constructor<ClassWriter> c = ClassWriter.class.getConstructor(new Class[] {int.class});
+ Field f = ClassWriter.class.getField("COMPUTE_MAXS");
+ cw = c.newInstance(f.get(null));
+ } catch ( Exception ex ) {
+ try {
+ Constructor<ClassWriter> c = ClassWriter.class.getConstructor(new Class[] {boolean.class});
+ cw = c.newInstance(true);
+ } catch ( Exception ex2 ) {
+ throw new IllegalArgumentException(ex2);
+ }
+
+ }
+
+ byte[] byteCode = defineClass(cw, classDescriptor, classSignature, namespace, name, properties);
+ String className = classDescriptor.replace('/', '.');
+ Class<?> generated = classLoader.getGeneratedClass(className, byteCode);
+ return generated;
+ }
+
+ public static class BeanProperty {
+ private Class<?> type;
+ private String namespace;
+ private String name;
+ private String signature;
+ private String genericSignature;
+ private List<Annotation> jaxbAnnotaions = new ArrayList<Annotation>();
+ private boolean element;
+ private boolean nillable;
+
+ public BeanProperty(String namespace, String name, Class<?> javaClass, Type type, boolean isElement) {
+ super();
+ this.namespace = namespace;
+ this.name = name;
+ this.signature = CodeGenerationHelper.getJAXWSSignature(javaClass);
+ this.type = javaClass;
+ this.genericSignature = CodeGenerationHelper.getJAXWSSignature(type);
+ this.element = isElement;
+ // FIXME: How to test nillable?
+ // this.nillable = (type instanceof GenericArrayType) || Collection.class.isAssignableFrom(javaClass) || javaClass.isArray();
+ // TUSCANY-2389: Set the nillable consistent with what wsgen produces
+ this.nillable = javaClass.isArray();
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getSignature() {
+ return signature;
+ }
+
+ public String getGenericSignature() {
+ return genericSignature;
+ }
+
+ public Class<?> getType() {
+ return type;
+ }
+
+ public List<Annotation> getJaxbAnnotaions() {
+ return jaxbAnnotaions;
+ }
+
+ public String getNamespace() {
+ return namespace;
+ }
+
+ public boolean isElement() {
+ return element;
+ }
+
+ public boolean isNillable() {
+ return nillable;
+ }
+ }
+
+ public XMLAdapterExtensionPoint getXmlAdapters() {
+ return xmlAdapters;
+ }
+
+ public void setXmlAdapters(XMLAdapterExtensionPoint xmlAdapters) {
+ this.xmlAdapters = xmlAdapters;
+ }
+
+ protected static <T extends Annotation> T findAnnotation(Annotation[] anns, Class<T> annotationClass) {
+ for (Annotation a : anns) {
+ if (a.annotationType() == annotationClass) {
+ return annotationClass.cast(a);
+ }
+ }
+ return null;
+ }
+
+ protected static List<Annotation> findJAXBAnnotations(Annotation[] anns) {
+ List<Annotation> jaxbAnnotation = new ArrayList<Annotation>();
+ for (Class<? extends Annotation> c : KNOWN_JAXB_ANNOTATIONS) {
+ Annotation a = findAnnotation(anns, c);
+ if (a != null) {
+ jaxbAnnotation.add(a);
+ }
+ }
+ return jaxbAnnotation;
+ }
+
+ protected List<Annotation> findJAXBAnnotations(Method method) {
+ List<Annotation> anns = new ArrayList<Annotation>();
+ for (Class<? extends Annotation> c : KNOWN_JAXB_ANNOTATIONS) {
+ Annotation ann = method.getAnnotation(c);
+ if (ann != null) {
+ anns.add(ann);
+ }
+ }
+ return anns;
+ }
+
+}