Skip to content

Commit

Permalink
WELD-2156 Fix EnhancedAnnotated immutability
Browse files Browse the repository at this point in the history
  • Loading branch information
mkouba committed May 24, 2016
1 parent 9c2c917 commit fb42844
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 38 deletions.
Expand Up @@ -42,6 +42,8 @@
import org.jboss.weld.resources.ReflectionCache;
import org.jboss.weld.util.collections.Arrays2;
import org.jboss.weld.util.collections.ImmutableSet;
import org.jboss.weld.util.collections.Multimap;
import org.jboss.weld.util.collections.Multimaps;
import org.jboss.weld.util.collections.SetMultimap;
import org.jboss.weld.util.collections.WeldCollections;
import org.jboss.weld.util.reflection.Reflections;
Expand Down Expand Up @@ -94,7 +96,7 @@ private static void addMetaAnnotation(SetMultimap<Class<? extends Annotation>, A
private final Map<Class<? extends Annotation>, Annotation> annotationMap;
// The meta-annotation map (annotation type -> set of annotations containing
// meta-annotation) of the item
private final SetMultimap<Class<? extends Annotation>, Annotation> metaAnnotationMap;
private final Multimap<Class<? extends Annotation>, Annotation> metaAnnotationMap;

private final Class<T> rawType;
private final Type[] actualTypeArguments;
Expand Down Expand Up @@ -123,7 +125,7 @@ public AbstractEnhancedAnnotated(Annotated annotated, Map<Class<? extends Annota
this.annotationMap = immutableMapView(annotationMap);
SetMultimap<Class<? extends Annotation>, Annotation> metaAnnotationMap = SetMultimap.newSetMultimap();
processMetaAnnotations(metaAnnotationMap, annotationMap.values(), classTransformer, false);
this.metaAnnotationMap = metaAnnotationMap;
this.metaAnnotationMap = Multimaps.unmodifiableMultimap(metaAnnotationMap);

if (declaredAnnotationMap == null) {
throw ReflectionLogger.LOG.declaredAnnotationMapNull();
Expand Down
Expand Up @@ -95,12 +95,12 @@ public class EnhancedAnnotatedTypeImpl<T> extends AbstractEnhancedAnnotated<T, C
// The set of abstracted fields
private final Set<EnhancedAnnotatedField<?, ? super T>> fields;
// The map from annotation type to abstracted field with annotation
private final ListMultimap<Class<? extends Annotation>, EnhancedAnnotatedField<?, ?>> annotatedFields;
private final Multimap<Class<? extends Annotation>, EnhancedAnnotatedField<?, ?>> annotatedFields;

// The set of abstracted fields
private final Set<EnhancedAnnotatedField<?, ? super T>> declaredFields;
// The map from annotation type to abstracted field with annotation
private final ListMultimap<Class<? extends Annotation>, EnhancedAnnotatedField<?, ? super T>> declaredAnnotatedFields;
private final Multimap<Class<? extends Annotation>, EnhancedAnnotatedField<?, ? super T>> declaredAnnotatedFields;

// The set of abstracted methods
private final Set<EnhancedAnnotatedMethod<?, ? super T>> methods;
Expand All @@ -114,9 +114,9 @@ public class EnhancedAnnotatedTypeImpl<T> extends AbstractEnhancedAnnotated<T, C
// The set of abstracted methods
private final Set<EnhancedAnnotatedMethod<?, ? super T>> declaredMethods;
// The map from annotation type to abstracted method with annotation
private final ListMultimap<Class<? extends Annotation>, EnhancedAnnotatedMethod<?, ? super T>> declaredAnnotatedMethods;
private final Multimap<Class<? extends Annotation>, EnhancedAnnotatedMethod<?, ? super T>> declaredAnnotatedMethods;
// The map from annotation type to method with a parameter with annotation
private final ListMultimap<Class<? extends Annotation>, EnhancedAnnotatedMethod<?, ? super T>> declaredMethodsByAnnotatedParameters;
private final Multimap<Class<? extends Annotation>, EnhancedAnnotatedMethod<?, ? super T>> declaredMethodsByAnnotatedParameters;

// The set of abstracted constructors
private final Set<EnhancedAnnotatedConstructor<T>> constructors;
Expand Down Expand Up @@ -156,7 +156,7 @@ protected EnhancedAnnotatedTypeImpl(SlimAnnotatedType<T> annotatedType, Map<Clas
}

// Assign class field information
this.declaredAnnotatedFields = new ListMultimap<Class<? extends Annotation>, EnhancedAnnotatedField<?, ? super T>>();
Multimap<Class<? extends Annotation>, EnhancedAnnotatedField<?, ? super T>> declaredAnnotatedFields = new ListMultimap<Class<? extends Annotation>, EnhancedAnnotatedField<?, ? super T>>();
Set<EnhancedAnnotatedField<?, ? super T>> fieldsTemp = null;
ArrayList<EnhancedAnnotatedField<?, ? super T>> declaredFieldsTemp = new ArrayList<EnhancedAnnotatedField<?, ? super T>>();

Expand All @@ -170,7 +170,7 @@ protected EnhancedAnnotatedTypeImpl(SlimAnnotatedType<T> annotatedType, Map<Clas
EnhancedAnnotatedField<?, ? super T> annotatedField = EnhancedAnnotatedFieldImpl.of(field, this, classTransformer);
declaredFieldsTemp.add(annotatedField);
for (Annotation annotation : annotatedField.getAnnotations()) {
this.declaredAnnotatedFields.put(annotation.annotationType(), annotatedField);
declaredAnnotatedFields.put(annotation.annotationType(), annotatedField);
}
}
}
Expand All @@ -181,7 +181,7 @@ protected EnhancedAnnotatedTypeImpl(SlimAnnotatedType<T> annotatedType, Map<Clas
}
this.declaredFields = new HashSet<EnhancedAnnotatedField<?, ? super T>>(declaredFieldsTemp);
} else {
this.annotatedFields = new ListMultimap<Class<? extends Annotation>, EnhancedAnnotatedField<?, ?>>();
Multimap<Class<? extends Annotation>, EnhancedAnnotatedField<?, ?>> annotatedFields = new ListMultimap<Class<? extends Annotation>, EnhancedAnnotatedField<?, ?>>();
fieldsTemp = new HashSet<EnhancedAnnotatedField<?, ? super T>>();
for (AnnotatedField<? super T> annotatedField : annotatedType.getFields()) {
EnhancedAnnotatedField<?, ? super T> weldField = EnhancedAnnotatedFieldImpl.of(annotatedField, this, classTransformer);
Expand All @@ -190,15 +190,17 @@ protected EnhancedAnnotatedTypeImpl(SlimAnnotatedType<T> annotatedType, Map<Clas
declaredFieldsTemp.add(weldField);
}
for (Annotation annotation : weldField.getAnnotations()) {
this.annotatedFields.put(annotation.annotationType(), weldField);
annotatedFields.put(annotation.annotationType(), weldField);
if (annotatedField.getDeclaringType().getJavaClass().equals(javaClass)) {
this.declaredAnnotatedFields.put(annotation.annotationType(), weldField);
declaredAnnotatedFields.put(annotation.annotationType(), weldField);
}
}
}
this.annotatedFields = Multimaps.unmodifiableMultimap(annotatedFields);
this.declaredFields = new HashSet<EnhancedAnnotatedField<?, ? super T>>(declaredFieldsTemp);
}
this.fields = fieldsTemp;
this.declaredAnnotatedFields = Multimaps.unmodifiableMultimap(declaredAnnotatedFields);

// Assign constructor information
this.constructors = new HashSet<EnhancedAnnotatedConstructor<T>>();
Expand All @@ -211,8 +213,8 @@ protected EnhancedAnnotatedTypeImpl(SlimAnnotatedType<T> annotatedType, Map<Clas
}

// Assign method information
this.declaredAnnotatedMethods = new ListMultimap<Class<? extends Annotation>, EnhancedAnnotatedMethod<?, ? super T>>();
this.declaredMethodsByAnnotatedParameters = new ListMultimap<Class<? extends Annotation>, EnhancedAnnotatedMethod<?, ? super T>>();
Multimap<Class<? extends Annotation>, EnhancedAnnotatedMethod<?, ? super T>> declaredAnnotatedMethods = new ListMultimap<Class<? extends Annotation>, EnhancedAnnotatedMethod<?, ? super T>>();
Multimap<Class<? extends Annotation>, EnhancedAnnotatedMethod<?, ? super T>> declaredMethodsByAnnotatedParameters = new ListMultimap<Class<? extends Annotation>, EnhancedAnnotatedMethod<?, ? super T>>();

Set<EnhancedAnnotatedMethod<?, ? super T>> methodsTemp = new HashSet<EnhancedAnnotatedMethod<?,? super T>>();
ArrayList<EnhancedAnnotatedMethod<?, ? super T>> declaredMethodsTemp = new ArrayList<EnhancedAnnotatedMethod<?, ? super T>>();
Expand All @@ -223,11 +225,11 @@ protected EnhancedAnnotatedTypeImpl(SlimAnnotatedType<T> annotatedType, Map<Clas
EnhancedAnnotatedMethod<?, ? super T> weldMethod = EnhancedAnnotatedMethodImpl.of(method, this, classTransformer);
declaredMethodsTemp.add(weldMethod);
for (Annotation annotation : weldMethod.getAnnotations()) {
this.declaredAnnotatedMethods.put(annotation.annotationType(), weldMethod);
declaredAnnotatedMethods.put(annotation.annotationType(), weldMethod);
}
for (Class<? extends Annotation> annotationType : MAPPED_DECLARED_METHOD_PARAMETER_ANNOTATIONS) {
if (weldMethod.getEnhancedParameters(annotationType).size() > 0) {
this.declaredMethodsByAnnotatedParameters.put(annotationType, weldMethod);
declaredMethodsByAnnotatedParameters.put(annotationType, weldMethod);
}
}
}
Expand All @@ -252,19 +254,21 @@ protected EnhancedAnnotatedTypeImpl(SlimAnnotatedType<T> annotatedType, Map<Clas
}
for (Annotation annotation : enhancedMethod.getAnnotations()) {
if (method.getJavaMember().getDeclaringClass().equals(javaClass)) {
this.declaredAnnotatedMethods.put(annotation.annotationType(), enhancedMethod);
declaredAnnotatedMethods.put(annotation.annotationType(), enhancedMethod);
}
}
for (Class<? extends Annotation> annotationType : MAPPED_DECLARED_METHOD_PARAMETER_ANNOTATIONS) {
if (enhancedMethod.getEnhancedParameters(annotationType).size() > 0) {
if (method.getJavaMember().getDeclaringClass().equals(javaClass)) {
this.declaredMethodsByAnnotatedParameters.put(annotationType, enhancedMethod);
declaredMethodsByAnnotatedParameters.put(annotationType, enhancedMethod);
}
}
}
}
this.declaredMethods = ImmutableSet.copyOf(declaredMethodsTemp);
}
this.declaredAnnotatedMethods = Multimaps.unmodifiableMultimap(declaredAnnotatedMethods);
this.declaredMethodsByAnnotatedParameters = Multimaps.unmodifiableMultimap(declaredMethodsByAnnotatedParameters);

