Skip to content

Commit

Permalink
implement name based resolution, resolution index rebuild when a bean…
Browse files Browse the repository at this point in the history
… is added, use of parameterized types and annotation members when doing typesafe resolution

git-svn-id: http://anonsvn.jboss.org/repos/weld/ri/trunk@144 1c488680-804c-0410-94cd-c6b725194a0e
  • Loading branch information
pmuir committed Oct 25, 2008
1 parent 3e050cf commit c1da4b2
Show file tree
Hide file tree
Showing 35 changed files with 620 additions and 163 deletions.
73 changes: 65 additions & 8 deletions webbeans-api/src/main/java/javax/webbeans/AnnotationLiteral.java
Expand Up @@ -27,6 +27,8 @@
* the annotation type
*/
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

Expand All @@ -35,6 +37,7 @@ public abstract class AnnotationLiteral<T extends Annotation> implements
{

private Class<T> annotationType;
private Method[] members;

protected AnnotationLiteral()
{
Expand All @@ -43,12 +46,15 @@ protected AnnotationLiteral()
{
throw new RuntimeException(getClass() + "is not a subclass of AnnotationLiteral ");
}

annotationType = getTypeParameter(annotationLiteralSubclass);

if (annotationType == null)
{
throw new RuntimeException(getClass() + " is missing type parameter in AnnotationLiteral");

}

this.members = annotationType.getDeclaredMethods();
}

@SuppressWarnings("unchecked")
Expand Down Expand Up @@ -93,7 +99,17 @@ public Class<? extends Annotation> annotationType()
@Override
public String toString()
{
return "@" + annotationType().getName() + "()";
String string = "@" + annotationType().getName() + "(";
for (int i = 0; i < members.length; i++)
{
string += members[i].getName() + "=";
string += invoke(members[i], this);
if (i < members.length - 1)
{
string += ",";
}
}
return string + ")";
}

@Override
Expand All @@ -102,17 +118,58 @@ public boolean equals(Object other)
if (other instanceof Annotation)
{
Annotation that = (Annotation) other;
return this.annotationType().equals(that.annotationType());
}
else
{
return false;
if (this.annotationType().equals(that.annotationType()))
{
for (Method member : members)
{
Object thisValue = invoke(member, this);
Object thatValue = invoke(member, that);
if (!thisValue.equals(thatValue))
{
return false;
}
}
return true;
}
}
return false;
}

@Override
/*
* The hash code of a primitive value v is equal to WrapperType.valueOf(v).hashCode(), where WrapperType is the wrapper type corresponding to the primitive type of v (Byte, Character, Double, Float, Integer, Long, Short, or Boolean).
* The hash code of a string, enum, class, or annotation member-value I v is computed as by calling v.hashCode(). (In the case of annotation member values, this is a recursive definition.)
* The hash code of an array member-value is computed by calling the appropriate overloading of Arrays.hashCode on the value. (There is one overloading for each primitive type, and one for object reference types.)
*/
public int hashCode()
{
return 0;
int hashCode = 0;
for (Method member : members)
{
int memberNameHashCode = 127 * member.getName().hashCode();
int memberValueHashCode = invoke(member, this).hashCode();
hashCode += memberNameHashCode ^ memberValueHashCode;
}
return hashCode;
}

private static Object invoke(Method method, Object instance)
{
try
{
return method.invoke(instance);
}
catch (IllegalArgumentException e)
{
throw new ExecutionException("Error checking value of member method " + method.getName() + " on " + method.getDeclaringClass(), e);
}
catch (IllegalAccessException e)
{
throw new ExecutionException("Error checking value of member method " + method.getName() + " on " + method.getDeclaringClass(), e);
}
catch (InvocationTargetException e)
{
throw new ExecutionException("Error checking value of member method " + method.getName() + " on " + method.getDeclaringClass(), e);
}
}
}
26 changes: 26 additions & 0 deletions webbeans-api/src/main/java/javax/webbeans/ExecutionException.java
@@ -0,0 +1,26 @@
package javax.webbeans;

public class ExecutionException extends RuntimeException
{

public ExecutionException()
{
super();
}

public ExecutionException(String message, Throwable throwable)
{
super(message, throwable);
}

public ExecutionException(String message)
{
super(message);
}

public ExecutionException(Throwable throwable)
{
super(throwable);
}

}
27 changes: 23 additions & 4 deletions webbeans-ri/src/main/java/org/jboss/webbeans/BasicContext.java
@@ -1,30 +1,49 @@
package org.jboss.webbeans;

import java.lang.annotation.Annotation;
import java.util.HashMap;

import javax.webbeans.ContextNotActiveException;
import javax.webbeans.manager.Bean;
import javax.webbeans.manager.Context;
import javax.webbeans.manager.Manager;

