FIXED - SHIRO-496: Update shior.guice dependency 
- apply Kevin Sweeney's patch to remove Guava with changes. The original patch has a bug in ShiroWebModule.setupFilterChainConfig, add a rudimentary fix

git-svn-id: https://svn.apache.org/repos/asf/shiro/branches/1.x@1667368 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/pom.xml b/pom.xml
index 2f79f55..7166860 100644
--- a/pom.xml
+++ b/pom.xml
@@ -92,7 +92,6 @@
         <slf4j.version>1.6.4</slf4j.version>
         <spring.version>3.1.0.RELEASE</spring.version>
         <guice.version>3.0</guice.version>
-        <guava.version>r09</guava.version>
 
         <!-- Test 3rd-party dependencies: -->
         <easymock.version>3.1</easymock.version>
@@ -845,11 +844,6 @@
                 </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>
diff --git a/support/guice/pom.xml b/support/guice/pom.xml
index b5b06be..cecf88b 100644
--- a/support/guice/pom.xml
+++ b/support/guice/pom.xml
@@ -46,10 +46,6 @@
             <optional>true</optional>
         </dependency>
         <dependency>
-            <groupId>com.google.guava</groupId>
-            <artifactId>guava</artifactId>
-        </dependency>
-        <dependency>
             <groupId>com.google.inject</groupId>
             <artifactId>guice</artifactId>
         </dependency>
diff --git a/support/guice/src/main/java/org/apache/shiro/guice/BeanTypeListener.java b/support/guice/src/main/java/org/apache/shiro/guice/BeanTypeListener.java
index 6570f38..7cc4521 100644
--- a/support/guice/src/main/java/org/apache/shiro/guice/BeanTypeListener.java
+++ b/support/guice/src/main/java/org/apache/shiro/guice/BeanTypeListener.java
@@ -18,8 +18,23 @@
  */

 package org.apache.shiro.guice;

 

-import com.google.common.primitives.Primitives;

-import com.google.inject.*;

+import java.beans.PropertyDescriptor;

+import java.lang.reflect.InvocationTargetException;

+import java.lang.reflect.Modifier;

+import java.lang.reflect.Type;

+import java.util.Arrays;

+import java.util.HashMap;

+import java.util.HashSet;

+import java.util.Map;

+import java.util.Set;

+

+import com.google.inject.Binder;

+import com.google.inject.ConfigurationException;

+import com.google.inject.Injector;

+import com.google.inject.Key;

+import com.google.inject.MembersInjector;

+import com.google.inject.Provider;

+import com.google.inject.TypeLiteral;

 import com.google.inject.matcher.Matcher;

 import com.google.inject.matcher.Matchers;

 import com.google.inject.multibindings.MapBinder;

@@ -27,16 +42,10 @@
 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;

 

-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.

  */

@@ -54,6 +63,17 @@
     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));

 

+    private static final Set<Class<?>> WRAPPER_TYPES = new HashSet<Class<?>>(Arrays.asList(

+        Byte.class,

+        Boolean.class,

+        Character.class,

+        Double.class,

+        Float.class,

+        Integer.class,

+        Long.class,

+        Short.class,

+        Void.class));

+

     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);

@@ -112,7 +132,7 @@
     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);

+            return aClass.isPrimitive() || aClass.isEnum() || WRAPPER_TYPES.contains(aClass) || CharSequence.class.isAssignableFrom(aClass);

         } else {

             return false;

         }

diff --git a/support/guice/src/main/java/org/apache/shiro/guice/ShiroModule.java b/support/guice/src/main/java/org/apache/shiro/guice/ShiroModule.java
index f032be2..308a9c4 100644
--- a/support/guice/src/main/java/org/apache/shiro/guice/ShiroModule.java
+++ b/support/guice/src/main/java/org/apache/shiro/guice/ShiroModule.java
@@ -18,7 +18,13 @@
  */

 package org.apache.shiro.guice;

 

-import com.google.common.collect.Sets;

+import java.util.Collection;

+import java.util.Collections;

+import java.util.Set;

+import java.util.WeakHashMap;

+

+import javax.annotation.PreDestroy;

+

 import com.google.inject.Key;

 import com.google.inject.PrivateModule;

 import com.google.inject.TypeLiteral;

@@ -26,6 +32,7 @@
 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;

@@ -35,11 +42,6 @@
 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

