You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shiro.apache.org by ka...@apache.org on 2011/07/18 13:10:55 UTC
svn commit: r1147810 [1/2] - in /shiro/trunk: ./ all/ support/
support/guice/ support/guice/src/ support/guice/src/main/
support/guice/src/main/java/ support/guice/src/main/java/org/
support/guice/src/main/java/org/apache/ support/guice/src/main/java/o...
Author: kaosko
Date: Mon Jul 18 11:10:51 2011
New Revision: 1147810
URL: http://svn.apache.org/viewvc?rev=1147810&view=rev
Log:
SHIRO-23 - Integrating Jsecurity with Guice:
- apply Jared Bunting's guice-final.patch with no other changes but added license info
- rat run passes
Added:
shiro/trunk/support/guice/ (with props)
shiro/trunk/support/guice/pom.xml
shiro/trunk/support/guice/src/
shiro/trunk/support/guice/src/main/
shiro/trunk/support/guice/src/main/java/
shiro/trunk/support/guice/src/main/java/org/
shiro/trunk/support/guice/src/main/java/org/apache/
shiro/trunk/support/guice/src/main/java/org/apache/shiro/
shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/
shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/BeanTypeListener.java
shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/DestroyableInjectionListener.java
shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/GuiceEnvironment.java
shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/InitializableInjectionListener.java
shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/LifecycleTypeListener.java
shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/ShiroMatchers.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/ShiroSessionScope.java
shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/aop/
shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/aop/AopAllianceMethodInterceptorAdapter.java
shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/aop/AopAllianceMethodInvocationAdapter.java
shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/aop/ShiroAopModule.java
shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/web/
shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/web/AbstractInjectionProvider.java
shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/web/FilterChainResolverProvider.java
shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/web/GuiceShiroFilter.java
shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/web/PathMatchingFilterProvider.java
shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/web/ShiroWebModule.java
shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/web/SimpleFilterChain.java
shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/web/SimpleFilterChainResolver.java
shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/web/WebGuiceEnvironment.java
shiro/trunk/support/guice/src/test/
shiro/trunk/support/guice/src/test/java/
shiro/trunk/support/guice/src/test/java/org/
shiro/trunk/support/guice/src/test/java/org/apache/
shiro/trunk/support/guice/src/test/java/org/apache/shiro/
shiro/trunk/support/guice/src/test/java/org/apache/shiro/guice/
shiro/trunk/support/guice/src/test/java/org/apache/shiro/guice/BeanTypeListenerTest.java
shiro/trunk/support/guice/src/test/java/org/apache/shiro/guice/DestroyableInjectionListenerTest.java
shiro/trunk/support/guice/src/test/java/org/apache/shiro/guice/GuiceEnvironmentTest.java
shiro/trunk/support/guice/src/test/java/org/apache/shiro/guice/InitializableInjectionListenerTest.java
shiro/trunk/support/guice/src/test/java/org/apache/shiro/guice/LifecycleTypeListenerTest.java
shiro/trunk/support/guice/src/test/java/org/apache/shiro/guice/ShiroMatchersTest.java
shiro/trunk/support/guice/src/test/java/org/apache/shiro/guice/ShiroModuleTest.java
shiro/trunk/support/guice/src/test/java/org/apache/shiro/guice/ShiroSessionScopeTest.java
shiro/trunk/support/guice/src/test/java/org/apache/shiro/guice/aop/
shiro/trunk/support/guice/src/test/java/org/apache/shiro/guice/aop/AopAllianceMethodInterceptorAdapterTest.java
shiro/trunk/support/guice/src/test/java/org/apache/shiro/guice/aop/AopAllianceMethodInvocationAdapterTest.java
shiro/trunk/support/guice/src/test/java/org/apache/shiro/guice/aop/ShiroAopModuleTest.java
shiro/trunk/support/guice/src/test/java/org/apache/shiro/guice/web/
shiro/trunk/support/guice/src/test/java/org/apache/shiro/guice/web/AbstractInjectionProviderTest.java
shiro/trunk/support/guice/src/test/java/org/apache/shiro/guice/web/DefaultFiltersTest.java
shiro/trunk/support/guice/src/test/java/org/apache/shiro/guice/web/FilterChainResolverProviderTest.java
shiro/trunk/support/guice/src/test/java/org/apache/shiro/guice/web/FilterConfigTest.java
shiro/trunk/support/guice/src/test/java/org/apache/shiro/guice/web/GuiceShiroFilterTest.java
shiro/trunk/support/guice/src/test/java/org/apache/shiro/guice/web/PathMatchingFilterProviderTest.java
shiro/trunk/support/guice/src/test/java/org/apache/shiro/guice/web/ShiroWebModuleTest.java
shiro/trunk/support/guice/src/test/java/org/apache/shiro/guice/web/SimpleFilterChainResolverTest.java
shiro/trunk/support/guice/src/test/java/org/apache/shiro/guice/web/SimpleFilterChainTest.java
shiro/trunk/support/guice/src/test/java/org/apache/shiro/guice/web/WebGuiceEnvironmentTest.java
Modified:
shiro/trunk/all/pom.xml
shiro/trunk/pom.xml
shiro/trunk/support/pom.xml
Modified: shiro/trunk/all/pom.xml
URL: http://svn.apache.org/viewvc/shiro/trunk/all/pom.xml?rev=1147810&r1=1147809&r2=1147810&view=diff
==============================================================================
--- shiro/trunk/all/pom.xml (original)
+++ shiro/trunk/all/pom.xml Mon Jul 18 11:10:51 2011
@@ -53,6 +53,10 @@
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.apache.shiro</groupId>
+ <artifactId>shiro-guice</artifactId>
+ </dependency>
</dependencies>
<build>
Modified: shiro/trunk/pom.xml
URL: http://svn.apache.org/viewvc/shiro/trunk/pom.xml?rev=1147810&r1=1147809&r2=1147810&view=diff
==============================================================================
--- shiro/trunk/pom.xml (original)
+++ shiro/trunk/pom.xml Mon Jul 18 11:10:51 2011
@@ -85,6 +85,8 @@
<quartz.version>1.6.1</quartz.version>
<slf4j.version>1.6.1</slf4j.version>
<spring.version>3.0.5.RELEASE</spring.version>
+ <guice.version>3.0</guice.version>
+ <guava.version>r09</guava.version>
<!-- Test 3rd-party dependencies: -->
<easymock.version>3.0</easymock.version>
@@ -460,6 +462,11 @@
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
+ <artifactId>shiro-guice</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.shiro</groupId>
<artifactId>shiro-aspectj</artifactId>
<version>${project.version}</version>
</dependency>
@@ -750,6 +757,26 @@
</exclusions>
</dependency>
<dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ <version>${guava.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.google.inject</groupId>
+ <artifactId>guice</artifactId>
+ <version>${guice.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.google.inject.extensions</groupId>
+ <artifactId>guice-multibindings</artifactId>
+ <version>${guice.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.google.inject.extensions</groupId>
+ <artifactId>guice-servlet</artifactId>
+ <version>${guice.version}</version>
+ </dependency>
+ <dependency>
<groupId>org.opensymphony.quartz</groupId>
<artifactId>quartz</artifactId>
<version>${quartz.version}</version>
Propchange: shiro/trunk/support/guice/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Mon Jul 18 11:10:51 2011
@@ -0,0 +1 @@
+target
Added: shiro/trunk/support/guice/pom.xml
URL: http://svn.apache.org/viewvc/shiro/trunk/support/guice/pom.xml?rev=1147810&view=auto
==============================================================================
--- shiro/trunk/support/guice/pom.xml (added)
+++ shiro/trunk/support/guice/pom.xml Mon Jul 18 11:10:51 2011
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ 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.
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <parent>
+ <groupId>org.apache.shiro</groupId>
+ <artifactId>shiro-root</artifactId>
+ <version>1.2.0-SNAPSHOT</version>
+ <relativePath>../../pom.xml</relativePath>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>shiro-guice</artifactId>
+ <name>Apache Shiro :: Support :: Guice</name>
+ <packaging>bundle</packaging>
+
+ <properties>
+ <guice.version>3.0</guice.version>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.shiro</groupId>
+ <artifactId>shiro-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.shiro</groupId>
+ <artifactId>shiro-web</artifactId>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.google.inject</groupId>
+ <artifactId>guice</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.google.inject.extensions</groupId>
+ <artifactId>guice-multibindings</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.google.inject.extensions</groupId>
+ <artifactId>guice-servlet</artifactId>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>jcl-over-slf4j</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Bundle-SymbolicName>org.apache.shiro.guice</Bundle-SymbolicName>
+ <Export-Package>org.apache.shiro.guice*;version=${project.version}</Export-Package>
+ <Import-Package>
+ org.apache.shiro*;version="${shiro.osgi.importRange}",
+ org.aopalliance*;version="[1.0.0, 2.0.0)",
+ com.google.inject*;version="[3.0.0, 4.0.0)",
+ *
+ </Import-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
Added: 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=1147810&view=auto
==============================================================================
--- shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/BeanTypeListener.java (added)
+++ shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/BeanTypeListener.java Mon Jul 18 11:10:51 2011
@@ -0,0 +1,93 @@
+/*
+ * 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.shiro.guice;
+
+import com.google.common.primitives.Primitives;
+import com.google.inject.*;
+import com.google.inject.matcher.Matcher;
+import com.google.inject.matcher.Matchers;
+import com.google.inject.name.Names;
+import com.google.inject.spi.TypeEncounter;
+import com.google.inject.spi.TypeListener;
+import org.apache.commons.beanutils.PropertyUtils;
+import org.apache.shiro.SecurityUtils;
+
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Type;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * TypeListener that injects setter methods on Shiro objects.
+ */
+class BeanTypeListener implements TypeListener {
+ public static final Package SHIRO_GUICE_PACKAGE = ShiroModule.class.getPackage();
+ public static final Package SHIRO_PACKAGE = SecurityUtils.class.getPackage();
+
+ private static Matcher<Class> shiroMatcher = Matchers.inSubpackage(SHIRO_PACKAGE.getName());
+ private static Matcher<Class> shiroGuiceMatcher = Matchers.inSubpackage(SHIRO_GUICE_PACKAGE.getName());
+
+ private static Matcher<Class> classMatcher = ShiroMatchers.ANY_PACKAGE.and(shiroMatcher.and(Matchers.not(shiroGuiceMatcher)));
+
+ public static final Matcher<TypeLiteral> MATCHER = ShiroMatchers.typeLiteral(classMatcher);
+
+ 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);
+ final Provider<Injector> injectorProvider = encounter.getProvider(Injector.class);
+ 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));
+ }
+ }
+ 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());
+ dependency.getKey().getWriteMethod().invoke(instance, value);
+
+ } catch (ConfigurationException e) {
+ // This is ok, it simply means that we can't fulfill this dependency.
+ // Is there a better way to do this?
+ } catch (InvocationTargetException e) {
+ throw new RuntimeException("Couldn't set property " + dependency.getKey().getDisplayName(), e);
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException("We shouldn't have ever reached this point, we don't try to inject to non-accessible methods.", e);
+ }
+ }
+
+ }
+ });
+ }
+
+ private static boolean requiresName(Type propertyType) {
+ if (propertyType instanceof Class) {
+ Class<?> aClass = (Class<?>) propertyType;
+ return aClass.isPrimitive() || aClass.isEnum() || Primitives.isWrapperType(aClass) || CharSequence.class.isAssignableFrom(aClass);
+ } else {
+ return false;
+ }
+ }
+}
Added: shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/DestroyableInjectionListener.java
URL: http://svn.apache.org/viewvc/shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/DestroyableInjectionListener.java?rev=1147810&view=auto
==============================================================================
--- shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/DestroyableInjectionListener.java (added)
+++ shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/DestroyableInjectionListener.java Mon Jul 18 11:10:51 2011
@@ -0,0 +1,48 @@
+/*
+ * 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.shiro.guice;
+
+import com.google.inject.TypeLiteral;
+import com.google.inject.matcher.Matcher;
+import com.google.inject.matcher.Matchers;
+import com.google.inject.spi.InjectionListener;
+import org.apache.shiro.util.Destroyable;
+
+/**
+ * Injection listener that assists with honoring the {@link org.apache.shiro.util.Destroyable} interface.
+ *
+ * @param <I>
+ */
+class DestroyableInjectionListener<I extends Destroyable> implements InjectionListener<I> {
+ public static final Matcher<TypeLiteral> MATCHER = ShiroMatchers.typeLiteral(Matchers.subclassesOf(Destroyable.class));
+
+ private DestroyableRegistry registry;
+
+ public DestroyableInjectionListener(DestroyableRegistry registry) {
+ this.registry = registry;
+ }
+
+ public void afterInjection(Destroyable injectee) {
+ registry.add(injectee);
+ }
+
+ public static interface DestroyableRegistry {
+ void add(Destroyable destroyable);
+ }
+}
Added: shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/GuiceEnvironment.java
URL: http://svn.apache.org/viewvc/shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/GuiceEnvironment.java?rev=1147810&view=auto
==============================================================================
--- shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/GuiceEnvironment.java (added)
+++ shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/GuiceEnvironment.java Mon Jul 18 11:10:51 2011
@@ -0,0 +1,36 @@
+/*
+ * 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.shiro.guice;
+
+import com.google.inject.Inject;
+import org.apache.shiro.env.Environment;
+import org.apache.shiro.mgt.SecurityManager;
+
+class GuiceEnvironment implements Environment {
+ private SecurityManager securityManager;
+
+ @Inject
+ public GuiceEnvironment(SecurityManager securityManager) {
+ this.securityManager = securityManager;
+ }
+
+ public SecurityManager getSecurityManager() {
+ return securityManager;
+ }
+}
Added: shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/InitializableInjectionListener.java
URL: http://svn.apache.org/viewvc/shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/InitializableInjectionListener.java?rev=1147810&view=auto
==============================================================================
--- shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/InitializableInjectionListener.java (added)
+++ shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/InitializableInjectionListener.java Mon Jul 18 11:10:51 2011
@@ -0,0 +1,38 @@
+/*
+ * 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.shiro.guice;
+
+import com.google.inject.TypeLiteral;
+import com.google.inject.matcher.Matcher;
+import com.google.inject.matcher.Matchers;
+import com.google.inject.spi.InjectionListener;
+import org.apache.shiro.util.Initializable;
+
+/**
+ * Injection listener that honors the {@link org.apache.shiro.util.Initializable} interface.
+ *
+ * @param <I>
+ */
+class InitializableInjectionListener<I extends Initializable> implements InjectionListener<I> {
+ public static final Matcher<TypeLiteral> MATCHER = ShiroMatchers.typeLiteral(Matchers.subclassesOf(Initializable.class));
+
+ public void afterInjection(Initializable injectee) {
+ injectee.init();
+ }
+}
Added: shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/LifecycleTypeListener.java
URL: http://svn.apache.org/viewvc/shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/LifecycleTypeListener.java?rev=1147810&view=auto
==============================================================================
--- shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/LifecycleTypeListener.java (added)
+++ shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/LifecycleTypeListener.java Mon Jul 18 11:10:51 2011
@@ -0,0 +1,51 @@
+/*
+ * 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.shiro.guice;
+
+import com.google.inject.TypeLiteral;
+import com.google.inject.matcher.Matcher;
+import com.google.inject.spi.InjectionListener;
+import com.google.inject.spi.TypeEncounter;
+import com.google.inject.spi.TypeListener;
+import org.apache.shiro.util.Destroyable;
+import org.apache.shiro.util.Initializable;
+
+
+class LifecycleTypeListener implements TypeListener {
+ public static final Matcher<TypeLiteral> MATCHER = InitializableInjectionListener.MATCHER.or(DestroyableInjectionListener.MATCHER);
+ private DestroyableInjectionListener.DestroyableRegistry registry;
+
+ public LifecycleTypeListener(DestroyableInjectionListener.DestroyableRegistry registry) {
+ this.registry = registry;
+ }
+
+ public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) {
+ if (InitializableInjectionListener.MATCHER.matches(type)) {
+ encounter.register(this.<I>castListener(new InitializableInjectionListener<Initializable>()));
+ }
+ if (DestroyableInjectionListener.MATCHER.matches(type)) {
+ encounter.register(this.<I>castListener(new DestroyableInjectionListener<Destroyable>(registry)));
+ }
+ }
+
+ @SuppressWarnings({"unchecked"})
+ private <I> InjectionListener<? super I> castListener(InjectionListener<?> listener) {
+ return (InjectionListener<? super I>) listener;
+ }
+}
Added: shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/ShiroMatchers.java
URL: http://svn.apache.org/viewvc/shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/ShiroMatchers.java?rev=1147810&view=auto
==============================================================================
--- shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/ShiroMatchers.java (added)
+++ shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/ShiroMatchers.java Mon Jul 18 11:10:51 2011
@@ -0,0 +1,41 @@
+/*
+ * 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.shiro.guice;
+
+import com.google.inject.TypeLiteral;
+import com.google.inject.matcher.AbstractMatcher;
+import com.google.inject.matcher.Matcher;
+
+class ShiroMatchers {
+ public static Matcher<Class> ANY_PACKAGE = new AbstractMatcher<Class>() {
+
+ public boolean matches(Class aClass) {
+ return aClass.getPackage() != null;
+ }
+ };
+
+ public static Matcher<TypeLiteral> typeLiteral(final Matcher<Class> classMatcher) {
+ return new AbstractMatcher<TypeLiteral>() {
+
+ public boolean matches(TypeLiteral typeLiteral) {
+ return classMatcher.matches(typeLiteral.getRawType());
+ }
+ };
+ }
+}
Added: 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=1147810&view=auto
==============================================================================
--- shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/ShiroModule.java (added)
+++ shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/ShiroModule.java Mon Jul 18 11:10:51 2011
@@ -0,0 +1,158 @@
+/*
+ * 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.shiro.guice;
+
+import com.google.common.collect.Sets;
+import com.google.inject.Key;
+import com.google.inject.PrivateModule;
+import com.google.inject.TypeLiteral;
+import com.google.inject.binder.AnnotatedBindingBuilder;
+import com.google.inject.binder.LinkedBindingBuilder;
+import com.google.inject.multibindings.Multibinder;
+import com.google.inject.util.Types;
+import org.apache.shiro.config.ConfigurationException;
+import org.apache.shiro.env.Environment;
+import org.apache.shiro.mgt.DefaultSecurityManager;
+import org.apache.shiro.mgt.SecurityManager;
+import org.apache.shiro.realm.Realm;
+import org.apache.shiro.session.mgt.DefaultSessionManager;
+import org.apache.shiro.session.mgt.SessionManager;
+import org.apache.shiro.util.Destroyable;
+
+import javax.annotation.PreDestroy;
+import java.util.Collection;
+import java.util.Set;
+import java.util.WeakHashMap;
+
+
+/**
+ * Sets up Shiro lifecycles within Guice, enables the injecting of Shiro objects, and binds a default
+ * {@link org.apache.shiro.mgt.SecurityManager} and {@link org.apache.shiro.session.mgt.SessionManager}. At least one realm must be added by using
+ * {@link #bindRealm() bindRealm}.
+ */
+public abstract class ShiroModule extends PrivateModule implements Destroyable {
+
+ private Set<Destroyable> destroyables = Sets.newSetFromMap(new WeakHashMap<Destroyable, Boolean>());
+
+ public void configure() {
+ // setup security manager
+ bindSecurityManager(bind(SecurityManager.class));
+ bindSessionManager(bind(SessionManager.class));
+ bindEnvironment(bind(Environment.class));
+ bindListener(BeanTypeListener.MATCHER, new BeanTypeListener());
+ final DestroyableInjectionListener.DestroyableRegistry registry = new DestroyableInjectionListener.DestroyableRegistry() {
+ public void add(Destroyable destroyable) {
+ ShiroModule.this.add(destroyable);
+ }
+
+ @PreDestroy
+ public void destroy() throws Exception {
+ ShiroModule.this.destroy();
+ }
+ };
+ bindListener(LifecycleTypeListener.MATCHER, new LifecycleTypeListener(registry));
+
+ expose(SecurityManager.class);
+
+ configureShiro();
+ bind(realmCollectionKey())
+ .to(realmSetKey());
+
+ bind(DestroyableInjectionListener.DestroyableRegistry.class).toInstance(registry);
+ }
+
+ @SuppressWarnings({"unchecked"})
+ private Key<Set<Realm>> realmSetKey() {
+ return (Key<Set<Realm>>) Key.get(TypeLiteral.get(Types.setOf(Realm.class)));
+ }
+
+ @SuppressWarnings({"unchecked"})
+ private Key<Collection<Realm>> realmCollectionKey() {
+ return (Key<Collection<Realm>>) Key.get(Types.newParameterizedType(Collection.class, Realm.class));
+ }
+
+ /**
+ * Implement this method in order to configure your realms and any other Shiro customization you may need.
+ */
+ protected abstract void configureShiro();
+
+ /**
+ * This is the preferred manner to bind a realm. The {@link org.apache.shiro.mgt.SecurityManager} will be injected with any Realm bound
+ * with this method.
+ *
+ * @return a binding builder for a realm
+ */
+ protected final LinkedBindingBuilder<Realm> bindRealm() {
+ Multibinder<Realm> multibinder = Multibinder.newSetBinder(binder(), Realm.class);
+ return multibinder.addBinding();
+ }
+
+ /**
+ * Binds the security manager. Override this method in order to provide your own security manager binding.
+ * <p/>
+ * By default, a {@link org.apache.shiro.mgt.DefaultSecurityManager} is bound as an eager singleton.
+ *
+ * @param bind
+ */
+ protected void bindSecurityManager(AnnotatedBindingBuilder<? super SecurityManager> bind) {
+ try {
+ bind.toConstructor(DefaultSecurityManager.class.getConstructor(Collection.class)).asEagerSingleton();
+ } catch (NoSuchMethodException e) {
+ throw new ConfigurationException("This really shouldn't happen. Either something has changed in Shiro, or there's a bug in " + ShiroModule.class.getSimpleName(), e);
+ }
+ }
+
+ /**
+ * Binds the session manager. Override this method in order to provide your own session manager binding.
+ * <p/>
+ * By default, a {@link org.apache.shiro.session.mgt.DefaultSessionManager} is bound as an eager singleton.
+ *
+ * @param bind
+ */
+ protected void bindSessionManager(AnnotatedBindingBuilder<SessionManager> bind) {
+ bind.to(DefaultSessionManager.class).asEagerSingleton();
+ }
+
+ /**
+ * Binds the environment. Override this method in order to provide your own environment binding.
+ * <p/>
+ * By default, a {@link GuiceEnvironment} is bound as an eager singleton.
+ *
+ * @param bind
+ */
+ protected void bindEnvironment(AnnotatedBindingBuilder<Environment> bind) {
+ bind.to(GuiceEnvironment.class).asEagerSingleton();
+ }
+
+ /**
+ * 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.
+ *
+ * @throws Exception
+ */
+ public final void destroy() throws Exception {
+ for (Destroyable destroyable : destroyables) {
+ destroyable.destroy();
+ }
+ }
+
+ public void add(Destroyable destroyable) {
+ this.destroyables.add(destroyable);
+ }
+}
Added: shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/ShiroSessionScope.java
URL: http://svn.apache.org/viewvc/shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/ShiroSessionScope.java?rev=1147810&view=auto
==============================================================================
--- shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/ShiroSessionScope.java (added)
+++ shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/ShiroSessionScope.java Mon Jul 18 11:10:51 2011
@@ -0,0 +1,64 @@
+/*
+ * 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.shiro.guice;
+
+import com.google.inject.Key;
+import com.google.inject.OutOfScopeException;
+import com.google.inject.Provider;
+import com.google.inject.Scope;
+import org.apache.shiro.session.Session;
+import org.apache.shiro.subject.Subject;
+import org.apache.shiro.util.ThreadContext;
+
+/**
+ * Guice scope for Shiro sessions. Not bound by default.
+ */
+public class ShiroSessionScope implements Scope {
+ public <T> Provider<T> scope(final Key<T> key, final Provider<T> unscoped) {
+ return new Provider<T>() {
+ public T get() {
+ Subject subject = ThreadContext.getSubject();
+ if (subject == null) {
+ throw new OutOfScopeException("There is no Shiro Session currently in scope.");
+ }
+ Session session = subject.getSession();
+ T scoped = castSessionAttribute(session);
+ if (scoped == null) {
+ scoped = unscoped.get();
+ }
+ return scoped;
+ }
+
+ @SuppressWarnings({"unchecked"})
+ private T castSessionAttribute(Session session) {
+ return (T) session.getAttribute(key);
+ }
+
+ @Override
+ public String toString() {
+ return unscoped.toString();
+ }
+ };
+ }
+
+ @Override
+ public String toString() {
+ return "ShiroSessionScope";
+ }
+}
Added: shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/aop/AopAllianceMethodInterceptorAdapter.java
URL: http://svn.apache.org/viewvc/shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/aop/AopAllianceMethodInterceptorAdapter.java?rev=1147810&view=auto
==============================================================================
--- shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/aop/AopAllianceMethodInterceptorAdapter.java (added)
+++ shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/aop/AopAllianceMethodInterceptorAdapter.java Mon Jul 18 11:10:51 2011
@@ -0,0 +1,43 @@
+/*
+ * 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.shiro.guice.aop;
+
+import org.aopalliance.intercept.MethodInterceptor;
+import org.aopalliance.intercept.MethodInvocation;
+
+/**
+ * Adapts a Shiro {@link org.apache.shiro.aop.MethodInterceptor MethodInterceptor} to an AOPAlliance
+ * {@link org.aopalliance.intercept.MethodInterceptor}.
+ */
+class AopAllianceMethodInterceptorAdapter implements MethodInterceptor {
+ org.apache.shiro.aop.MethodInterceptor shiroInterceptor;
+
+ public AopAllianceMethodInterceptorAdapter(org.apache.shiro.aop.MethodInterceptor shiroInterceptor) {
+ this.shiroInterceptor = shiroInterceptor;
+ }
+
+ public Object invoke(MethodInvocation invocation) throws Throwable {
+ return shiroInterceptor.invoke(new AopAllianceMethodInvocationAdapter(invocation));
+ }
+
+ @Override
+ public String toString() {
+ return "AopAlliance Adapter for " + shiroInterceptor.toString();
+ }
+}
Added: shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/aop/AopAllianceMethodInvocationAdapter.java
URL: http://svn.apache.org/viewvc/shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/aop/AopAllianceMethodInvocationAdapter.java?rev=1147810&view=auto
==============================================================================
--- shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/aop/AopAllianceMethodInvocationAdapter.java (added)
+++ shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/aop/AopAllianceMethodInvocationAdapter.java Mon Jul 18 11:10:51 2011
@@ -0,0 +1,55 @@
+/*
+ * 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.shiro.guice.aop;
+
+import org.aopalliance.intercept.MethodInvocation;
+
+import java.lang.reflect.Method;
+
+/**
+ * Adapts a Shiro {@link org.apache.shiro.aop.MethodInvocation MethodInvocation} to an AOPAlliance
+ * {@link org.aopalliance.intercept.MethodInvocation}.
+ */
+class AopAllianceMethodInvocationAdapter implements org.apache.shiro.aop.MethodInvocation {
+ private final MethodInvocation mi;
+
+ public AopAllianceMethodInvocationAdapter(MethodInvocation mi) {
+ this.mi = mi;
+ }
+
+ public Method getMethod() {
+ return mi.getMethod();
+ }
+
+ public Object[] getArguments() {
+ return mi.getArguments();
+ }
+
+ public String toString() {
+ return "Method invocation [" + mi.getMethod() + "]";
+ }
+
+ public Object proceed() throws Throwable {
+ return mi.proceed();
+ }
+
+ public Object getThis() {
+ return mi.getThis();
+ }
+}
Added: shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/aop/ShiroAopModule.java
URL: http://svn.apache.org/viewvc/shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/aop/ShiroAopModule.java?rev=1147810&view=auto
==============================================================================
--- shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/aop/ShiroAopModule.java (added)
+++ shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/aop/ShiroAopModule.java Mon Jul 18 11:10:51 2011
@@ -0,0 +1,69 @@
+/*
+ * 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.shiro.guice.aop;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.matcher.AbstractMatcher;
+import com.google.inject.matcher.Matchers;
+import org.apache.shiro.aop.AnnotationMethodInterceptor;
+import org.apache.shiro.aop.AnnotationResolver;
+import org.apache.shiro.aop.DefaultAnnotationResolver;
+import org.apache.shiro.authz.aop.*;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+
+/**
+ * Install this module to enable Shiro AOP functionality in Guice. You may extend it to add your own Shiro
+ * interceptors, override the default ones, or provide a specific {@link org.apache.shiro.aop.AnnotationResolver}.
+ */
+public class ShiroAopModule extends AbstractModule {
+ @Override
+ protected final void configure() {
+ AnnotationResolver resolver = createAnnotationResolver();
+ configureDefaultInterceptors(resolver);
+ configureInterceptors(resolver);
+ }
+
+ protected final void bindShiroInterceptor(final AnnotationMethodInterceptor methodInterceptor) {
+ bindInterceptor(Matchers.any(), new AbstractMatcher<Method>() {
+ public boolean matches(Method method) {
+ Class<? extends Annotation> annotation = methodInterceptor.getHandler().getAnnotationClass();
+ return method.getAnnotation(annotation) != null
+ || method.getDeclaringClass().getAnnotation(annotation) != null;
+ }
+ }, new AopAllianceMethodInterceptorAdapter(methodInterceptor));
+ }
+
+ protected AnnotationResolver createAnnotationResolver() {
+ return new DefaultAnnotationResolver();
+ }
+
+ protected void configureDefaultInterceptors(AnnotationResolver resolver) {
+ bindShiroInterceptor(new RoleAnnotationMethodInterceptor(resolver));
+ bindShiroInterceptor(new PermissionAnnotationMethodInterceptor(resolver));
+ bindShiroInterceptor(new AuthenticatedAnnotationMethodInterceptor(resolver));
+ bindShiroInterceptor(new UserAnnotationMethodInterceptor(resolver));
+ bindShiroInterceptor(new GuestAnnotationMethodInterceptor(resolver));
+ }
+
+ protected void configureInterceptors(AnnotationResolver resolver) {
+
+ }
+}
Added: shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/web/AbstractInjectionProvider.java
URL: http://svn.apache.org/viewvc/shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/web/AbstractInjectionProvider.java?rev=1147810&view=auto
==============================================================================
--- shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/web/AbstractInjectionProvider.java (added)
+++ shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/web/AbstractInjectionProvider.java Mon Jul 18 11:10:51 2011
@@ -0,0 +1,83 @@
+/*
+ * 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.shiro.guice.web;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+import com.google.inject.Key;
+import com.google.inject.ProvisionException;
+import com.google.inject.spi.Dependency;
+import com.google.inject.spi.InjectionPoint;
+import com.google.inject.spi.ProviderWithDependencies;
+
+import java.lang.reflect.Constructor;
+import java.util.Set;
+
+class AbstractInjectionProvider<T> implements ProviderWithDependencies<T> {
+ private Key<T> key;
+
+ @Inject
+ Injector injector;
+
+ private InjectionPoint constructorInjectionPoint;
+ private Set<Dependency<?>> dependencies;
+
+ public AbstractInjectionProvider(Key<T> key) {
+ this.key = key;
+ constructorInjectionPoint = InjectionPoint.forConstructorOf(key.getTypeLiteral());
+
+ ImmutableSet.Builder<Dependency<?>> dependencyBuilder = ImmutableSet.builder();
+ dependencyBuilder.addAll(constructorInjectionPoint.getDependencies());
+ for (InjectionPoint injectionPoint : InjectionPoint.forInstanceMethodsAndFields(key.getTypeLiteral())) {
+ dependencyBuilder.addAll(injectionPoint.getDependencies());
+ }
+ this.dependencies = dependencyBuilder.build();
+ }
+
+ public T get() {
+ Constructor<T> constructor = getConstructor();
+ Object[] params = new Object[constructor.getParameterTypes().length];
+ for (Dependency<?> dependency : constructorInjectionPoint.getDependencies()) {
+ params[dependency.getParameterIndex()] = injector.getInstance(dependency.getKey());
+ }
+ T t;
+ try {
+ t = constructor.newInstance(params);
+ } catch (Exception e) {
+ throw new ProvisionException("Could not instantiate " + key + "", e);
+ }
+ injector.injectMembers(t);
+ return postProcess(t);
+ }
+
+ @SuppressWarnings({"unchecked"})
+ private Constructor<T> getConstructor() {
+ return (Constructor<T>) constructorInjectionPoint.getMember();
+ }
+
+ protected T postProcess(T t) {
+ // do nothing by default
+ return t;
+ }
+
+ public Set<Dependency<?>> getDependencies() {
+ return dependencies;
+ }
+}
Added: shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/web/FilterChainResolverProvider.java
URL: http://svn.apache.org/viewvc/shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/web/FilterChainResolverProvider.java?rev=1147810&view=auto
==============================================================================
--- shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/web/FilterChainResolverProvider.java (added)
+++ shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/web/FilterChainResolverProvider.java Mon Jul 18 11:10:51 2011
@@ -0,0 +1,71 @@
+/*
+ * 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.shiro.guice.web;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+import com.google.inject.Key;
+import com.google.inject.Singleton;
+import com.google.inject.spi.Dependency;
+import com.google.inject.spi.ProviderWithDependencies;
+import org.apache.shiro.util.AntPathMatcher;
+import org.apache.shiro.util.PatternMatcher;
+import org.apache.shiro.web.filter.mgt.FilterChainResolver;
+
+import javax.servlet.Filter;
+import java.util.Map;
+import java.util.Set;
+
+@Singleton
+class FilterChainResolverProvider implements ProviderWithDependencies<FilterChainResolver> {
+ @Inject
+ Injector injector;
+
+ private final Map<String, Key<? extends Filter>[]> chains;
+
+ private final Set<Dependency<?>> dependencies;
+
+ private PatternMatcher patternMatcher = new AntPathMatcher();
+
+ public FilterChainResolverProvider(Map<String, Key<? extends Filter>[]> chains) {
+ this.chains = chains;
+ ImmutableSet.Builder<Dependency<?>> dependenciesBuilder = ImmutableSet.builder();
+ for (String chain : chains.keySet()) {
+ for (Key<? extends Filter> filterKey : chains.get(chain)) {
+ dependenciesBuilder.add(Dependency.get(filterKey));
+ }
+ }
+ this.dependencies = dependenciesBuilder.build();
+ }
+
+ @Inject(optional = true)
+ public void setPatternMatcher(PatternMatcher patternMatcher) {
+ this.patternMatcher = patternMatcher;
+ }
+
+ public Set<Dependency<?>> getDependencies() {
+ return dependencies;
+ }
+
+ public FilterChainResolver get() {
+ return new SimpleFilterChainResolver(chains, injector, patternMatcher);
+ }
+
+}
Added: shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/web/GuiceShiroFilter.java
URL: http://svn.apache.org/viewvc/shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/web/GuiceShiroFilter.java?rev=1147810&view=auto
==============================================================================
--- shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/web/GuiceShiroFilter.java (added)
+++ shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/web/GuiceShiroFilter.java Mon Jul 18 11:10:51 2011
@@ -0,0 +1,38 @@
+/*
+ * 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.shiro.guice.web;
+
+import org.apache.shiro.web.filter.mgt.FilterChainResolver;
+import org.apache.shiro.web.mgt.WebSecurityManager;
+import org.apache.shiro.web.servlet.AbstractShiroFilter;
+
+import javax.inject.Inject;
+
+/**
+ * Shiro filter that is managed by and receives its filter chain configurations from Guice. The convenience method to
+ * map this filter to your application is
+ * {@link ShiroWebModule#bindGuiceFilter(com.google.inject.Binder) bindGuiceFilter}.
+ */
+public class GuiceShiroFilter extends AbstractShiroFilter {
+ @Inject
+ GuiceShiroFilter(WebSecurityManager webSecurityManager, FilterChainResolver filterChainResolver) {
+ this.setSecurityManager(webSecurityManager);
+ this.setFilterChainResolver(filterChainResolver);
+ }
+}
Added: shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/web/PathMatchingFilterProvider.java
URL: http://svn.apache.org/viewvc/shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/web/PathMatchingFilterProvider.java?rev=1147810&view=auto
==============================================================================
--- shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/web/PathMatchingFilterProvider.java (added)
+++ shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/web/PathMatchingFilterProvider.java Mon Jul 18 11:10:51 2011
@@ -0,0 +1,41 @@
+/*
+ * 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.shiro.guice.web;
+
+import com.google.inject.Key;
+import org.apache.shiro.web.filter.PathMatchingFilter;
+
+import java.util.Map;
+
+class PathMatchingFilterProvider<T extends PathMatchingFilter> extends AbstractInjectionProvider<T> {
+ private Map<String, String> pathConfigs;
+
+ public PathMatchingFilterProvider(Key<T> key, Map<String, String> pathConfigs) {
+ super(key);
+ this.pathConfigs = pathConfigs;
+ }
+
+ @Override
+ protected T postProcess(T filter) {
+ for (Map.Entry<String, String> pathConfig : this.pathConfigs.entrySet()) {
+ filter.processPathConfig(pathConfig.getKey(), pathConfig.getValue());
+ }
+ return filter;
+ }
+}
Added: 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=1147810&view=auto
==============================================================================
--- shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/web/ShiroWebModule.java (added)
+++ shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/web/ShiroWebModule.java Mon Jul 18 11:10:51 2011
@@ -0,0 +1,255 @@
+/*
+ * 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.shiro.guice.web;
+
+import com.google.common.collect.HashBasedTable;
+import com.google.common.collect.Table;
+import com.google.inject.Binder;
+import com.google.inject.Key;
+import com.google.inject.TypeLiteral;
+import com.google.inject.binder.AnnotatedBindingBuilder;
+import com.google.inject.name.Names;
+import com.google.inject.servlet.ServletModule;
+import org.apache.shiro.guice.ShiroModule;
+import org.apache.shiro.config.ConfigurationException;
+import org.apache.shiro.env.Environment;
+import org.apache.shiro.mgt.SecurityManager;
+import org.apache.shiro.session.mgt.SessionManager;
+import org.apache.shiro.web.env.WebEnvironment;
+import org.apache.shiro.web.filter.PathMatchingFilter;
+import org.apache.shiro.web.filter.authc.*;
+import org.apache.shiro.web.filter.authz.*;
+import org.apache.shiro.web.filter.mgt.FilterChainResolver;
+import org.apache.shiro.web.filter.session.NoSessionCreationFilter;
+import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
+import org.apache.shiro.web.mgt.WebSecurityManager;
+import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
+
+import javax.servlet.Filter;
+import javax.servlet.ServletContext;
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * Sets up Shiro lifecycles within Guice, enables the injecting of Shiro objects, and binds a default
+ * {@link org.apache.shiro.web.mgt.WebSecurityManager}, {@link org.apache.shiro.mgt.SecurityManager} and {@link org.apache.shiro.session.mgt.SessionManager}. At least one realm must be added by
+ * using {@link #bindRealm() bindRealm}.
+ * <p/>
+ * Also provides for the configuring of filter chains and binds a {@link org.apache.shiro.web.filter.mgt.FilterChainResolver} with that information.
+ */
+public abstract class ShiroWebModule extends ShiroModule {
+ @SuppressWarnings({"UnusedDeclaration"})
+ public static final Key<AnonymousFilter> ANON = Key.get(AnonymousFilter.class);
+ @SuppressWarnings({"UnusedDeclaration"})
+ public static final Key<FormAuthenticationFilter> AUTHC = Key.get(FormAuthenticationFilter.class);
+ @SuppressWarnings({"UnusedDeclaration"})
+ public static final Key<BasicHttpAuthenticationFilter> AUTHC_BASIC = Key.get(BasicHttpAuthenticationFilter.class);
+ @SuppressWarnings({"UnusedDeclaration"})
+ public static final Key<NoSessionCreationFilter> NO_SESSION_CREATION = Key.get(NoSessionCreationFilter.class);
+ @SuppressWarnings({"UnusedDeclaration"})
+ public static final Key<LogoutFilter> LOGOUT = Key.get(LogoutFilter.class);
+ @SuppressWarnings({"UnusedDeclaration"})
+ public static final Key<PermissionsAuthorizationFilter> PERMS = Key.get(PermissionsAuthorizationFilter.class);
+ @SuppressWarnings({"UnusedDeclaration"})
+ public static final Key<PortFilter> PORT = Key.get(PortFilter.class);
+ @SuppressWarnings({"UnusedDeclaration"})
+ public static final Key<HttpMethodPermissionFilter> REST = Key.get(HttpMethodPermissionFilter.class);
+ @SuppressWarnings({"UnusedDeclaration"})
+ public static final Key<RolesAuthorizationFilter> ROLES = Key.get(RolesAuthorizationFilter.class);
+ @SuppressWarnings({"UnusedDeclaration"})
+ public static final Key<SslFilter> SSL = Key.get(SslFilter.class);
+ @SuppressWarnings({"UnusedDeclaration"})
+ public static final Key<UserFilter> USER = Key.get(UserFilter.class);
+
+
+ static final String NAME = "SHIRO";
+
+ /**
+ * We use a LinkedHashMap here to ensure that iterator order is the same as add order. This is important, as the
+ * FilterChainResolver uses iterator order when searching for a matching chain.
+ */
+ private final Map<String, Key<? extends Filter>[]> filterChains = new LinkedHashMap<String, Key<? extends Filter>[]>();
+ private final ServletContext servletContext;
+
+ public ShiroWebModule(ServletContext servletContext) {
+ this.servletContext = servletContext;
+ }
+
+ public static void bindGuiceFilter(Binder binder) {
+ binder.install(guiceFilterModule());
+ }
+
+ @SuppressWarnings({"UnusedDeclaration"})
+ public static void bindGuiceFilter(final String pattern, Binder binder) {
+ binder.install(guiceFilterModule(pattern));
+ }
+
+ public static ServletModule guiceFilterModule() {
+ return guiceFilterModule("/*");
+ }
+
+ public static ServletModule guiceFilterModule(final String pattern) {
+ return new ServletModule() {
+ @Override
+ protected void configureServlets() {
+ filter(pattern).through(GuiceShiroFilter.class);
+ }
+ };
+ }
+
+ @Override
+ protected final void configureShiro() {
+ bind(Key.get(ServletContext.class, Names.named(NAME))).toInstance(this.servletContext);
+ bindWebSecurityManager(bind(WebSecurityManager.class));
+ bindWebEnvironment(bind(WebEnvironment.class));
+ bind(GuiceShiroFilter.class).asEagerSingleton();
+ expose(GuiceShiroFilter.class);
+
+ this.configureShiroWeb();
+
+ setupFilterChainConfigs();
+
+ bind(FilterChainResolver.class).toProvider(new FilterChainResolverProvider(filterChains));
+ }
+
+ private void setupFilterChainConfigs() {
+ Table<Key<? extends PathMatchingFilter>, String, String> configs = HashBasedTable.create();
+
+ for (Map.Entry<String, Key<? extends Filter>[]> filterChain : filterChains.entrySet()) {
+ for (int i = 0; i < filterChain.getValue().length; i++) {
+ Key<? extends Filter> key = filterChain.getValue()[i];
+ if (key instanceof FilterConfigKey) {
+ FilterConfigKey<? extends PathMatchingFilter> configKey = (FilterConfigKey<? extends PathMatchingFilter>) key;
+ key = configKey.getKey();
+ filterChain.getValue()[i] = key;
+ if (!PathMatchingFilter.class.isAssignableFrom(key.getTypeLiteral().getRawType())) {
+ throw new ConfigurationException("Config information requires a PathMatchingFilter - can't apply to " + key.getTypeLiteral().getRawType());
+ }
+ configs.put(castToPathMatching(key), filterChain.getKey(), configKey.getConfigValue());
+ } else if (PathMatchingFilter.class.isAssignableFrom(key.getTypeLiteral().getRawType())) {
+ configs.put(castToPathMatching(key), filterChain.getKey(), "");
+ }
+ }
+ }
+ for (Key<? extends PathMatchingFilter> filterKey : configs.rowKeySet()) {
+ bindPathMatchingFilter(filterKey, configs.row(filterKey));
+ }
+ }
+
+ private <T extends PathMatchingFilter> void bindPathMatchingFilter(Key<T> filterKey, Map<String, String> configs) {
+ bind(filterKey).toProvider(new PathMatchingFilterProvider<T>(filterKey, configs)).asEagerSingleton();
+ }
+
+ @SuppressWarnings({"unchecked"})
+ private Key<? extends PathMatchingFilter> castToPathMatching(Key<? extends Filter> key) {
+ return (Key<? extends PathMatchingFilter>) key;
+ }
+
+ protected abstract void configureShiroWeb();
+
+ @SuppressWarnings({"unchecked"})
+ @Override
+ protected final void bindSecurityManager(AnnotatedBindingBuilder<? super SecurityManager> bind) {
+ bindWebSecurityManager(bind);
+ }
+
+ /**
+ * Binds the security manager. Override this method in order to provide your own security manager binding.
+ * <p/>
+ * By default, a {@link org.apache.shiro.web.mgt.DefaultWebSecurityManager} is bound as an eager singleton.
+ *
+ * @param bind
+ */
+ protected void bindWebSecurityManager(AnnotatedBindingBuilder<? super WebSecurityManager> bind) {
+ try {
+ bind.toConstructor(DefaultWebSecurityManager.class.getConstructor(Collection.class)).asEagerSingleton();
+ } catch (NoSuchMethodException e) {
+ throw new ConfigurationException("This really shouldn't happen. Either something has changed in Shiro, or there's a bug in ShiroModule.", e);
+ }
+ }
+
+ /**
+ * Binds the session manager. Override this method in order to provide your own session manager binding.
+ * <p/>
+ * By default, a {@link org.apache.shiro.web.session.mgt.DefaultWebSessionManager} is bound as an eager singleton.
+ *
+ * @param bind
+ */
+ @Override
+ protected void bindSessionManager(AnnotatedBindingBuilder<SessionManager> bind) {
+ bind.to(DefaultWebSessionManager.class).asEagerSingleton();
+ }
+
+ @Override
+ protected final void bindEnvironment(AnnotatedBindingBuilder<Environment> bind) {
+ bindWebEnvironment(bind);
+ }
+
+ protected void bindWebEnvironment(AnnotatedBindingBuilder<? super WebEnvironment> bind) {
+ bind.to(WebGuiceEnvironment.class).asEagerSingleton();
+ }
+
+ /**
+ * Adds a filter chain to the shiro configuration.
+ * <p/>
+ * NOTE: If the provided key is for a subclass of {@link org.apache.shiro.web.filter.PathMatchingFilter}, it will be registered with a proper
+ * provider.
+ *
+ * @param pattern
+ * @param keys
+ */
+ @SuppressWarnings({"UnusedDeclaration"})
+ protected final void addFilterChain(String pattern, Key<? extends Filter>... keys) {
+ filterChains.put(pattern, keys);
+ }
+
+ protected static <T extends PathMatchingFilter> Key<T> config(Key<T> baseKey, String configValue) {
+ return new FilterConfigKey<T>(baseKey, configValue);
+ }
+
+ @SuppressWarnings({"UnusedDeclaration"})
+ protected static <T extends PathMatchingFilter> Key<T> config(TypeLiteral<T> typeLiteral, String configValue) {
+ return config(Key.get(typeLiteral), configValue);
+ }
+
+ @SuppressWarnings({"UnusedDeclaration"})
+ protected static <T extends PathMatchingFilter> Key<T> config(Class<T> type, String configValue) {
+ return config(Key.get(type), configValue);
+ }
+
+ private static class FilterConfigKey<T extends PathMatchingFilter> extends Key<T> {
+ private Key<T> key;
+ private String configValue;
+
+ private FilterConfigKey(Key<T> key, String configValue) {
+ super();
+ this.key = key;
+ this.configValue = configValue;
+ }
+
+ public Key<T> getKey() {
+ return key;
+ }
+
+ public String getConfigValue() {
+ return configValue;
+ }
+ }
+}
Added: shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/web/SimpleFilterChain.java
URL: http://svn.apache.org/viewvc/shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/web/SimpleFilterChain.java?rev=1147810&view=auto
==============================================================================
--- shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/web/SimpleFilterChain.java (added)
+++ shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/web/SimpleFilterChain.java Mon Jul 18 11:10:51 2011
@@ -0,0 +1,47 @@
+/*
+ * 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.shiro.guice.web;
+
+import javax.servlet.*;
+import java.io.IOException;
+import java.util.Iterator;
+
+class SimpleFilterChain implements FilterChain {
+
+
+ private final FilterChain originalChain;
+ private final Iterator<? extends Filter> chain;
+
+ private boolean originalCalled = false;
+
+ public SimpleFilterChain(FilterChain originalChain, Iterator<? extends Filter> chain) {
+ this.originalChain = originalChain;
+ this.chain = chain;
+ }
+
+ public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
+ if (chain.hasNext()) {
+ Filter filter = chain.next();
+ filter.doFilter(request, response, this);
+ } else if (!originalCalled) {
+ originalCalled = true;
+ originalChain.doFilter(request, response);
+ }
+ }
+}
Added: shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/web/SimpleFilterChainResolver.java
URL: http://svn.apache.org/viewvc/shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/web/SimpleFilterChainResolver.java?rev=1147810&view=auto
==============================================================================
--- shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/web/SimpleFilterChainResolver.java (added)
+++ shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/web/SimpleFilterChainResolver.java Mon Jul 18 11:10:51 2011
@@ -0,0 +1,61 @@
+/*
+ * 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.shiro.guice.web;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Iterators;
+import com.google.inject.Injector;
+import com.google.inject.Key;
+import org.apache.shiro.util.PatternMatcher;
+import org.apache.shiro.web.filter.mgt.FilterChainResolver;
+import org.apache.shiro.web.util.WebUtils;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import java.util.Map;
+
+class SimpleFilterChainResolver implements FilterChainResolver {
+ private final Map<String, Key<? extends Filter>[]> chains;
+ private final Injector injector;
+ private final PatternMatcher patternMatcher;
+
+ SimpleFilterChainResolver(Map<String, Key<? extends Filter>[]> chains, Injector injector, PatternMatcher patternMatcher) {
+ this.chains = chains;
+ this.injector = injector;
+ this.patternMatcher = patternMatcher;
+ }
+
+ public FilterChain getChain(ServletRequest request, ServletResponse response, final FilterChain originalChain) {
+ String path = WebUtils.getPathWithinApplication(WebUtils.toHttp(request));
+ for (final String pathPattern : chains.keySet()) {
+ if (patternMatcher.matches(pathPattern, path)) {
+ return new SimpleFilterChain(originalChain, Iterators.transform(Iterators.forArray(chains.get(pathPattern)),
+ new Function<Key<? extends Filter>, Filter>() {
+ public Filter apply(Key<? extends Filter> input) {
+ return injector.getInstance(input);
+ }
+ }));
+ }
+ }
+ return null;
+ }
+
+}
Added: shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/web/WebGuiceEnvironment.java
URL: http://svn.apache.org/viewvc/shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/web/WebGuiceEnvironment.java?rev=1147810&view=auto
==============================================================================
--- shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/web/WebGuiceEnvironment.java (added)
+++ shiro/trunk/support/guice/src/main/java/org/apache/shiro/guice/web/WebGuiceEnvironment.java Mon Jul 18 11:10:51 2011
@@ -0,0 +1,62 @@
+/*
+ * 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.shiro.guice.web;
+
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+import org.apache.shiro.mgt.SecurityManager;
+import org.apache.shiro.web.env.EnvironmentLoaderListener;
+import org.apache.shiro.web.env.WebEnvironment;
+import org.apache.shiro.web.filter.mgt.FilterChainResolver;
+import org.apache.shiro.web.mgt.WebSecurityManager;
+
+import javax.inject.Named;
+import javax.servlet.ServletContext;
+
+@Singleton
+class WebGuiceEnvironment implements WebEnvironment {
+ private FilterChainResolver filterChainResolver;
+ private ServletContext servletContext;
+ private WebSecurityManager securityManager;
+
+ @Inject
+ WebGuiceEnvironment(FilterChainResolver filterChainResolver, @Named(ShiroWebModule.NAME) ServletContext servletContext, WebSecurityManager securityManager) {
+ this.filterChainResolver = filterChainResolver;
+ this.servletContext = servletContext;
+ this.securityManager = securityManager;
+
+ servletContext.setAttribute(EnvironmentLoaderListener.ENVIRONMENT_ATTRIBUTE_KEY, this);
+ }
+
+ public FilterChainResolver getFilterChainResolver() {
+ return filterChainResolver;
+ }
+
+ public ServletContext getServletContext() {
+ return servletContext;
+ }
+
+ public WebSecurityManager getWebSecurityManager() {
+ return securityManager;
+ }
+
+ public SecurityManager getSecurityManager() {
+ return securityManager;
+ }
+}
Added: 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=1147810&view=auto
==============================================================================
--- shiro/trunk/support/guice/src/test/java/org/apache/shiro/guice/BeanTypeListenerTest.java (added)
+++ shiro/trunk/support/guice/src/test/java/org/apache/shiro/guice/BeanTypeListenerTest.java Mon Jul 18 11:10:51 2011
@@ -0,0 +1,124 @@
+/*
+ * 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.shiro.guice;
+
+import com.google.inject.*;
+import com.google.inject.name.Names;
+import com.google.inject.spi.Message;
+import com.google.inject.spi.TypeEncounter;
+import org.apache.shiro.guice.aop.ShiroAopModule;
+import org.apache.shiro.guice.web.ShiroWebModule;
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.aop.DefaultAnnotationResolver;
+import org.apache.shiro.crypto.BlowfishCipherService;
+import org.easymock.Capture;
+import org.easymock.IMocksControl;
+import org.junit.Test;
+
+import java.util.Collections;
+
+import static org.easymock.EasyMock.*;
+import static org.junit.Assert.*;
+
+/**
+ * Test Cases::
+ * Test package matching
+ * injects on classes in shiro package and sub packages
+ * excludes classes in shiro-guice package and sub packages
+ * Test that properties are set properly
+ * ensure optional
+ * ensure property names are correct
+ * ensure "named" properties require a name, and unnamed do not
+ */
+public class BeanTypeListenerTest {
+ @Test
+ public void testUnmatchedPackage() throws Exception {
+ assertFalse(BeanTypeListener.MATCHER.matches(TypeLiteral.get(GuiceEnvironment.class)));
+ assertFalse(BeanTypeListener.MATCHER.matches(TypeLiteral.get(ShiroWebModule.class)));
+ assertFalse(BeanTypeListener.MATCHER.matches(TypeLiteral.get(ShiroAopModule.class)));
+ }
+
+ @Test
+ public void testMatchedPackage() throws Exception {
+ assertTrue(BeanTypeListener.MATCHER.matches(TypeLiteral.get(SecurityUtils.class)));
+ assertTrue(BeanTypeListener.MATCHER.matches(TypeLiteral.get(DefaultAnnotationResolver.class)));
+ assertTrue(BeanTypeListener.MATCHER.matches(TypeLiteral.get(BlowfishCipherService.class)));
+ }
+
+ @Test
+ public void testPropertySetting() throws Exception {
+ IMocksControl control = createControl();
+ TypeEncounter<SomeInjectableBean> encounter = control.createMock(TypeEncounter.class);
+
+ Provider<Injector> injectorProvider = control.createMock(Provider.class);
+ Injector injector = control.createMock(Injector.class);
+
+ expect(encounter.getProvider(Injector.class)).andReturn(injectorProvider);
+
+ expect(injectorProvider.get()).andReturn(injector).anyTimes();
+
+ Capture<MembersInjector<SomeInjectableBean>> capture = new Capture<MembersInjector<SomeInjectableBean>>();
+ encounter.register(and(anyObject(MembersInjector.class), capture(capture)));
+
+ SecurityManager securityManager = control.createMock(SecurityManager.class);
+ String property = "myPropertyValue";
+
+ expect(injector.getInstance(Key.get(SecurityManager.class))).andReturn(securityManager);
+ 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!"))));
+
+ control.replay();
+
+ BeanTypeListener underTest = new BeanTypeListener();
+
+ underTest.hear(TypeLiteral.get(SomeInjectableBean.class), encounter);
+
+ SomeInjectableBean bean = new SomeInjectableBean();
+
+ capture.getValue().injectMembers(bean);
+
+ assertSame(securityManager, bean.securityManager);
+ assertSame(property, bean.myProperty);
+ assertNull(bean.unavailableProperty);
+
+ control.verify();
+ }
+
+ public static class SomeInjectableBean {
+ private SecurityManager securityManager;
+ private String myProperty;
+ private String unavailableProperty;
+
+ public void setSecurityManager(SecurityManager securityManager) {
+
+ this.securityManager = securityManager;
+ }
+
+ public void setMyProperty(String myProperty) {
+
+ this.myProperty = myProperty;
+ }
+
+ public void setUnavailableProperty(String unavailableProperty) {
+
+ this.unavailableProperty = unavailableProperty;
+ }
+ }
+}
Added: shiro/trunk/support/guice/src/test/java/org/apache/shiro/guice/DestroyableInjectionListenerTest.java
URL: http://svn.apache.org/viewvc/shiro/trunk/support/guice/src/test/java/org/apache/shiro/guice/DestroyableInjectionListenerTest.java?rev=1147810&view=auto
==============================================================================
--- shiro/trunk/support/guice/src/test/java/org/apache/shiro/guice/DestroyableInjectionListenerTest.java (added)
+++ shiro/trunk/support/guice/src/test/java/org/apache/shiro/guice/DestroyableInjectionListenerTest.java Mon Jul 18 11:10:51 2011
@@ -0,0 +1,41 @@
+/*
+ * 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.shiro.guice;
+
+import org.apache.shiro.util.Destroyable;
+import org.junit.Test;
+
+import static org.easymock.EasyMock.*;
+
+public class DestroyableInjectionListenerTest {
+ @Test
+ public void testAfterInjection() throws Exception {
+ DestroyableInjectionListener.DestroyableRegistry registry = createMock(DestroyableInjectionListener.DestroyableRegistry.class);
+ Destroyable destroyable = createMock(Destroyable.class);
+
+ registry.add(destroyable);
+
+ replay(registry, destroyable);
+
+ DestroyableInjectionListener underTest = new DestroyableInjectionListener(registry);
+ underTest.afterInjection(destroyable);
+
+ verify(registry, destroyable);
+ }
+}