001: /* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
002: *
003: * Licensed under the Apache License, Version 2.0 (the "License");
004: * you may not use this file except in compliance with the License.
005: * You may obtain a copy of the License at
006: *
007: * http://www.apache.org/licenses/LICENSE-2.0
008: *
009: * Unless required by applicable law or agreed to in writing, software
010: * distributed under the License is distributed on an "AS IS" BASIS,
011: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012: * See the License for the specific language governing permissions and
013: * limitations under the License.
014: */
015:
016: package org.acegisecurity.vote;
017:
018: import java.util.Iterator;
019: import java.util.List;
020:
021: import org.acegisecurity.AccessDecisionManager;
022: import org.acegisecurity.AccessDeniedException;
023: import org.acegisecurity.AcegiMessageSource;
024: import org.acegisecurity.ConfigAttribute;
025: import org.springframework.beans.factory.InitializingBean;
026: import org.springframework.context.MessageSource;
027: import org.springframework.context.MessageSourceAware;
028: import org.springframework.context.support.MessageSourceAccessor;
029: import org.springframework.util.Assert;
030:
031: /**
032: * Abstract implementation of {@link AccessDecisionManager}.
033: * <p/>
034: * Handles configuration of a bean context defined list of
035: * {@link AccessDecisionVoter}s and the access control behaviour if all voters
036: * abstain from voting (defaults to deny access).
037: * </p>
038: */
039: public abstract class AbstractAccessDecisionManager implements
040: AccessDecisionManager, InitializingBean, MessageSourceAware {
041: // ~ Instance fields
042: // ================================================================================================
043:
044: private List decisionVoters;
045:
046: protected MessageSourceAccessor messages = AcegiMessageSource
047: .getAccessor();
048:
049: private boolean allowIfAllAbstainDecisions = false;
050:
051: // ~ Methods
052: // ========================================================================================================
053:
054: public void afterPropertiesSet() throws Exception {
055: Assert.notEmpty(this .decisionVoters,
056: "A list of AccessDecisionVoters is required");
057: Assert.notNull(this .messages, "A message source must be set");
058: }
059:
060: protected final void checkAllowIfAllAbstainDecisions() {
061: if (!this .isAllowIfAllAbstainDecisions()) {
062: throw new AccessDeniedException(messages.getMessage(
063: "AbstractAccessDecisionManager.accessDenied",
064: "Access is denied"));
065: }
066: }
067:
068: public List getDecisionVoters() {
069: return this .decisionVoters;
070: }
071:
072: public boolean isAllowIfAllAbstainDecisions() {
073: return allowIfAllAbstainDecisions;
074: }
075:
076: public void setAllowIfAllAbstainDecisions(
077: boolean allowIfAllAbstainDecisions) {
078: this .allowIfAllAbstainDecisions = allowIfAllAbstainDecisions;
079: }
080:
081: public void setDecisionVoters(List newList) {
082: Assert.notEmpty(newList);
083:
084: Iterator iter = newList.iterator();
085:
086: while (iter.hasNext()) {
087: Object currentObject = iter.next();
088: Assert.isInstanceOf(AccessDecisionVoter.class,
089: currentObject, "AccessDecisionVoter "
090: + currentObject.getClass().getName()
091: + " must implement AccessDecisionVoter");
092: }
093:
094: this .decisionVoters = newList;
095: }
096:
097: public void setMessageSource(MessageSource messageSource) {
098: this .messages = new MessageSourceAccessor(messageSource);
099: }
100:
101: public boolean supports(ConfigAttribute attribute) {
102: Iterator iter = this .decisionVoters.iterator();
103:
104: while (iter.hasNext()) {
105: AccessDecisionVoter voter = (AccessDecisionVoter) iter
106: .next();
107:
108: if (voter.supports(attribute)) {
109: return true;
110: }
111: }
112:
113: return false;
114: }
115:
116: /**
117: * Iterates through all <code>AccessDecisionVoter</code>s and ensures
118: * each can support the presented class.
119: * <p/>
120: * If one or more voters cannot support the presented class,
121: * <code>false</code> is returned.
122: * </p>
123: *
124: * @param clazz DOCUMENT ME!
125: * @return DOCUMENT ME!
126: */
127: public boolean supports(Class clazz) {
128: Iterator iter = this .decisionVoters.iterator();
129:
130: while (iter.hasNext()) {
131: AccessDecisionVoter voter = (AccessDecisionVoter) iter
132: .next();
133:
134: if (!voter.supports(clazz)) {
135: return false;
136: }
137: }
138:
139: return true;
140: }
141: }
|