1
2
3
4
5
6
7
8
9
10
11
12
13
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}.
35 *
36 * <p>
37 * Handles configuration of a bean context defined list of {@link
38 * AfterInvocationProvider}s.
39 * </p>
40 *
41 * <p>
42 * Every <code>AfterInvocationProvider</code> will be polled when the {@link
43 * #decide(Authentication, Object, ConfigAttributeDefinition, Object)} method
44 * is called. The <code>Object</code> returned from each provider will be
45 * presented to the successive provider for processing. This means each
46 * provider <b>must</b> ensure they return the <code>Object</code>, even if
47 * they are not interested in the "after invocation" decision (perhaps as the
48 * secure object invocation did not include a configuration attribute a given
49 * provider is configured to respond to).
50 * </p>
51 *
52 * @author Ben Alex
53 * @version $Id: AfterInvocationProviderManager.java,v 1.3 2005/11/17 00:55:56 benalex Exp $
54 */
55 public class AfterInvocationProviderManager implements AfterInvocationManager,
56 InitializingBean {
57
58
59 protected static final Log logger = LogFactory.getLog(AfterInvocationProviderManager.class);
60
61
62
63 private List providers;
64
65
66
67 public void setProviders(List newList) {
68 checkIfValidList(newList);
69
70 Iterator iter = newList.iterator();
71
72 while (iter.hasNext()) {
73 Object currentObject = null;
74
75 try {
76 currentObject = iter.next();
77
78 AfterInvocationProvider attemptToCast = (AfterInvocationProvider) currentObject;
79 } catch (ClassCastException cce) {
80 throw new IllegalArgumentException("AfterInvocationProvider "
81 + currentObject.getClass().getName()
82 + " must implement AfterInvocationProvider");
83 }
84 }
85
86 this.providers = newList;
87 }
88
89 public List getProviders() {
90 return this.providers;
91 }
92
93 public void afterPropertiesSet() throws Exception {
94 checkIfValidList(this.providers);
95 }
96
97 public Object decide(Authentication authentication, Object object,
98 ConfigAttributeDefinition config, Object returnedObject)
99 throws AccessDeniedException {
100 Iterator iter = this.providers.iterator();
101
102 Object result = returnedObject;
103
104 while (iter.hasNext()) {
105 AfterInvocationProvider provider = (AfterInvocationProvider) iter
106 .next();
107 result = provider.decide(authentication, object, config, result);
108 }
109
110 return result;
111 }
112
113 public boolean supports(ConfigAttribute attribute) {
114 Iterator iter = this.providers.iterator();
115
116 while (iter.hasNext()) {
117 AfterInvocationProvider provider = (AfterInvocationProvider) iter
118 .next();
119
120 if (logger.isDebugEnabled()) {
121 logger.debug("Evaluating " + attribute + " against " + provider);
122 }
123
124 if (provider.supports(attribute)) {
125 return true;
126 }
127 }
128
129 return false;
130 }
131
132 /***
133 * Iterates through all <code>AfterInvocationProvider</code>s and ensures
134 * each can support the presented class.
135 *
136 * <p>
137 * If one or more providers cannot support the presented class,
138 * <code>false</code> is returned.
139 * </p>
140 *
141 * @param clazz the secure object class being queries
142 *
143 * @return if the <code>AfterInvocationProviderManager</code> can support
144 * the secure object class, which requires every one of its
145 * <code>AfterInvocationProvider</code>s to support the secure
146 * object class
147 */
148 public boolean supports(Class clazz) {
149 Iterator iter = this.providers.iterator();
150
151 while (iter.hasNext()) {
152 AfterInvocationProvider provider = (AfterInvocationProvider) iter
153 .next();
154
155 if (!provider.supports(clazz)) {
156 return false;
157 }
158 }
159
160 return true;
161 }
162
163 private void checkIfValidList(List listToCheck) {
164 if ((listToCheck == null) || (listToCheck.size() == 0)) {
165 throw new IllegalArgumentException(
166 "A list of AfterInvocationProviders is required");
167 }
168 }
169 }