@@ -48,7 +50,8 @@
  */

 public abstract class ShiroModule extends PrivateModule implements Destroyable {

 

-    private Set<Destroyable> destroyables = Sets.newSetFromMap(new WeakHashMap<Destroyable, Boolean>());

+    private Set<Destroyable> destroyables =

+        Collections.newSetFromMap(new WeakHashMap<Destroyable, Boolean>());

 

     public void configure() {

         this.binder().requireExplicitBindings();

diff --git a/support/guice/src/main/java/org/apache/shiro/guice/web/AbstractInjectionProvider.java b/support/guice/src/main/java/org/apache/shiro/guice/web/AbstractInjectionProvider.java
index 8c8e564..5564448 100644
--- a/support/guice/src/main/java/org/apache/shiro/guice/web/AbstractInjectionProvider.java
+++ b/support/guice/src/main/java/org/apache/shiro/guice/web/AbstractInjectionProvider.java
@@ -18,7 +18,11 @@
  */

 package org.apache.shiro.guice.web;

 

-import com.google.common.collect.ImmutableSet;

+import java.lang.reflect.Constructor;

+import java.util.Collections;

+import java.util.HashSet;

+import java.util.Set;

+

 import com.google.inject.Inject;

 import com.google.inject.Injector;

 import com.google.inject.Key;

@@ -27,9 +31,6 @@
 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;

 

@@ -43,12 +44,12 @@
         this.key = key;

         constructorInjectionPoint = InjectionPoint.forConstructorOf(key.getTypeLiteral());

 

-        ImmutableSet.Builder<Dependency<?>> dependencyBuilder = ImmutableSet.builder();

+        Set<Dependency<?>> dependencyBuilder = new HashSet<Dependency<?>>();

         dependencyBuilder.addAll(constructorInjectionPoint.getDependencies());

         for (InjectionPoint injectionPoint : InjectionPoint.forInstanceMethodsAndFields(key.getTypeLiteral())) {

             dependencyBuilder.addAll(injectionPoint.getDependencies());

         }

-        this.dependencies = dependencyBuilder.build();

+        this.dependencies = Collections.unmodifiableSet(dependencyBuilder);

     }

 

     public T get() {

diff --git a/support/guice/src/main/java/org/apache/shiro/guice/web/FilterChainResolverProvider.java b/support/guice/src/main/java/org/apache/shiro/guice/web/FilterChainResolverProvider.java
index 474c263..4eb5b27 100644
--- a/support/guice/src/main/java/org/apache/shiro/guice/web/FilterChainResolverProvider.java
+++ b/support/guice/src/main/java/org/apache/shiro/guice/web/FilterChainResolverProvider.java
@@ -18,21 +18,24 @@
  */

 package org.apache.shiro.guice.web;

 

-import com.google.common.collect.ImmutableSet;

+import java.util.Collections;

+import java.util.HashSet;

+import java.util.Map;

+import java.util.Set;

+

+import javax.servlet.Filter;

+

 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

@@ -46,13 +49,13 @@
 

     public FilterChainResolverProvider(Map<String, Key<? extends Filter>[]> chains) {

         this.chains = chains;

-        ImmutableSet.Builder<Dependency<?>> dependenciesBuilder = ImmutableSet.builder();

+        Set<Dependency<?>> dependenciesBuilder = new HashSet<Dependency<?>>();

         for (String chain : chains.keySet()) {

             for (Key<? extends Filter> filterKey : chains.get(chain)) {

                 dependenciesBuilder.add(Dependency.get(filterKey));

             }

         }

-        this.dependencies = dependenciesBuilder.build();

+        this.dependencies = Collections.unmodifiableSet(dependenciesBuilder);

     }

 

     @Inject(optional = true)

diff --git a/support/guice/src/main/java/org/apache/shiro/guice/web/ShiroWebModule.java b/support/guice/src/main/java/org/apache/shiro/guice/web/ShiroWebModule.java
index 1334320..67fdd14 100644
--- a/support/guice/src/main/java/org/apache/shiro/guice/web/ShiroWebModule.java
+++ b/support/guice/src/main/java/org/apache/shiro/guice/web/ShiroWebModule.java
@@ -18,35 +18,44 @@
  */

 package org.apache.shiro.guice.web;

 

-import com.google.common.collect.HashBasedTable;

-import com.google.common.collect.Table;

+import java.util.Collection;

+import java.util.HashMap;

+import java.util.LinkedHashMap;

+import java.util.Map;

+

+import javax.servlet.Filter;

+import javax.servlet.ServletContext;

+

 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.guice.ShiroModule;

 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.authc.AnonymousFilter;

+import org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter;

+import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;

+import org.apache.shiro.web.filter.authc.LogoutFilter;

+import org.apache.shiro.web.filter.authc.UserFilter;

+import org.apache.shiro.web.filter.authz.HttpMethodPermissionFilter;

+import org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter;

+import org.apache.shiro.web.filter.authz.PortFilter;

+import org.apache.shiro.web.filter.authz.RolesAuthorizationFilter;

+import org.apache.shiro.web.filter.authz.SslFilter;

 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.ServletContainerSessionManager;

 

-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

@@ -131,26 +140,27 @@
     }

 

     private void setupFilterChainConfigs() {

-        Table<Key<? extends PathMatchingFilter>, String, String> configs = HashBasedTable.create();

-

+        Map<Key<? extends PathMatchingFilter>, Map<String, String>> configs = new HashMap<Key<? extends PathMatchingFilter>, Map<String, String>>();

         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(), "");

-                }

