浏览代码

SEC-1557: Added getter to DelegatingMethodSecurityMetadataSource. Also added some optimizations of cache lookup key equals method. A class type check is unnecessary since the key class is a private inner class.

Luke Taylor 14 年之前
父节点
当前提交
bfb723feac

+ 4 - 6
core/src/main/java/org/springframework/security/access/method/DelegatingMethodSecurityMetadataSource.java

@@ -85,6 +85,10 @@ public final class DelegatingMethodSecurityMetadataSource extends AbstractMethod
         return set;
     }
 
+    public List<MethodSecurityMetadataSource> getMethodSecurityMetadataSources() {
+        return methodSecurityMetadataSources;
+    }
+
     //~ Inner Classes ==================================================================================================
 
     private static class DefaultCacheKey {
@@ -97,12 +101,6 @@ public final class DelegatingMethodSecurityMetadataSource extends AbstractMethod
         }
 
         public boolean equals(Object other) {
-            if (this == other) {
-                return true;
-            }
-            if (!(other instanceof DefaultCacheKey)) {
-                return false;
-            }
             DefaultCacheKey otherKey = (DefaultCacheKey) other;
             return (this.method.equals(otherKey.method) &&
                     ObjectUtils.nullSafeEquals(this.targetClass, otherKey.targetClass));

+ 56 - 0
core/src/test/java/org/springframework/security/access/method/DelegatingMethodSecurityMetadataSourceTests.java

@@ -0,0 +1,56 @@
+package org.springframework.security.access.method;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
+
+import org.aopalliance.intercept.MethodInvocation;
+import org.junit.Test;
+import org.mockito.Matchers;
+import org.springframework.security.access.ConfigAttribute;
+import org.springframework.security.util.SimpleMethodInvocation;
+
+import java.lang.reflect.Method;
+import java.util.*;
+
+/**
+ * @author Luke Taylor
+ */
+@SuppressWarnings({"unchecked"})
+public class DelegatingMethodSecurityMetadataSourceTests {
+    DelegatingMethodSecurityMetadataSource mds;
+
+    @Test
+    public void returnsNullIfDelegateReturnsNull() throws Exception {
+        List sources = new ArrayList();
+        MethodSecurityMetadataSource delegate = mock(MethodSecurityMetadataSource.class);
+        when(delegate.getAttributes(Matchers.<Method>any(), Matchers.any(Class.class))).thenReturn(null);
+        sources.add(delegate);
+        mds = new DelegatingMethodSecurityMetadataSource(sources);
+        assertSame(sources, mds.getMethodSecurityMetadataSources());
+        assertTrue(mds.getAllConfigAttributes().isEmpty());
+        MethodInvocation mi = new SimpleMethodInvocation(null, String.class.getMethod("toString"));
+        assertNull(mds.getAttributes(mi));
+        // Exercise the cached case
+        assertNull(mds.getAttributes(mi));
+    }
+
+    @Test
+    public void returnsDelegateAttributes() throws Exception {
+        List sources = new ArrayList();
+        MethodSecurityMetadataSource delegate = mock(MethodSecurityMetadataSource.class);
+        ConfigAttribute ca = mock(ConfigAttribute.class);
+        List attributes = Arrays.asList(ca);
+        Method toString = String.class.getMethod("toString");
+        when(delegate.getAttributes(toString, String.class)).thenReturn(attributes);
+        sources.add(delegate);
+        mds = new DelegatingMethodSecurityMetadataSource(sources);
+        assertSame(sources, mds.getMethodSecurityMetadataSources());
+        assertTrue(mds.getAllConfigAttributes().isEmpty());
+        MethodInvocation mi = new SimpleMethodInvocation("", toString);
+        assertSame(attributes, mds.getAttributes(mi));
+        // Exercise the cached case
+        assertSame(attributes, mds.getAttributes(mi));
+        assertTrue(mds.getAttributes(new SimpleMethodInvocation(null, String.class.getMethod("length"))).isEmpty());
+    }
+
+}