SetMultimap<Class<? extends Annotation>, Annotation> declaredMetaAnnotationMap = SetMultimap.newSetMultimap();
processMetaAnnotations(declaredMetaAnnotationMap, declaredAnnotationMap.values(), classTransformer, true);
Expand Down Expand Up @@ -393,7 +397,7 @@ public Class<T> getDelegate() {

@Override
public Collection<EnhancedAnnotatedField<?, ? super T>> getDeclaredEnhancedFields(Class<? extends Annotation> annotationType) {
return Collections.unmodifiableCollection(declaredAnnotatedFields.get(annotationType));
return declaredAnnotatedFields.get(annotationType);
}

@Override
Expand All @@ -420,7 +424,7 @@ public EnhancedAnnotatedConstructor<T> getDeclaredEnhancedConstructor(Constructo
return Collections.unmodifiableCollection(aggregatedFields);
} else {
// Return results collected directly from AnnotatedType
return Collections.unmodifiableCollection(annotatedFields.get(annotationType));
return annotatedFields.get(annotationType);
}
}

Expand Down Expand Up @@ -675,7 +679,8 @@ public Set<AnnotatedMethod<? super T>> getMethods() {

@Override
public Set<Annotation> getDeclaredMetaAnnotations(Class<? extends Annotation> metaAnnotationType) {
return ImmutableSet.copyOf(declaredMetaAnnotationMap.get(metaAnnotationType));
return declaredMetaAnnotationMap.containsKey(metaAnnotationType) ? ImmutableSet.copyOf(declaredMetaAnnotationMap.get(metaAnnotationType))
: Collections.emptySet();
}

@Override
Expand Down
Expand Up @@ -44,7 +44,7 @@ public interface Multimap<K, V> {
boolean isEmpty();

/**
* This method never returns null.
* This method never returns null. If no collection of values for a given key exists a new value collection is initialized.
*
* @param key
* @return the collection of values for the given key
Expand Down
43 changes: 26 additions & 17 deletions impl/src/main/java/org/jboss/weld/util/collections/Multimaps.java
Expand Up @@ -37,7 +37,8 @@ private Multimaps() {
}

/**
* Note that {@link Multimap#get(Object)} returns unmodifiable collections.
* Note that {@link Multimap#get(Object)} always returns unmodifiable collections. Moreover, it does not trigger initialization of a new value collection
* (i.e. when no collection of values for a given key exists).
*
* @param multimap
* @return an unmodifiable view of the given multimap
Expand Down Expand Up @@ -87,9 +88,16 @@ public boolean isEmpty() {
return delegate.isEmpty();
}

/**
* Returns unmodifiable collections. Moreover, it does not trigger initialization of a new value collection (i.e. when no collection of values for a
* given key exists).
*/
@Override
public Collection<V> get(K key) {
return unmodifiableValueCollection(delegate.get(key));
if (delegate.containsKey(key)) {
return unmodifiableValueCollection(delegate.get(key));
}
return Collections.emptyList();
}

@Override
Expand Down Expand Up @@ -158,21 +166,6 @@ public Collection<V> get(K key) {
return Collections.emptyList();
}

@Override
public boolean put(K key, V value) {
throw new UnsupportedOperationException();
}

@Override
public boolean putAll(K key, Collection<? extends V> values) {
throw new UnsupportedOperationException();
}

@Override
public Collection<V> replaceValues(K key, Iterable<? extends V> values) {
throw new UnsupportedOperationException();
}

@Override
public boolean containsKey(Object key) {
return false;
Expand All @@ -198,8 +191,24 @@ public Set<Entry<K, Collection<V>>> entrySet() {
return Collections.emptySet();
}

@Override
public boolean put(K key, V value) {
throw new UnsupportedOperationException();
}

@Override
public boolean putAll(K key, Collection<? extends V> values) {
throw new UnsupportedOperationException();
}

@Override
public Collection<V> replaceValues(K key, Iterable<? extends V> values) {
throw new UnsupportedOperationException();
}

@Override
public void clear() {
throw new UnsupportedOperationException();
}

public boolean equals(Object o) {
Expand Down

0 comments on commit fb42844

Please sign in to comment.