+	                  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());

+	                  }

+	                  if (configs.get(castToPathMatching(key)) == null) configs.put(castToPathMatching(key), new HashMap<String, String>());

+	                  configs.get(castToPathMatching(key)).put(filterChain.getKey(), configKey.getConfigValue());

+	              } else if (PathMatchingFilter.class.isAssignableFrom(key.getTypeLiteral().getRawType())) {

+	                  if (configs.get(castToPathMatching(key)) == null) configs.put(castToPathMatching(key), new HashMap<String, String>());

+	                  configs.get(castToPathMatching(key)).put(filterChain.getKey(), "");

+	              }

             }

         }

-        for (Key<? extends PathMatchingFilter> filterKey : configs.rowKeySet()) {

-            bindPathMatchingFilter(filterKey, configs.row(filterKey));

+        for (Key<? extends PathMatchingFilter> filterKey : configs.keySet()) {

+            bindPathMatchingFilter(filterKey, configs.get(filterKey));

         }

     }

 

diff --git a/support/guice/src/main/java/org/apache/shiro/guice/web/SimpleFilterChainResolver.java b/support/guice/src/main/java/org/apache/shiro/guice/web/SimpleFilterChainResolver.java
index 526012c..e0d29c4 100644
--- a/support/guice/src/main/java/org/apache/shiro/guice/web/SimpleFilterChainResolver.java
+++ b/support/guice/src/main/java/org/apache/shiro/guice/web/SimpleFilterChainResolver.java
@@ -18,19 +18,21 @@
  */

 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 java.util.Arrays;

+import java.util.Iterator;

+import java.util.Map;

 

 import javax.servlet.Filter;

 import javax.servlet.FilterChain;

 import javax.servlet.ServletRequest;

 import javax.servlet.ServletResponse;

-import java.util.Map;

+

+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;

 

 class SimpleFilterChainResolver implements FilterChainResolver {

     private final Map<String, Key<? extends Filter>[]> chains;

@@ -47,12 +49,20 @@
         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);

-                            }

-                        }));

+                final Iterator<Key<? extends Filter>> chain = Arrays.asList(chains.get(pathPattern)).iterator();

+                return new SimpleFilterChain(originalChain, new Iterator<Filter>() {

+                    public boolean hasNext() {

+                        return chain.hasNext();

+                    }

+

+                    public Filter next() {

+                        return injector.getInstance(chain.next());

+                    }

+

+                    public void remove() {

+                        throw new UnsupportedOperationException();

+                    }

+                });

             }

         }

         return null;

diff --git a/support/guice/src/test/java/org/apache/shiro/guice/web/SimpleFilterChainTest.java b/support/guice/src/test/java/org/apache/shiro/guice/web/SimpleFilterChainTest.java
index 5938550..77bea50 100644
--- a/support/guice/src/test/java/org/apache/shiro/guice/web/SimpleFilterChainTest.java
+++ b/support/guice/src/test/java/org/apache/shiro/guice/web/SimpleFilterChainTest.java
@@ -18,17 +18,22 @@
  */

 package org.apache.shiro.guice.web;

 

-import com.google.common.collect.Iterators;

-import org.easymock.Capture;

-import org.easymock.IMocksControl;

-import org.junit.Test;

+import java.util.Arrays;

 

 import javax.servlet.Filter;

 import javax.servlet.FilterChain;

 import javax.servlet.ServletRequest;

 import javax.servlet.ServletResponse;

 

-import static org.easymock.EasyMock.*;

+import org.easymock.Capture;

+import org.easymock.IMocksControl;

+import org.junit.Test;

+

+import static org.easymock.EasyMock.and;

+import static org.easymock.EasyMock.anyObject;

+import static org.easymock.EasyMock.capture;

+import static org.easymock.EasyMock.createStrictControl;

+import static org.easymock.EasyMock.same;

 

 public class SimpleFilterChainTest {

     @Test

@@ -50,7 +55,7 @@
 

         ctrl.replay();

 

-        SimpleFilterChain underTest = new SimpleFilterChain(originalChain, Iterators.forArray(filter1, filter2));

+        SimpleFilterChain underTest = new SimpleFilterChain(originalChain, Arrays.asList(filter1, filter2).iterator());

 

         // all we actually care about is that, if we keep calling the filter chain, everything is called in the right

         // order - we don't care what fc actually contains