| 
					
				 | 
			
			
				@@ -0,0 +1,277 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* Copyright 2004 Acegi Technology Pty Limited 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Licensed 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 net.sf.acegisecurity.vote; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import net.sf.acegisecurity.Authentication; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import net.sf.acegisecurity.AuthorizationServiceException; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import net.sf.acegisecurity.ConfigAttribute; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import net.sf.acegisecurity.ConfigAttributeDefinition; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import net.sf.acegisecurity.acl.AclEntry; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import net.sf.acegisecurity.acl.AclManager; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import net.sf.acegisecurity.acl.basic.AbstractBasicAclEntry; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.aopalliance.intercept.MethodInvocation; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.springframework.beans.factory.InitializingBean; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import java.util.Iterator; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * <p> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Given a domain object instance passed as a method argument, ensures the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * principal has appropriate permission as defined by the {@link AclManager}. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * </p> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ *  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * <p> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * The <code>AclManager</code> is used to retrieve the access control list 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * (ACL) permissions associated with a domain object instance for the current 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * <code>Authentication</code> object. This class is designed to process 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * {@link AclEntry}s that are subclasses of {@link 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * net.sf.acegisecurity.acl.basic.AbstractBasicAclEntry} only. Generally these 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * are obtained by using the {@link 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * net.sf.acegisecurity.acl.basic.BasicAclProvider}. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * </p> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ *  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * <p> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * The voter will vote if any  {@link ConfigAttribute#getAttribute()} matches 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * the {@link #processConfigAttribute}. The provider will then locate the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * first method argument of type {@link #processDomainObjectClass}. Assuming 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * that method argument is non-null, the provider will then lookup the ACLs 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * from the <code>AclManager</code> and ensure the principal is {@link 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * net.sf.acegisecurity.acl.basic.AbstractBasicAclEntry#isPermitted(int)} for 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * at least one of the {@link #requirePermission}s. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * </p> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ *  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * <p> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * If the method argument is <code>null</code>, the voter will abstain from 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * voting. If the method argument could not be found, an {@link 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * net.sf.acegisecurity.AuthorizationServiceException} will be thrown. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * </p> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ *  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * <p> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * In practical terms users will typically setup a number of 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * <code>BasicAclEntryVoter</code>s. Each will have a different {@link 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * #processDomainObjectClass}, {@link #processConfigAttribute} and {@link 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * #requirePermission} combination. For example, a small application might 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * employ the following instances of <code>BasicAclEntryVoter</code>: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ *  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * <ul> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * <li> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Process domain object class <code>BankAccount</code>, configuration 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * attribute <code>VOTE_ACL_BANK_ACCONT_READ</code>, require permission 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * <code>SimpleAclEntry.READ</code> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * </li> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * <li> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Process domain object class <code>BankAccount</code>, configuration 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * attribute <code>VOTE_ACL_BANK_ACCOUNT_WRITE</code>, require permission list 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * <code>SimpleAclEntry.WRITE</code> and <code>SimpleAclEntry.CREATE</code> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * (allowing the principal to have <b>either</b> of these two permissions 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * </li> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * <li> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Process domain object class <code>Customer</code>, configuration attribute 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * <code>VOTE_ACL_CUSTOMER_READ</code>, require permission 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * <code>SimpleAclEntry.READ</code> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * </li> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * <li> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Process domain object class <code>Customer</code>, configuration attribute 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * <code>VOTE_ACL_CUSTOMER_WRITE</code>, require permission list 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * <code>SimpleAclEntry.WRITE</code> and <code>SimpleAclEntry.CREATE</code> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * </li> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * </ul> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ *  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Alternatively, you could have used a common superclass or interface for the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * {@link #processDomainObjectClass} if both <code>BankAccount</code> and 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * <code>Customer</code> had common parents. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * </p> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ *  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * <p> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * If the principal does not have sufficient permissions, the voter will vote 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * to deny access. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * </p> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ *  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * <p> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * The <code>AclManager</code> is allowed to return any implementations of 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * <code>AclEntry</code> it wishes. However, this provider will only be able 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * to validate against <code>AbstractBasicAclEntry</code>s, and thus a vote to 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * deny access will be made if no <code>AclEntry</code> is of type 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * <code>AbstractBasicAclEntry</code>. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * </p> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ *  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * <p> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * All comparisons and prefixes are case sensitive. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * </p> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @author Ben Alex 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @version $Id$ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+public class BasicAclEntryVoter implements AccessDecisionVoter, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    InitializingBean { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    //~ Instance fields ======================================================== 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private AclManager aclManager; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private Class processDomainObjectClass; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private String processConfigAttribute; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private int[] requirePermission; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    //~ Methods ================================================================ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public void setAclManager(AclManager aclManager) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.aclManager = aclManager; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public AclManager getAclManager() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return aclManager; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public void setProcessConfigAttribute(String processConfigAttribute) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.processConfigAttribute = processConfigAttribute; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public String getProcessConfigAttribute() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return processConfigAttribute; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public void setProcessDomainObjectClass(Class processDomainObjectClass) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.processDomainObjectClass = processDomainObjectClass; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public Class getProcessDomainObjectClass() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return processDomainObjectClass; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public void setRequirePermission(int[] requirePermission) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.requirePermission = requirePermission; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public int[] getRequirePermission() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return requirePermission; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public void afterPropertiesSet() throws Exception { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (processConfigAttribute == null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            throw new IllegalArgumentException( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                "A processConfigAttribute is mandatory"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if ((requirePermission == null) || (requirePermission.length == 0)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            throw new IllegalArgumentException( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                "One or more requirePermission entries is mandatory"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (aclManager == null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            throw new IllegalArgumentException("An aclManager is mandatory"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (processDomainObjectClass == null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            throw new IllegalArgumentException( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                "A processDomainObjectClass is mandatory"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public boolean supports(ConfigAttribute attribute) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if ((attribute.getAttribute() != null) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            && attribute.getAttribute().startsWith(getProcessConfigAttribute())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * This implementation supports only 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * <code>MethodSecurityInterceptor</code>, because it queries the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * presented <code>MethodInvocation</code>. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @param clazz the secure object 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @return <code>true</code> if the secure object is 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     *         <code>MethodInvocation</code>, <code>false</code> otherwise 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public boolean supports(Class clazz) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return (MethodInvocation.class.isAssignableFrom(clazz)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public int vote(Authentication authentication, Object object, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ConfigAttributeDefinition config) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Iterator iter = config.getConfigAttributes(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        while (iter.hasNext()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ConfigAttribute attr = (ConfigAttribute) iter.next(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (this.supports(attr)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                // Need to make an access decision on this invocation 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                // Attempt to locate the domain object instance to process 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                Object domainObject = getDomainObjectInstance(object); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                // If domain object is null, vote to abstain 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (domainObject == null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    return AccessDecisionVoter.ACCESS_ABSTAIN; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                // Obtain the ACLs applicable to the domain object 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                AclEntry[] acls = aclManager.getAcls(domainObject, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        authentication); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                // If principal has no permissions for domain object, deny 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if ((acls == null) || (acls.length == 0)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    return AccessDecisionVoter.ACCESS_DENIED; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                // Principal has some permissions for domain object, check them 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                for (int i = 0; i < acls.length; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    // Locate processable AclEntrys 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if (acls[i] instanceof AbstractBasicAclEntry) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        AbstractBasicAclEntry processableAcl = (AbstractBasicAclEntry) acls[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        // See if principal has any of the required permissions 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        for (int y = 0; y < requirePermission.length; y++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            if (processableAcl.isPermitted(requirePermission[y])) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                return AccessDecisionVoter.ACCESS_GRANTED; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                // No permissions match 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return AccessDecisionVoter.ACCESS_DENIED; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // No configuration attribute matched, so abstain 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return AccessDecisionVoter.ACCESS_ABSTAIN; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private Object getDomainObjectInstance(Object secureObject) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (secureObject instanceof MethodInvocation) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            MethodInvocation invocation = (MethodInvocation) secureObject; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            for (int i = 0; i < invocation.getArguments().length; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                Class argClass = invocation.getArguments()[i].getClass(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (processDomainObjectClass.isAssignableFrom(argClass)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    return invocation.getArguments()[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            throw new AuthorizationServiceException("MethodInvocation: " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                + invocation + " did not provide any argument of type: " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                + processDomainObjectClass); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return null; // should never happen 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 |