Index: impl/src/main/java/org/jboss/weld/bean/DisposalMethod.java =================================================================== --- impl/src/main/java/org/jboss/weld/bean/DisposalMethod.java (revision 5216) +++ impl/src/main/java/org/jboss/weld/bean/DisposalMethod.java (working copy) @@ -41,6 +41,7 @@ import org.jboss.weld.introspector.WeldMethod; import org.jboss.weld.introspector.WeldParameter; import org.jboss.weld.util.Beans; +import org.jboss.weld.util.reflection.AnnotatedTypeIdProvider; public class DisposalMethod extends AbstractReceiverBean { @@ -51,7 +52,8 @@ protected DisposalMethod(BeanManagerImpl manager, WeldMethod disposalMethod, AbstractClassBean declaringBean) { - super(new StringBuilder().append(DisposalMethod.class.getSimpleName()).append(BEAN_ID_SEPARATOR).append(declaringBean.getAnnotatedItem().getName()).append(disposalMethod.getSignature().toString()).toString(), declaringBean, manager); + super(new StringBuilder().append(DisposalMethod.class.getSimpleName()).append(BEAN_ID_SEPARATOR).append(AnnotatedTypeIdProvider.getAnnotatedMethodId(disposalMethod)).toString(), declaringBean, + manager); this.disposalMethodInjectionPoint = MethodInjectionPoint.of(this, disposalMethod); initBindings(); initType(); Index: impl/src/main/java/org/jboss/weld/bean/ManagedBean.java =================================================================== --- impl/src/main/java/org/jboss/weld/bean/ManagedBean.java (revision 5216) +++ impl/src/main/java/org/jboss/weld/bean/ManagedBean.java (working copy) @@ -64,6 +64,7 @@ import org.jboss.weld.serialization.spi.helpers.SerializableContextual; import org.jboss.weld.util.Beans; import org.jboss.weld.util.Names; +import org.jboss.weld.util.reflection.AnnotatedTypeIdProvider; import org.jboss.weld.util.reflection.Reflections; import org.slf4j.cal10n.LocLogger; import org.slf4j.ext.XLogger; @@ -110,7 +111,7 @@ protected static String createId(String beanType, WeldClass clazz) { - return new StringBuilder().append(beanType).append(BEAN_ID_SEPARATOR).append(clazz.getBaseType()).toString(); + return new StringBuilder().append(beanType).append(BEAN_ID_SEPARATOR).append(AnnotatedTypeIdProvider.getAnnotatedTypeId(clazz)).toString(); } /** Index: impl/src/main/java/org/jboss/weld/bean/ProducerMethod.java =================================================================== --- impl/src/main/java/org/jboss/weld/bean/ProducerMethod.java (revision 5216) +++ impl/src/main/java/org/jboss/weld/bean/ProducerMethod.java (working copy) @@ -43,6 +43,7 @@ import org.jboss.weld.introspector.WeldMethod; import org.jboss.weld.introspector.WeldParameter; import org.jboss.weld.util.Names; +import org.jboss.weld.util.reflection.AnnotatedTypeIdProvider; /** * Represents a producer method bean @@ -82,7 +83,7 @@ initType(); initTypes(); initBindings(); - this.id = new StringBuilder().append(BEAN_ID_PREFIX).append(getClass().getSimpleName()).append(BEAN_ID_SEPARATOR).append(declaringBean.getAnnotatedItem().getName()).append(getAnnotatedItem().getSignature().toString()).toString(); + this.id = new StringBuilder().append(BEAN_ID_PREFIX).append(getClass().getSimpleName()).append(BEAN_ID_SEPARATOR).append(AnnotatedTypeIdProvider.getAnnotatedMethodId(method)).toString(); initStereotypes(); initAlternative(); initProducerMethodInjectableParameters(); Index: impl/src/main/java/org/jboss/weld/bean/ProducerField.java =================================================================== --- impl/src/main/java/org/jboss/weld/bean/ProducerField.java (revision 5216) +++ impl/src/main/java/org/jboss/weld/bean/ProducerField.java (working copy) @@ -30,6 +30,7 @@ import org.jboss.weld.bootstrap.BeanDeployerEnvironment; import org.jboss.weld.introspector.WeldField; import org.jboss.weld.util.Names; +import org.jboss.weld.util.reflection.AnnotatedTypeIdProvider; /** * Represents a producer field @@ -65,7 +66,7 @@ */ protected ProducerField(WeldField field, AbstractClassBean declaringBean, BeanManagerImpl manager) { - super(new StringBuilder().append(ProducerField.class.getSimpleName()).append(BEAN_ID_SEPARATOR).append(declaringBean.getAnnotatedItem().getName()).append(".").append(field.getName()).toString(), declaringBean, manager); + super(new StringBuilder().append(ProducerField.class.getSimpleName()).append(BEAN_ID_SEPARATOR).append(AnnotatedTypeIdProvider.getAnnotatedFieldId(field)).toString(), declaringBean, manager); this.field = field; initType(); initTypes(); Index: impl/src/main/java/org/jboss/weld/bean/NewManagedBean.java =================================================================== --- impl/src/main/java/org/jboss/weld/bean/NewManagedBean.java (revision 5216) +++ impl/src/main/java/org/jboss/weld/bean/NewManagedBean.java (working copy) @@ -45,7 +45,12 @@ { return new NewManagedBean(clazz, createId(NewManagedBean.class.getSimpleName(), clazz), manager); } - + + protected static String createId(String beanType, WeldClass clazz) + { + return new StringBuilder().append(beanType).append(BEAN_ID_SEPARATOR).append(clazz.getBaseType()).toString(); + } + private Set bindings; /** Index: impl/src/main/java/org/jboss/weld/util/reflection/AnnotatedTypeIdProvider.java =================================================================== --- impl/src/main/java/org/jboss/weld/util/reflection/AnnotatedTypeIdProvider.java (revision 0) +++ impl/src/main/java/org/jboss/weld/util/reflection/AnnotatedTypeIdProvider.java (revision 0) @@ -0,0 +1,314 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2008, Red Hat Middleware LLC, and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * Licensed 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.jboss.weld.util.reflection; + +import java.lang.annotation.Annotation; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Set; + +import javax.enterprise.inject.spi.AnnotatedCallable; +import javax.enterprise.inject.spi.AnnotatedConstructor; +import javax.enterprise.inject.spi.AnnotatedField; +import javax.enterprise.inject.spi.AnnotatedMethod; +import javax.enterprise.inject.spi.AnnotatedParameter; +import javax.enterprise.inject.spi.AnnotatedType; + +/** + * Class that can take an AnnotatedType and return a unique + * string representation of that type + * @author Stuart Douglas + * + */ +public class AnnotatedTypeIdProvider +{ + + static final char SEPERATOR = ';'; + + /** + * generates a unique signature for an annotated type. + * members without annotations are ommited to reduce + * the length of the signature + * @param + * @param annotatedType + * @return + */ + public static String getAnnotatedTypeId(AnnotatedType annotatedType) + { + StringBuilder builder = new StringBuilder(); + + builder.append(annotatedType.getJavaClass().getName()); + builder.append(getAnnotationSetId(annotatedType.getAnnotations())); + builder.append("{ "); + + //now deal with the fields + List> fields = new ArrayList>(); + fields.addAll(annotatedType.getFields()); + Collections.sort(fields,new Comparator>() + { + public int compare(AnnotatedField arg0, AnnotatedField arg1) + { + if (arg0.getJavaMember().getName().equals(arg1.getJavaMember().getName())) + { + return arg0.getJavaMember().getDeclaringClass().getName().compareTo(arg1.getJavaMember().getDeclaringClass().getName()); + } + return arg0.getJavaMember().getName().compareTo(arg1.getJavaMember().getName()); + } + }); + for (AnnotatedField field : fields) + { + if (!field.getAnnotations().isEmpty()) + { + builder.append(getAnnotatedFieldId(field)); + builder.append(SEPERATOR); + } + } + + //methods + List> methods = new ArrayList>(); + methods.addAll(annotatedType.getMethods()); + Collections.sort(methods, new AnnotatedMethodComparator()); + for (AnnotatedMethod method : methods) + { + if (!method.getAnnotations().isEmpty() || hasMethodParameters(method)) + { + builder.append(getAnnotatedMethodId(method)); + builder.append(SEPERATOR); + } + } + + //constructors + List> constructors = new ArrayList>(); + constructors.addAll(annotatedType.getConstructors()); + Collections.sort(constructors, new AnnotatedConstructorComparator()); + for (AnnotatedConstructor con : constructors) + { + if (!con.getAnnotations().isEmpty() || hasMethodParameters(con)) + { + builder.append(getAnnotatedConstructorId(con)); + builder.append(SEPERATOR); + } + } + builder.append("}"); + + return builder.toString(); + } + + public static boolean hasMethodParameters(AnnotatedCallable callable) + { + for(AnnotatedParameter p : callable.getParameters()) + { + if (p.getAnnotations().isEmpty()) + return true; + } + return false; + } + + public static String getAnnotationSetId(Set annotations) + { + if (annotations.isEmpty()) + return ""; + StringBuilder builder = new StringBuilder(); + builder.append('['); + + List anList = new ArrayList(annotations.size()); + anList.addAll(annotations); + Collections.sort(anList, new Comparator() + { + public int compare(Annotation arg0, Annotation arg1) + { + return arg0.annotationType().getName().compareTo(arg1.annotationType().getName()); + } + }); + for(Annotation a : anList) + { + builder.append('@'); + builder.append(a.annotationType().getName()); + builder.append('('); + Method[] decMethod = a.annotationType().getDeclaredMethods(); + List methods = new ArrayList(decMethod.length); + Collections.sort(methods, new Comparator() + { + + public int compare(Method arg0, Method arg1) + { + return arg0.getName().compareTo(arg1.getName()); + } + }); + + for (int i = 0; i < methods.size(); ++i) + { + Method m = methods.get(i); + try + { + Object value = m.invoke(a); + builder.append(m.getName()); + builder.append('='); + builder.append(value.toString()); + } + catch (NullPointerException e) + { + throw new RuntimeException("NullPointerException accessing annotation member, annotation:" + a.annotationType().getName() + " member: " + m.getName(), e); + } + catch (IllegalArgumentException e) + { + throw new RuntimeException("IllegalArgumentException accessing annotation member, annotation:" + a.annotationType().getName() + " member: " + m.getName(), e); + } + catch (IllegalAccessException e) + { + throw new RuntimeException("IllegalAccessException accessing annotation member, annotation:" + a.annotationType().getName() + " member: " + m.getName(), e); + } + catch (InvocationTargetException e) + { + throw new RuntimeException("InvocationTargetException accessing annotation member, annotation:" + a.annotationType().getName() + " member: " + m.getName(), e); + } + if (i + 1 != methods.size()) + { + builder.append(','); + } + } + builder.append(')'); + } + builder.append(']'); + return builder.toString(); + } + + public static String getAnnotatedFieldId(AnnotatedField field) + { + StringBuilder builder = new StringBuilder(); + builder.append(field.getJavaMember().getDeclaringClass().getName()); + builder.append('.'); + builder.append(field.getJavaMember().getName()); + builder.append(getAnnotationSetId(field.getAnnotations())); + return builder.toString(); + } + + public static String getAnnotatedMethodId(AnnotatedMethod method) + { + StringBuilder builder = new StringBuilder(); + builder.append(method.getJavaMember().getDeclaringClass().getName()); + builder.append('.'); + builder.append(method.getJavaMember().getName()); + builder.append(getAnnotationSetId(method.getAnnotations())); + builder.append(getAnnotatatedParameterListId(method.getParameters(), method.getJavaMember().getParameterTypes())); + return builder.toString(); + } + + public static String getAnnotatedConstructorId(AnnotatedConstructor constructor) + { + StringBuilder builder = new StringBuilder(); + builder.append(constructor.getJavaMember().getDeclaringClass().getName()); + builder.append('.'); + builder.append(constructor.getJavaMember().getName()); + builder.append(getAnnotationSetId(constructor.getAnnotations())); + builder.append(getAnnotatatedParameterListId(constructor.getParameters(), constructor.getJavaMember().getParameterTypes())); + return builder.toString(); + } + + public static String getAnnotatatedParameterListId(List> parameters, Class[] paramTypes) + { + StringBuilder builder = new StringBuilder(); + builder.append("("); + for (int i = 0; i < parameters.size(); ++i) + { + AnnotatedParameter ap = parameters.get(i); + Class c = paramTypes[i]; + builder.append(c.getName()); + builder.append(getAnnotationSetId(ap.getAnnotations())); + if (i + 1 != parameters.size()) + { + builder.append(','); + } + } + builder.append(")"); + return builder.toString(); + } + + /** + * Does the first stage of comparing AnnoatedCallables, however it cannot compare the + * method parameters + * @author Stuart Douglas + * + * @param + */ + static class AnnotatedCallableComparator implements Comparator> + { + + public int compare(AnnotatedCallable arg0, AnnotatedCallable arg1) + { + //compare the names first + int res = (arg0.getJavaMember().getName().compareTo(arg1.getJavaMember().getName())); + if (res != 0) + return res; + res = arg0.getJavaMember().getDeclaringClass().getName().compareTo(arg1.getJavaMember().getDeclaringClass().getName()); + if (res != 0) + return res; + res = arg0.getParameters().size() - arg1.getParameters().size(); + return res; + } + + } + + static class AnnotatedMethodComparator implements Comparator> + { + AnnotatedCallableComparator cmp = new AnnotatedCallableComparator(); + + public int compare(AnnotatedMethod arg0, AnnotatedMethod arg1) + { + int res = cmp.compare(arg0, arg1); + if (res != 0) + return res; + for (int i = 0; i < arg0.getJavaMember().getParameterTypes().length; ++i) + { + Class p0 = arg0.getJavaMember().getParameterTypes()[i]; + Class p1 = arg1.getJavaMember().getParameterTypes()[i]; + res = p0.getName().compareTo(p1.getName()); + if (res != 0) + return res; + } + return 0; + } + + } + + static class AnnotatedConstructorComparator implements Comparator> + { + AnnotatedCallableComparator cmp = new AnnotatedCallableComparator(); + + public int compare(AnnotatedConstructor arg0, AnnotatedConstructor arg1) + { + int res = cmp.compare(arg0, arg1); + if (res != 0) + return res; + for (int i = 0; i < arg0.getJavaMember().getParameterTypes().length; ++i) + { + Class p0 = arg0.getJavaMember().getParameterTypes()[i]; + Class p1 = arg1.getJavaMember().getParameterTypes()[i]; + res = p0.getName().compareTo(p1.getName()); + if (res != 0) + return res; + } + return 0; + } + + } + +}