Author: jbunting
Date: Fri Aug 5 15:05:28 2011
New Revision: 1154256
URL: http://svn.apache.org/viewvc?rev=1154256&view=rev
Log:
SHIRO-318: Adding type mappings for BeanTypeListener in shiro-guice and adding
a mapping for ServletContext.
Modified:
shiro/trunk/support/guice/ (props changed)
shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/BeanTypeListener.java
shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/ShiroModule.java
shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/web/ShiroWebModule.java
shiro/trunk/support/guice/src/test/java/org/apache/shiro/guice/BeanTypeListenerTest.java
Propchange: shiro/trunk/support/guice/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Fri Aug 5 15:05:28 2011
@@ -1 +1,6 @@
+*.iml
+.classpath
+.externalToolBuilders
+.project
+.settings
target
Modified:
shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/BeanTypeListener.java
URL:
http://svn.apache.org/viewvc/shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/BeanTypeListener.java?rev=1154256&r1=1154255&r2=1154256&view=diff
==============================================================================
---
shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/BeanTypeListener.java
(original)
+++
shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/BeanTypeListener.java
Fri Aug 5 15:05:28 2011
@@ -22,9 +22,11 @@ import com.google.common.primitives.Prim
import com.google.inject.*;
import com.google.inject.matcher.Matcher;
import com.google.inject.matcher.Matchers;
+import com.google.inject.multibindings.MapBinder;
import com.google.inject.name.Names;
import com.google.inject.spi.TypeEncounter;
import com.google.inject.spi.TypeListener;
+import com.google.inject.util.Types;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.shiro.SecurityUtils;
@@ -49,6 +51,9 @@ class BeanTypeListener implements TypeLi
public static final Matcher<TypeLiteral> MATCHER =
ShiroMatchers.typeLiteral(classMatcher);
+ private static final String BEAN_TYPE_MAP_NAME = "__SHIRO_BEAN_TYPES__";
+ static final Key<?> MAP_KEY = Key.get(Types.mapOf(TypeLiteral.class,
BeanTypeKey.class), Names.named(BEAN_TYPE_MAP_NAME));
+
public <I> void hear(TypeLiteral<I> type, final TypeEncounter<I>
encounter) {
PropertyDescriptor propertyDescriptors[] =
PropertyUtils.getPropertyDescriptors(type.getRawType());
final Map<PropertyDescriptor, Key<?>> propertyDependencies = new
HashMap<PropertyDescriptor, Key<?>>(propertyDescriptors.length);
@@ -56,16 +61,16 @@ class BeanTypeListener implements TypeLi
for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
if (propertyDescriptor.getWriteMethod() != null &&
Modifier.isPublic(propertyDescriptor.getWriteMethod().getModifiers())) {
Type propertyType =
propertyDescriptor.getWriteMethod().getGenericParameterTypes()[0];
- propertyDependencies.put(propertyDescriptor,
requiresName(propertyType)
- ? Key.get(propertyType, Names.named("shiro." +
propertyDescriptor.getName()))
- : Key.get(propertyType));
+ propertyDependencies.put(propertyDescriptor,
createDependencyKey(propertyDescriptor, propertyType));
}
}
encounter.register(new MembersInjector<I>() {
public void injectMembers(I instance) {
for (Map.Entry<PropertyDescriptor, Key<?>> dependency :
propertyDependencies.entrySet()) {
try {
- Object value =
injectorProvider.get().getInstance(dependency.getValue());
+ final Injector injector = injectorProvider.get();
+
+ Object value =
injector.getInstance(getMappedKey(injector, dependency.getValue()));
dependency.getKey().getWriteMethod().invoke(instance,
value);
} catch (ConfigurationException e) {
@@ -82,6 +87,28 @@ class BeanTypeListener implements TypeLi
});
}
+ private static Key<?> getMappedKey(Injector injector, Key<?> key) {
+ Map<TypeLiteral, BeanTypeKey> beanTypeMap = getBeanTypeMap(injector);
+ if(key.getAnnotation() == null &&
beanTypeMap.containsKey(key.getTypeLiteral())) {
+ return beanTypeMap.get(key.getTypeLiteral()).key;
+ } else {
+ return key;
+ }
+ }
+
+ @SuppressWarnings({"unchecked"})
+ private static Map<TypeLiteral, BeanTypeKey> getBeanTypeMap(Injector
injector) {
+ return (Map<TypeLiteral, BeanTypeKey>) injector.getInstance(MAP_KEY);
+ }
+
+ private static Key<?> createDependencyKey(PropertyDescriptor
propertyDescriptor, Type propertyType) {
+ if(requiresName(propertyType)) {
+ return Key.get(propertyType, Names.named("shiro." +
propertyDescriptor.getName()));
+ } else {
+ return Key.get(propertyType);
+ }
+ }
+
private static boolean requiresName(Type propertyType) {
if (propertyType instanceof Class) {
Class<?> aClass = (Class<?>) propertyType;
@@ -90,4 +117,24 @@ class BeanTypeListener implements TypeLi
return false;
}
}
+
+ static void ensureBeanTypeMapExists(Binder binder) {
+
beanTypeMapBinding(binder).addBinding(TypeLiteral.get(BeanTypeKey.class)).toInstance(new
BeanTypeKey(null));
+ }
+
+ static <T> void bindBeanType(Binder binder, TypeLiteral<T> typeLiteral,
Key<? extends T> key) {
+ beanTypeMapBinding(binder).addBinding(typeLiteral).toInstance(new
BeanTypeKey(key));
+ }
+
+ private static MapBinder<TypeLiteral, BeanTypeKey>
beanTypeMapBinding(Binder binder) {
+ return MapBinder.newMapBinder(binder, TypeLiteral.class,
BeanTypeKey.class, Names.named(BEAN_TYPE_MAP_NAME));
+ }
+
+ private static class BeanTypeKey {
+ Key<?> key;
+
+ private BeanTypeKey(Key<?> key) {
+ this.key = key;
+ }
+ }
}
Modified:
shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/ShiroModule.java
URL:
http://svn.apache.org/viewvc/shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/ShiroModule.java?rev=1154256&r1=1154255&r2=1154256&view=diff
==============================================================================
---
shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/ShiroModule.java
(original)
+++
shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/ShiroModule.java
Fri Aug 5 15:05:28 2011
@@ -75,6 +75,7 @@ public abstract class ShiroModule extend
.to(realmSetKey());
bind(DestroyableInjectionListener.DestroyableRegistry.class).toInstance(registry);
+ BeanTypeListener.ensureBeanTypeMapExists(binder());
}
@SuppressWarnings({"unchecked"})
@@ -141,6 +142,16 @@ public abstract class ShiroModule extend
}
/**
+ * Binds a key to use for injecting setters in shiro classes.
+ * @param typeLiteral the bean property type
+ * @param key the key to use to satisfy the bean property dependency
+ * @param <T>
+ */
+ protected final <T> void bindBeanType(TypeLiteral<T> typeLiteral, Key<?
extends T> key) {
+ BeanTypeListener.bindBeanType(binder(), typeLiteral, key);
+ }
+
+ /**
* Destroys all beans created within this module that implement {@link
org.apache.shiro.util.Destroyable}. Should be called when this
* module will no longer be used.
*
Modified:
shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/web/ShiroWebModule.java
URL:
http://svn.apache.org/viewvc/shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/web/ShiroWebModule.java?rev=1154256&r1=1154255&r2=1154256&view=diff
==============================================================================
---
shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/web/ShiroWebModule.java
(original)
+++
shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/web/ShiroWebModule.java
Fri Aug 5 15:05:28 2011
@@ -116,6 +116,7 @@ public abstract class ShiroWebModule ext
@Override
protected final void configureShiro() {
+ bindBeanType(TypeLiteral.get(ServletContext.class),
Key.get(ServletContext.class, Names.named(NAME)));
bind(Key.get(ServletContext.class,
Names.named(NAME))).toInstance(this.servletContext);
bindWebSecurityManager(bind(WebSecurityManager.class));
bindWebEnvironment(bind(WebEnvironment.class));
Modified:
shiro/trunk/support/guice/src/test/java/org/apache/shiro/guice/BeanTypeListenerTest.java
URL:
http://svn.apache.org/viewvc/shiro/trunk/support/guice/src/test/java/org/apache/shiro/guice/BeanTypeListenerTest.java?rev=1154256&r1=1154255&r2=1154256&view=diff
==============================================================================
---
shiro/trunk/support/guice/src/test/java/org/apache/shiro/guice/BeanTypeListenerTest.java
(original)
+++
shiro/trunk/support/guice/src/test/java/org/apache/shiro/guice/BeanTypeListenerTest.java
Fri Aug 5 15:05:28 2011
@@ -83,6 +83,7 @@ public class BeanTypeListenerTest {
expect(injector.getInstance(Key.get(String.class,
Names.named("shiro.myProperty")))).andReturn(property);
expect(injector.getInstance(Key.get(String.class,
Names.named("shiro.unavailableProperty"))))
.andThrow(new ConfigurationException(Collections.singleton(new
Message("Not Available!"))));
+
expect(injector.getInstance(BeanTypeListener.MAP_KEY)).andReturn(Collections.EMPTY_MAP).anyTimes();
control.replay();