/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}