import org.jboss.webbeans.util.BeanMap;
import org.jboss.webbeans.util.MapWrapper;

/**
* Basic implementation of javax.webbeans.Context, backed by a HashMap
*
* @author Shane Bryzak
* @author Nicklas Karlsson (nickarls@gmail.com)
* @author Pete\ Muir
* @
*/
public class BasicContext implements Context
{
private BeanMap<Object> beans;

private class BeanMap extends MapWrapper<Bean<? extends Object>, Object>
{

public BeanMap()
{
super(new HashMap<Bean<? extends Object>, Object>());
}

@SuppressWarnings("unchecked")
public <T extends Object> T get(Bean<? extends T> key)
{
return (T) super.get(key);
}

}

private BeanMap beans;
private Class<? extends Annotation> scopeType;
private boolean active;

public BasicContext(Class<? extends Annotation> scopeType)
{
this.scopeType = scopeType;
beans = new BeanMap<Object>();
beans = new BeanMap();
active = true;
}

Expand Down
5 changes: 5 additions & 0 deletions webbeans-ri/src/main/java/org/jboss/webbeans/BeanImpl.java
Expand Up @@ -84,5 +84,10 @@ public String toString()
{
return model.toString();
}

public AbstractComponentModel<T, ?> getModel()
{
return model;
}

}
52 changes: 42 additions & 10 deletions webbeans-ri/src/main/java/org/jboss/webbeans/ManagerImpl.java
Expand Up @@ -2,6 +2,8 @@

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
Expand All @@ -19,13 +21,17 @@
import javax.webbeans.manager.Interceptor;
import javax.webbeans.manager.Manager;

import org.jboss.webbeans.bindings.CurrentAnnotationLiteral;
import org.jboss.webbeans.ejb.EjbManager;
import org.jboss.webbeans.event.EventBus;
import org.jboss.webbeans.injectable.Injectable;
import org.jboss.webbeans.injectable.SimpleInjectable;

public class ManagerImpl implements Manager
{

private static final Annotation[] DEFAULT_BINDING = {new CurrentAnnotationLiteral()};

private List<Class<? extends Annotation>> enabledDeploymentTypes;
private ModelManager modelManager;
private EjbManager ejbLookupManager;
Expand Down Expand Up @@ -66,6 +72,7 @@ private void initEnabledDeploymentTypes(

public Manager addBean(Bean<?> bean)
{
getResolutionManager().clear();
beans.add(bean);
return this;
}
Expand Down Expand Up @@ -104,8 +111,39 @@ public EjbManager getEjbManager()
public <T> Set<Bean<T>> resolveByType(Class<T> apiType,
Annotation... bindingTypes)
{
Set<Bean<T>> beans = getResolutionManager().get(
new SimpleInjectable<T>(apiType, bindingTypes));
return resolveByType(apiType, bindingTypes, new Type[0]);
}

public <T> Set<Bean<T>> resolveByType(TypeLiteral<T> apiType,
Annotation... bindingTypes)
{
if (apiType.getType() instanceof ParameterizedType)
{
return resolveByType(apiType.getRawType(), bindingTypes, ((ParameterizedType) apiType.getType()).getActualTypeArguments());
}
else
{
return resolveByType(apiType.getRawType(), bindingTypes, new Type[0]);
}

}

private <T> Set<Bean<T>> resolveByType(Class<T> apiType, Annotation[] bindingTypes, Type[] actualTypeArguements)
{
if (bindingTypes.length == 0)
{
bindingTypes = DEFAULT_BINDING;
}
Injectable<T, ?> injectable = null;
if (actualTypeArguements.length > 0)
{
injectable = new SimpleInjectable<T>(apiType, bindingTypes, actualTypeArguements);
}
else
{
injectable = new SimpleInjectable<T>(apiType, bindingTypes);
}
Set<Bean<T>> beans = getResolutionManager().get(injectable);
if (beans == null)
{
return new HashSet<Bean<T>>();
Expand All @@ -114,12 +152,7 @@ public <T> Set<Bean<T>> resolveByType(Class<T> apiType,
{
return beans;
}
}

public <T> Set<Bean<T>> resolveByType(TypeLiteral<T> apiType,
Annotation... bindingTypes)
{
return resolveByType(apiType.getRawType(), bindingTypes);

}

public ResolutionManager getResolutionManager()
Expand Down Expand Up @@ -223,8 +256,7 @@ public <T> Manager removeObserver(Observer<T> observer,

public Set<Bean<?>> resolveByName(String name)
{
// TODO Auto-generated method stub
return null;
return getResolutionManager().get(name);
}

public List<Decorator> resolveDecorators(Set<Class<?>> types,
Expand Down

0 comments on commit c1da4b2

Please sign in to comment.