Coverage Report - org.acegisecurity.afterinvocation.AfterInvocationProviderManager
 
Classes in this File Line Coverage Branch Coverage Complexity
AfterInvocationProviderManager
98% 
100% 
2.857
 
 1  
 /* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
 2  
  *
 3  
  * Licensed under the Apache License, Version 2.0 (the "License");
 4  
  * you may not use this file except in compliance with the License.
 5  
  * You may obtain a copy of the License at
 6  
  *
 7  
  *     http://www.apache.org/licenses/LICENSE-2.0
 8  
  *
 9  
  * Unless required by applicable law or agreed to in writing, software
 10  
  * distributed under the License is distributed on an "AS IS" BASIS,
 11  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 12  
  * See the License for the specific language governing permissions and
 13  
  * limitations under the License.
 14  
  */
 15  
 
 16  
 package org.acegisecurity.afterinvocation;
 17  
 
 18  
 import org.acegisecurity.AccessDeniedException;
 19  
 import org.acegisecurity.AfterInvocationManager;
 20  
 import org.acegisecurity.Authentication;
 21  
 import org.acegisecurity.ConfigAttribute;
 22  
 import org.acegisecurity.ConfigAttributeDefinition;
 23  
 
 24  
 import org.apache.commons.logging.Log;
 25  
 import org.apache.commons.logging.LogFactory;
 26  
 
 27  
 import org.springframework.beans.factory.InitializingBean;
 28  
 
 29  
 import java.util.Iterator;
 30  
 import java.util.List;
 31  
 
 32  
 
 33  
 /**
 34  
  * Provider-based implementation of {@link AfterInvocationManager}.<p>Handles configuration of a bean context
 35  
  * defined list of  {@link AfterInvocationProvider}s.</p>
 36  
  *  <p>Every <code>AfterInvocationProvider</code> will be polled when the {@link #decide(Authentication, Object,
 37  
  * ConfigAttributeDefinition, Object)} method is called. The <code>Object</code> returned from each provider will be
 38  
  * presented to the successive provider for processing. This means each provider <b>must</b> ensure they return the
 39  
  * <code>Object</code>, even if they are not interested in the "after invocation" decision (perhaps as the secure
 40  
  * object invocation did not include a configuration attribute a given provider is configured to respond to).</p>
 41  
  *
 42  
  * @author Ben Alex
 43  
  * @version $Id: AfterInvocationProviderManager.java 1496 2006-05-23 13:38:33Z benalex $
 44  
  */
 45  6
 public class AfterInvocationProviderManager implements AfterInvocationManager, InitializingBean {
 46  
     //~ Static fields/initializers =====================================================================================
 47  
 
 48  2
     protected static final Log logger = LogFactory.getLog(AfterInvocationProviderManager.class);
 49  
 
 50  
     //~ Instance fields ================================================================================================
 51  
 
 52  
     private List providers;
 53  
 
 54  
     //~ Methods ========================================================================================================
 55  
 
 56  
     public void afterPropertiesSet() throws Exception {
 57  4
         checkIfValidList(this.providers);
 58  3
     }
 59  
 
 60  
     private void checkIfValidList(List listToCheck) {
 61  9
         if ((listToCheck == null) || (listToCheck.size() == 0)) {
 62  2
             throw new IllegalArgumentException("A list of AfterInvocationProviders is required");
 63  
         }
 64  7
     }
 65  
 
 66  
     public Object decide(Authentication authentication, Object object, ConfigAttributeDefinition config,
 67  
         Object returnedObject) throws AccessDeniedException {
 68  5
         Iterator iter = this.providers.iterator();
 69  
 
 70  5
         Object result = returnedObject;
 71  
 
 72  20
         while (iter.hasNext()) {
 73  15
             AfterInvocationProvider provider = (AfterInvocationProvider) iter.next();
 74  15
             result = provider.decide(authentication, object, config, result);
 75  15
         }
 76  
 
 77  5
         return result;
 78  
     }
 79  
 
 80  
     public List getProviders() {
 81  1
         return this.providers;
 82  
     }
 83  
 
 84  
     public void setProviders(List newList) {
 85  5
         checkIfValidList(newList);
 86  
 
 87  4
         Iterator iter = newList.iterator();
 88  
 
 89  14
         while (iter.hasNext()) {
 90  11
             Object currentObject = null;
 91  
 
 92  
             try {
 93  11
                 currentObject = iter.next();
 94  
 
 95  11
                 AfterInvocationProvider attemptToCast = (AfterInvocationProvider) currentObject;
 96  1
             } catch (ClassCastException cce) {
 97  1
                 throw new IllegalArgumentException("AfterInvocationProvider " + currentObject.getClass().getName()
 98  
                     + " must implement AfterInvocationProvider");
 99  10
             }
 100  10
         }
 101  
 
 102  3
         this.providers = newList;
 103  3
     }
 104  
 
 105  
     public boolean supports(ConfigAttribute attribute) {
 106  2
         Iterator iter = this.providers.iterator();
 107  
 
 108  6
         while (iter.hasNext()) {
 109  5
             AfterInvocationProvider provider = (AfterInvocationProvider) iter.next();
 110  
 
 111  5
             if (logger.isDebugEnabled()) {
 112  0
                 logger.debug("Evaluating " + attribute + " against " + provider);
 113  
             }
 114  
 
 115  5
             if (provider.supports(attribute)) {
 116  1
                 return true;
 117  
             }
 118  4
         }
 119  
 
 120  1
         return false;
 121  
     }
 122  
 
 123  
     /**
 124  
      * Iterates through all <code>AfterInvocationProvider</code>s and ensures each can support the presented
 125  
      * class.<p>If one or more providers cannot support the presented class, <code>false</code> is returned.</p>
 126  
      *
 127  
      * @param clazz the secure object class being queries
 128  
      *
 129  
      * @return if the <code>AfterInvocationProviderManager</code> can support the secure object class, which requires
 130  
      *         every one of its <code>AfterInvocationProvider</code>s to support the secure object class
 131  
      */
 132  
     public boolean supports(Class clazz) {
 133  2
         Iterator iter = this.providers.iterator();
 134  
 
 135  5
         while (iter.hasNext()) {
 136  4
             AfterInvocationProvider provider = (AfterInvocationProvider) iter.next();
 137  
 
 138  4
             if (!provider.supports(clazz)) {
 139  1
                 return false;
 140  
             }
 141  3
         }
 142  
 
 143  1
         return true;
 144  
     }
 145  
 }