PageRenderTime 47ms CodeModel.GetById 28ms app.highlight 17ms RepoModel.GetById 0ms app.codeStats 0ms

/jboss-as-7.1.1.Final/ejb3/src/main/java/org/jboss/as/ejb3/component/allowedmethods/AllowedMethodsInformation.java

#
Java | 175 lines | 107 code | 39 blank | 29 comment | 21 complexity | 059f4ca5f047c57d1db52543d4c73689 MD5 | raw file
Possible License(s): LGPL-2.1, Apache-2.0
  1package org.jboss.as.ejb3.component.allowedmethods;
  2
  3import org.jboss.as.ee.component.Component;
  4import org.jboss.as.ee.component.interceptors.InvocationType;
  5import org.jboss.as.ejb3.EjbMessages;
  6import org.jboss.as.ejb3.component.EJBComponent;
  7import org.jboss.as.ejb3.component.stateful.CurrentSynchronizationCallback;
  8import org.jboss.as.ejb3.context.CurrentInvocationContext;
  9import org.jboss.invocation.InterceptorContext;
 10
 11import java.util.Collections;
 12import java.util.HashSet;
 13import java.util.Set;
 14
 15/**
 16 * This class and its subclasses can be used to determine if a given method
 17 * is allowed to be invoked.
 18 *
 19 * @see CurrentInvocationContext
 20 * @see CurrentSynchronizationCallback
 21 *
 22 * @author Stuart Douglas
 23 */
 24public class AllowedMethodsInformation {
 25
 26    public static final AllowedMethodsInformation INSTANCE = new AllowedMethodsInformation();
 27
 28
 29    private final Set<DeniedMethodKey> denied;
 30    private final Set<DeniedSyncMethodKey> deniedSyncMethods;
 31
 32
 33    protected AllowedMethodsInformation() {
 34        final Set<DeniedMethodKey> denied = new HashSet<DeniedMethodKey>();
 35        add(denied, InvocationType.SET_ENTITY_CONTEXT, MethodType.TIMER_SERVICE_METHOD);
 36        add(denied, InvocationType.SET_ENTITY_CONTEXT, MethodType.TIMER_SERVICE_METHOD);
 37        add(denied, InvocationType.SET_ENTITY_CONTEXT, MethodType.GET_PRIMARY_KEY);
 38        add(denied, InvocationType.SET_ENTITY_CONTEXT, MethodType.GET_TIMER_SERVICE);
 39        add(denied, InvocationType.SET_ENTITY_CONTEXT, MethodType.IS_CALLER_IN_ROLE);
 40        add(denied, InvocationType.SET_ENTITY_CONTEXT, MethodType.GET_CALLER_PRINCIPLE);
 41
 42        add(denied, InvocationType.HOME_METHOD, MethodType.TIMER_SERVICE_METHOD);
 43        add(denied, InvocationType.HOME_METHOD, MethodType.GET_PRIMARY_KEY);
 44
 45        add(denied, InvocationType.ENTITY_EJB_CREATE, MethodType.TIMER_SERVICE_METHOD);
 46        add(denied, InvocationType.ENTITY_EJB_CREATE, MethodType.GET_PRIMARY_KEY);
 47
 48        setup(denied);
 49        this.denied = Collections.unmodifiableSet(denied);
 50
 51        final Set<DeniedSyncMethodKey> deniedSync = new HashSet<DeniedSyncMethodKey>();
 52        add(deniedSync, CurrentSynchronizationCallback.CallbackType.AFTER_COMPLETION, MethodType.TIMER_SERVICE_METHOD);
 53        add(deniedSync, CurrentSynchronizationCallback.CallbackType.AFTER_COMPLETION, MethodType.GET_ROLLBACK_ONLY);
 54        add(deniedSync, CurrentSynchronizationCallback.CallbackType.AFTER_COMPLETION, MethodType.SET_ROLLBACK_ONLY);
 55
 56
 57        this.deniedSyncMethods = Collections.unmodifiableSet(deniedSync);
 58
 59    }
 60
 61    protected void setup(Set<DeniedMethodKey> denied) {
 62
 63    }
 64
 65    protected static void add(Set<DeniedMethodKey> otherDenied, InvocationType setEntityContext, MethodType timerServiceMethod) {
 66        otherDenied.add(new DeniedMethodKey(setEntityContext, timerServiceMethod));
 67    }
 68
 69    protected static void add(Set<DeniedSyncMethodKey> otherDenied, CurrentSynchronizationCallback.CallbackType callbackType, MethodType timerServiceMethod) {
 70        otherDenied.add(new DeniedSyncMethodKey(callbackType, timerServiceMethod));
 71    }
 72
 73    /**
 74     * Checks that the current method
 75     */
 76    public static void checkAllowed(final MethodType methodType) {
 77
 78        final InterceptorContext context = CurrentInvocationContext.get();
 79        if (context == null) {
 80            return;
 81        }
 82
 83        final Component component = context.getPrivateData(Component.class);
 84        if (!(component instanceof EJBComponent)) {
 85            return;
 86        }
 87        final InvocationType invocationType = context.getPrivateData(InvocationType.class);
 88
 89        ((EJBComponent) component).getAllowedMethodsInformation().realCheckPermission(methodType, invocationType);
 90
 91    }
 92
 93    /**
 94     * transaction sync is not affected by the current invocation, as multiple ejb methods may be invoked from afterCompletion
 95     */
 96    private void checkTransactionSync(MethodType methodType) {
 97        //first we have to check the synchronization status
 98        //as the sync is not affected by the current invocation
 99        final CurrentSynchronizationCallback.CallbackType currentSync = CurrentSynchronizationCallback.get();
100        if (currentSync != null) {
101            if (deniedSyncMethods.contains(new DeniedSyncMethodKey(currentSync, methodType))) {
102                throwException(methodType, currentSync);
103            }
104        }
105    }
106
107    protected void realCheckPermission(MethodType methodType, InvocationType invocationType) {
108        checkTransactionSync(methodType);
109        if (invocationType != null) {
110            if (denied.contains(new DeniedMethodKey(invocationType, methodType))) {
111                throwException(methodType, invocationType);
112            }
113        }
114    }
115
116    /**
117     * throw an exception when a method cannot be invoked
118     *
119     * @param methodType     the method
120     * @param invocationType the type of invocation that caused it to be disabled
121     */
122    protected void throwException(MethodType methodType, InvocationType invocationType) {
123        throw EjbMessages.MESSAGES.cannotCallMethod(methodType.getLabel(), invocationType.getLabel());
124    }
125
126
127    /**
128     * throw an exception when a method cannot be invoked
129     *
130     * @param methodType the method
131     * @param callback   the type of invocation that caused it to be disabled
132     */
133    protected void throwException(MethodType methodType, CurrentSynchronizationCallback.CallbackType callback) {
134        throw EjbMessages.MESSAGES.cannotCallMethod(methodType.getLabel(), callback.name());
135    }
136
137
138    private static class DeniedSyncMethodKey {
139        private final CurrentSynchronizationCallback.CallbackType callbackType;
140        private final MethodType methodType;
141
142        public DeniedSyncMethodKey(CurrentSynchronizationCallback.CallbackType callbackType, MethodType methodType) {
143            this.callbackType = callbackType;
144            this.methodType = methodType;
145        }
146
147        public CurrentSynchronizationCallback.CallbackType getCallbackType() {
148            return callbackType;
149        }
150
151        public MethodType getMethodType() {
152            return methodType;
153        }
154
155        @Override
156        public boolean equals(Object o) {
157            if (this == o) return true;
158            if (o == null || getClass() != o.getClass()) return false;
159
160            DeniedSyncMethodKey that = (DeniedSyncMethodKey) o;
161
162            if (callbackType != that.callbackType) return false;
163            if (methodType != that.methodType) return false;
164
165            return true;
166        }
167
168        @Override
169        public int hashCode() {
170            int result = callbackType != null ? callbackType.hashCode() : 0;
171            result = 31 * result + (methodType != null ? methodType.hashCode() : 0);
172            return result;
173        }
174    }
175}