001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */package org.apache.openejb.core;
017:
018: import java.io.Serializable;
019: import java.io.ObjectStreamException;
020: import java.security.Identity;
021: import java.security.Principal;
022: import java.util.Properties;
023: import javax.ejb.EJBContext;
024: import javax.ejb.EJBHome;
025: import javax.ejb.EJBLocalHome;
026: import javax.ejb.TimerService;
027: import javax.naming.NamingException;
028: import javax.naming.Context;
029: import javax.transaction.Status;
030: import javax.transaction.SystemException;
031: import javax.transaction.TransactionManager;
032: import javax.transaction.UserTransaction;
033: import javax.transaction.NotSupportedException;
034: import javax.transaction.HeuristicMixedException;
035: import javax.transaction.HeuristicRollbackException;
036: import javax.transaction.RollbackException;
037:
038: import org.apache.openejb.DeploymentInfo;
039: import org.apache.openejb.core.timer.EjbTimerService;
040: import org.apache.openejb.core.timer.TimerServiceImpl;
041: import org.apache.openejb.core.ivm.IntraVmArtifact;
042: import org.apache.openejb.spi.SecurityService;
043:
044: /**
045: * @version $Rev: 602704 $ $Date: 2007-12-09 09:58:22 -0800 $
046: */
047: public abstract class BaseContext implements EJBContext, Serializable {
048:
049: private final UserTransaction userTransaction;
050: private final SecurityService securityService;
051: private final TransactionManager transactionManager;
052:
053: public BaseContext(TransactionManager transactionManager,
054: SecurityService securityService) {
055: this .transactionManager = transactionManager;
056: this .securityService = securityService;
057: this .userTransaction = new UserTransactionWrapper(
058: new CoreUserTransaction(transactionManager));
059: }
060:
061: protected BaseContext(TransactionManager transactionManager,
062: SecurityService securityService,
063: UserTransaction userTransaction) {
064: this .transactionManager = transactionManager;
065: this .securityService = securityService;
066: this .userTransaction = new UserTransactionWrapper(
067: userTransaction);
068: }
069:
070: protected static State[] states;
071:
072: public static State[] getStates() {
073: return states;
074: }
075:
076: protected abstract State getState();
077:
078: public EJBHome getEJBHome() {
079: return getState().getEJBHome();
080: }
081:
082: public EJBLocalHome getEJBLocalHome() {
083: return getState().getEJBLocalHome();
084: }
085:
086: public final Properties getEnvironment() {
087: throw new UnsupportedOperationException();
088: }
089:
090: public final Identity getCallerIdentity() {
091: throw new UnsupportedOperationException();
092: }
093:
094: public Principal getCallerPrincipal() {
095: Principal callerPrincipal = getState().getCallerPrincipal(
096: securityService);
097: if (callerPrincipal == null)
098: callerPrincipal = UnauthenticatedPrincipal.INSTANCE;
099: return callerPrincipal;
100: }
101:
102: public final boolean isCallerInRole(Identity identity) {
103: throw new UnsupportedOperationException();
104: }
105:
106: public boolean isCallerInRole(String roleName) {
107: return getState().isCallerInRole(securityService, roleName);
108: }
109:
110: public UserTransaction getUserTransaction()
111: throws IllegalStateException {
112: return getState().getUserTransaction(userTransaction);
113: }
114:
115: public void setRollbackOnly() throws IllegalStateException {
116: getState().setRollbackOnly(transactionManager);
117: }
118:
119: public boolean getRollbackOnly() throws IllegalStateException {
120: return getState().getRollbackOnly(transactionManager);
121: }
122:
123: public TimerService getTimerService() throws IllegalStateException {
124: return getState().getTimerService();
125: }
126:
127: public Object lookup(String name) {
128: ThreadContext threadContext = ThreadContext.getThreadContext();
129: CoreDeploymentInfo deploymentInfo = threadContext
130: .getDeploymentInfo();
131: Context jndiEnc = deploymentInfo.getJndiEnc();
132: try {
133: jndiEnc = (Context) jndiEnc.lookup("java:comp/env");
134: return jndiEnc.lookup(name);
135: } catch (NamingException e) {
136: throw new IllegalArgumentException(e);
137: } catch (RuntimeException e) {
138: throw new IllegalArgumentException(e);
139: }
140:
141: // try {
142: // InitialContext initialContext = new InitialContext();
143: // Context ctx = (Context) initialContext.lookup("java:comp/env");
144: // return ctx.lookup(name);
145: // } catch (NamingException e) {
146: // throw new IllegalArgumentException(e);
147: // } catch (RuntimeException e) {
148: // throw new IllegalArgumentException(e);
149: // }
150: }
151:
152: public boolean isUserTransactionAccessAllowed() {
153: return getState().isUserTransactionAccessAllowed();
154: }
155:
156: public boolean isMessageContextAccessAllowed() {
157: return getState().isMessageContextAccessAllowed();
158: }
159:
160: public boolean isJNDIAccessAllowed() {
161: return getState().isJNDIAccessAllowed();
162: }
163:
164: public boolean isEntityManagerFactoryAccessAllowed() {
165: return getState().isEntityManagerFactoryAccessAllowed();
166: }
167:
168: public boolean isEntityManagerAccessAllowed() {
169: return getState().isEntityManagerAccessAllowed();
170: }
171:
172: public boolean isTimerAccessAllowed() {
173: return getState().isTimerAccessAllowed();
174: }
175:
176: public static boolean isTimerMethodAllowed() {
177: State[] currentStates = ThreadContext.getThreadContext()
178: .getCurrentAllowedStates();
179: State currentState = currentStates[ThreadContext
180: .getThreadContext().getCurrentOperation().ordinal()];
181:
182: return currentState.isTimerMethodAllowed();
183: }
184:
185: public class UserTransactionWrapper implements UserTransaction {
186: private UserTransaction userTransaction;
187:
188: public UserTransactionWrapper(UserTransaction userTransaction) {
189: this .userTransaction = userTransaction;
190: }
191:
192: public void begin() throws NotSupportedException,
193: SystemException {
194: if (!isUserTransactionAccessAllowed()) {
195: throw new IllegalStateException();
196: }
197: userTransaction.begin();
198: }
199:
200: public void commit() throws HeuristicMixedException,
201: HeuristicRollbackException, IllegalStateException,
202: RollbackException, SecurityException, SystemException {
203: if (!isUserTransactionAccessAllowed()) {
204: throw new IllegalStateException();
205: }
206: userTransaction.commit();
207: }
208:
209: public int getStatus() throws SystemException {
210: if (!isUserTransactionAccessAllowed()) {
211: throw new IllegalStateException();
212: }
213: return userTransaction.getStatus();
214: }
215:
216: public void rollback() throws IllegalStateException,
217: SecurityException, SystemException {
218: if (!isUserTransactionAccessAllowed()) {
219: throw new IllegalStateException();
220: }
221: userTransaction.rollback();
222: }
223:
224: public void setRollbackOnly() throws IllegalStateException,
225: SystemException {
226: if (!isUserTransactionAccessAllowed()) {
227: throw new IllegalStateException();
228: }
229: userTransaction.setRollbackOnly();
230: }
231:
232: public void setTransactionTimeout(int i) throws SystemException {
233: if (!isUserTransactionAccessAllowed()) {
234: throw new IllegalStateException();
235: }
236: userTransaction.setTransactionTimeout(i);
237: }
238: }
239:
240: public static class State {
241:
242: public EJBHome getEJBHome() {
243: ThreadContext threadContext = ThreadContext
244: .getThreadContext();
245: CoreDeploymentInfo di = threadContext.getDeploymentInfo();
246:
247: return di.getEJBHome();
248: }
249:
250: public EJBLocalHome getEJBLocalHome() {
251: ThreadContext threadContext = ThreadContext
252: .getThreadContext();
253: CoreDeploymentInfo di = threadContext.getDeploymentInfo();
254:
255: return di.getEJBLocalHome();
256: }
257:
258: public Principal getCallerPrincipal(
259: SecurityService securityService) {
260: return securityService.getCallerPrincipal();
261: }
262:
263: public boolean isCallerInRole(SecurityService securityService,
264: String roleName) {
265: return securityService.isCallerInRole(roleName);
266: }
267:
268: public UserTransaction getUserTransaction(
269: UserTransaction userTransaction)
270: throws IllegalStateException {
271: ThreadContext threadContext = ThreadContext
272: .getThreadContext();
273: DeploymentInfo di = threadContext.getDeploymentInfo();
274:
275: if (di.isBeanManagedTransaction()) {
276: return userTransaction;
277: } else {
278: throw new IllegalStateException(
279: "container-managed transaction beans can not access the UserTransaction");
280: }
281: }
282:
283: public void setRollbackOnly(
284: TransactionManager transactionManager)
285: throws IllegalStateException {
286: ThreadContext threadContext = ThreadContext
287: .getThreadContext();
288: DeploymentInfo di = threadContext.getDeploymentInfo();
289:
290: if (di.isBeanManagedTransaction()) {
291: throw new IllegalStateException(
292: "bean-managed transaction beans can not access the setRollbackOnly() method");
293: }
294:
295: try {
296: transactionManager.setRollbackOnly();
297: } catch (SystemException se) {
298: throw new RuntimeException(
299: "Transaction service has thrown a SystemException",
300: se);
301: }
302: }
303:
304: public boolean getRollbackOnly(
305: TransactionManager transactionManager)
306: throws IllegalStateException {
307: ThreadContext threadContext = ThreadContext
308: .getThreadContext();
309: DeploymentInfo di = threadContext.getDeploymentInfo();
310:
311: if (di.isBeanManagedTransaction()) {
312: throw new IllegalStateException(
313: "bean-managed transaction beans can not access the getRollbackOnly() method: deploymentId="
314: + di.getDeploymentID());
315: }
316:
317: try {
318: int status = transactionManager.getStatus();
319: if (status == Status.STATUS_MARKED_ROLLBACK
320: || status == Status.STATUS_ROLLEDBACK) {
321: return true;
322: } else if (status == Status.STATUS_NO_TRANSACTION) {
323: // this would be true for Supports tx attribute where no tx was propagated
324: throw new IllegalStateException(
325: "No current transaction");
326: } else {
327: return false;
328: }
329: } catch (SystemException se) {
330: throw new RuntimeException(
331: "Transaction service has thrown a SystemException",
332: se);
333: }
334: }
335:
336: public TimerService getTimerService()
337: throws IllegalStateException {
338: ThreadContext threadContext = ThreadContext
339: .getThreadContext();
340: DeploymentInfo deploymentInfo = threadContext
341: .getDeploymentInfo();
342: EjbTimerService timerService = deploymentInfo
343: .getEjbTimerService();
344: if (timerService == null) {
345: throw new IllegalStateException(
346: "This ejb does not support timers "
347: + deploymentInfo.getDeploymentID());
348: }
349: return new TimerServiceImpl(timerService, threadContext
350: .getPrimaryKey());
351: }
352:
353: public boolean isTimerAccessAllowed() {
354: return true;
355: }
356:
357: public boolean isTimerMethodAllowed() {
358: return true;
359: }
360:
361: public boolean isUserTransactionAccessAllowed() {
362: ThreadContext threadContext = ThreadContext
363: .getThreadContext();
364: DeploymentInfo di = threadContext.getDeploymentInfo();
365:
366: return di.isBeanManagedTransaction();
367: }
368:
369: public boolean isMessageContextAccessAllowed() {
370: return true;
371: }
372:
373: public boolean isJNDIAccessAllowed() {
374: return true;
375: }
376:
377: public boolean isEntityManagerFactoryAccessAllowed() {
378: return true;
379: }
380:
381: public boolean isEntityManagerAccessAllowed() {
382: return true;
383: }
384:
385: }
386:
387: protected Object writeReplace() throws ObjectStreamException {
388: return new IntraVmArtifact(this , true);
389: }
390: }
|