| Title: EjbContext Whiteboard |
| <DIV class="code panel" style="border-style: solid;border-width: 1px;"><DIV class="codeHeader panelHeader" style="border-bottom-width: 1px;border-bottom-style: solid;"><B>CoreContext.java</B></DIV><DIV class="codeContent panelContent"> |
| /** |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.openejb.core; |
| |
| import java.util.List; |
| import javax.ejb.EJBHome; |
| import javax.ejb.EJBLocalHome; |
| import javax.ejb.EJBLocalObject; |
| import javax.ejb.TimerService; |
| import javax.naming.Context; |
| import javax.naming.InitialContext; |
| import javax.naming.NamingException; |
| import javax.transaction.Status; |
| import javax.transaction.TransactionManager; |
| import javax.transaction.UserTransaction; |
| import java.util.List; |
| |
| import org.apache.openejb.DeploymentInfo; |
| import org.apache.openejb.InterfaceType; |
| import org.apache.openejb.RpcContainer; |
| import org.apache.openejb.InternalErrorException; |
| import org.apache.openejb.core.ivm.EjbObjectProxyHandler; |
| import org.apache.openejb.core.ivm.IntraVmProxy; |
| import org.apache.openejb.spi.SecurityService; |
| import org.apache.openejb.util.proxy.ProxyManager; |
| |
| |
| public abstract class CoreContext implements java.io.Serializable { |
| |
| public static enum Call { |
| getEJBHome, |
| getCallerPrincipal, |
| getRollbackOnly, |
| isCallerInRole, |
| setRollbackOnly, |
| getEJBObject, |
| getPrimaryKey, |
| getUserTransaction |
| } |
| |
| private final UserTransaction userTransaction; |
| private final SecurityService securityService; |
| private final TransactionManager transactionManager; |
| |
| public CoreContext(TransactionManager transactionManager, |
| SecurityService securityService) { |
| this.transactionManager = transactionManager; |
| this.securityService = securityService; |
| this.userTransaction = new CoreUserTransaction(transactionManager); |
| } |
| |
| protected CoreContext(TransactionManager transactionManager, |
| SecurityService securityService, UserTransaction userTransaction) { |
| this.transactionManager = transactionManager; |
| this.securityService = securityService; |
| this.userTransaction = userTransaction; |
| } |
| |
| private TransactionManager getTransactionManager() { |
| return transactionManager; |
| } |
| |
| public abstract void checkBeanState(Call methodCategory) throws |
| IllegalStateException; |
| |
| public java.security.Principal getCallerPrincipal() { |
| checkBeanState(Call.getCallerPrincipal); |
| Object securityIdentity = |
| ThreadContext.getThreadContext().getSecurityIdentity(); |
| return (java.security.Principal) |
| getSecurityService().translateTo(securityIdentity, |
| java.security.Principal.class); |
| } |
| |
| private SecurityService getSecurityService() { |
| return securityService; |
| } |
| |
| public boolean isCallerInRole(java.lang.String roleName) { |
| checkBeanState(Call.isCallerInRole); |
| ThreadContext threadContext = ThreadContext.getThreadContext(); |
| org.apache.openejb.core.CoreDeploymentInfo di = |
| (org.apache.openejb.core.CoreDeploymentInfo) |
| threadContext.getDeploymentInfo(); |
| List<String> physicalRoles = di.getPhysicalRole(roleName); |
| Object caller = threadContext.getSecurityIdentity(); |
| return securityService.isCallerAuthorized(caller, physicalRoles); |
| } |
| |
| public EJBHome getEJBHome() { |
| checkBeanState(Call.getEJBHome); |
| |
| ThreadContext threadContext = ThreadContext.getThreadContext(); |
| org.apache.openejb.core.CoreDeploymentInfo di = |
| (org.apache.openejb.core.CoreDeploymentInfo) |
| threadContext.getDeploymentInfo(); |
| |
| return di.getEJBHome(); |
| } |
| |
| public javax.ejb.EJBObject getEJBObject() { |
| checkBeanState(Call.getEJBObject); |
| |
| ThreadContext threadContext = ThreadContext.getThreadContext(); |
| org.apache.openejb.DeploymentInfo di = |
| threadContext.getDeploymentInfo(); |
| |
| EjbObjectProxyHandler handler = newEjbObjectHandler((RpcContainer) |
| di.getContainer(), threadContext.getPrimaryKey(), di.getDeploymentID(), |
| InterfaceType.EJB_OBJECT); |
| Object newProxy = null; |
| try { |
| Class[] |
| interfaces = new Class[]{di.getRemoteInterface(), |
| org.apache.openejb.core.ivm.IntraVmProxy.class}; |
| newProxy = ProxyManager.newProxyInstance(interfaces, handler); |
| } catch (IllegalAccessException iae) { |
| throw new RuntimeException("Could not create IVM proxy for " + |
| di.getRemoteInterface() + " interface"); |
| } |
| return (javax.ejb.EJBObject) newProxy; |
| } |
| |
| public EJBLocalObject getEJBLocalObject() { |
| ThreadContext threadContext = ThreadContext.getThreadContext(); |
| org.apache.openejb.DeploymentInfo di = |
| threadContext.getDeploymentInfo(); |
| |
| EjbObjectProxyHandler handler = newEjbObjectHandler((RpcContainer) |
| di.getContainer(), threadContext.getPrimaryKey(), di.getDeploymentID(), |
| InterfaceType.EJB_LOCAL); |
| handler.setLocal(true); |
| Object newProxy = null; |
| try { |
| Class[] |
| interfaces = new Class[]{di.getLocalInterface(), |
| org.apache.openejb.core.ivm.IntraVmProxy.class}; |
| newProxy = ProxyManager.newProxyInstance(interfaces, handler); |
| } catch (IllegalAccessException iae) { |
| throw new RuntimeException("Could not create IVM proxy for " + |
| di.getLocalInterface() + " interface"); |
| } |
| return (EJBLocalObject) newProxy; |
| } |
| |
| public Object getBusinessObject(Class interfce) { |
| ThreadContext threadContext = ThreadContext.getThreadContext(); |
| DeploymentInfo di = threadContext.getDeploymentInfo(); |
| |
| InterfaceType interfaceType; |
| if (di.getBusinessLocalInterface() != null && |
| di.getBusinessLocalInterface().getName().equals(interfce.getName())) { |
| interfaceType = InterfaceType.BUSINESS_LOCAL; |
| } else if (di.getBusinessRemoteInterface() != null && |
| di.getBusinessRemoteInterface().getName().equals(interfce.getName())) { |
| interfaceType = InterfaceType.BUSINESS_REMOTE; |
| } else { |
| throw new IllegalArgumentException("Component has no such |
| interface " + interfce.getName()); |
| } |
| |
| Object newProxy; |
| try { |
| EjbObjectProxyHandler handler = |
| newEjbObjectHandler((RpcContainer) di.getContainer(), |
| threadContext.getPrimaryKey(), di.getDeploymentID(), interfaceType); |
| Class[] |
| interfaces = new Class[]{interfce, IntraVmProxy.class}; |
| newProxy = ProxyManager.newProxyInstance(interfaces, handler); |
| } catch (IllegalAccessException iae) { |
| throw new InternalErrorException("Could not create IVM proxy |
| for " + interfce.getName() + " interface", iae); |
| } |
| return newProxy; |
| } |
| |
| public EJBLocalHome getEJBLocalHome() { |
| ThreadContext threadContext = ThreadContext.getThreadContext(); |
| org.apache.openejb.core.CoreDeploymentInfo di = |
| threadContext.getDeploymentInfo(); |
| |
| return di.getEJBLocalHome(); |
| } |
| |
| public TimerService getTimerService() { |
| return null; |
| } |
| |
| public Object getPrimaryKey() { |
| /* |
| * This method is only declared in the EntityContext interface and |
| is therefor |
| * unavailable in the SessionContext and doesn't not require a check |
| for bean kind (Entity vs Session). |
| */ |
| checkBeanState(Call.getPrimaryKey); |
| |
| ThreadContext threadContext = ThreadContext.getThreadContext(); |
| return threadContext.getPrimaryKey(); |
| } |
| |
| public boolean getRollbackOnly() { |
| |
| ThreadContext threadContext = ThreadContext.getThreadContext(); |
| org.apache.openejb.DeploymentInfo di = |
| threadContext.getDeploymentInfo(); |
| if (di.isBeanManagedTransaction()) { |
| throw new IllegalStateException("bean-managed transaction beans |
| can not access the getRollbackOnly( ) method"); |
| } |
| |
| checkBeanState(Call.getRollbackOnly); |
| try { |
| int status = getTransactionManager().getStatus(); |
| if (status == Status.STATUS_MARKED_ROLLBACK || status == |
| Status.STATUS_ROLLEDBACK) { |
| return true; |
| } else if (status == Status.STATUS_NO_TRANSACTION) { |
| // this would be true for Supports tx attribute where no tx |
| was propagated |
| throw new IllegalStateException("No current transaction"); |
| } else { |
| return false; |
| } |
| } catch (javax.transaction.SystemException se) { |
| throw new RuntimeException("Transaction service has thrown a |
| SystemException"); |
| } |
| } |
| |
| public void setRollbackOnly() { |
| ThreadContext threadContext = ThreadContext.getThreadContext(); |
| org.apache.openejb.DeploymentInfo di = |
| threadContext.getDeploymentInfo(); |
| if (di.isBeanManagedTransaction()) { |
| throw new IllegalStateException("bean-managed transaction beans |
| can not access the setRollbackOnly( ) method"); |
| } |
| |
| checkBeanState(Call.setRollbackOnly); |
| |
| try { |
| getTransactionManager().setRollbackOnly(); |
| } catch (javax.transaction.SystemException se) { |
| throw new RuntimeException("Transaction service has thrown a |
| SystemException"); |
| } |
| |
| } |
| |
| public javax.transaction.UserTransaction getUserTransaction() { |
| |
| ThreadContext threadContext = ThreadContext.getThreadContext(); |
| org.apache.openejb.DeploymentInfo di = |
| threadContext.getDeploymentInfo(); |
| if (di.isBeanManagedTransaction()) { |
| checkBeanState(Call.getUserTransaction); |
| return userTransaction; |
| } else { |
| throw new java.lang.IllegalStateException("container-managed |
| transaction beans can not access the UserTransaction"); |
| } |
| } |
| |
| /** |
| * Lookup a resource within the component's private naming context. |
| * |
| * @param name - Name of the entry (relative to java:comp/env). |
| * @return The looked-up object. |
| * @see |
| http://java.sun.com/javaee/5/docs/api/javax/ejb/EJBContext.html#lookup(java.lang.String) |
| * @see EJB3.0 "Core Contracts and Requirements", section 4.5.2, table |
| 2. |
| */ |
| public Object lookup(String name) { |
| Context initialContext = null; |
| Object object = null; |
| |
| try { |
| initialContext = new InitialContext(); |
| object = initialContext.lookup("java:comp/env/" + name); |
| } catch (NamingException nex) { |
| throw new IllegalArgumentException(nex); |
| } |
| return object; |
| } |
| |
| /*----------------------------------------------------*/ |
| /* UNSUPPORTED DEPRICATED METHODS */ |
| /*----------------------------------------------------*/ |
| |
| public boolean isCallerInRole(java.security.Identity role) { |
| throw new java.lang.UnsupportedOperationException(); |
| } |
| |
| public java.security.Identity getCallerIdentity() { |
| throw new java.lang.UnsupportedOperationException(); |
| } |
| |
| public java.util.Properties getEnvironment() { |
| throw new java.lang.UnsupportedOperationException(); |
| } |
| |
| protected abstract EjbObjectProxyHandler |
| newEjbObjectHandler(RpcContainer container, Object pk, Object depID, |
| InterfaceType interfaceType); |
| } |
| |
| |
| <DIV class="code panel" style="border-style: solid;border-width: 1px;"><DIV class="codeHeader panelHeader" style="border-bottom-width: 1px;border-bottom-style: solid;"><B>EntityContext.java</B></DIV><DIV class="codeContent panelContent"> |
| /** |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.openejb.core.entity; |
| |
| import org.apache.openejb.RpcContainer; |
| import org.apache.openejb.InterfaceType; |
| import org.apache.openejb.spi.SecurityService; |
| import org.apache.openejb.core.ThreadContext; |
| import org.apache.openejb.core.Operation; |
| import org.apache.openejb.core.ivm.EjbObjectProxyHandler; |
| |
| import javax.transaction.TransactionManager; |
| |
| public class EntityContext extends org.apache.openejb.core.CoreContext |
| implements javax.ejb.EntityContext { |
| |
| public EntityContext(TransactionManager transactionManager, |
| SecurityService securityService) { |
| super(transactionManager, securityService); |
| } |
| |
| public void checkBeanState(Call methodCategory) throws |
| IllegalStateException { |
| /* |
| The super class, CoreContext determines if |
| Context.getUserTransaction( ) method |
| maybe called before invoking this.checkBeanState( ). Only "bean |
| managed" transaction |
| beans may access this method. |
| |
| The USER_TRANSACTION_METHOD constant will never be a methodCategory |
| because entity beans are not allowed to have "bean managed" |
| transactions. |
| |
| USER_TRANSACTION_METHOD: |
| */ |
| |
| ThreadContext callContext = ThreadContext.getThreadContext(); |
| org.apache.openejb.DeploymentInfo di = |
| callContext.getDeploymentInfo(); |
| |
| Operation currentOperation = callContext.getCurrentOperation(); |
| switch (currentOperation) { |
| case SET_CONTEXT: |
| case UNSET_CONTEXT: |
| switch(methodCategory){ |
| case getCallerPrincipal: |
| case getRollbackOnly: |
| case isCallerInRole: |
| case setRollbackOnly: |
| case getEJBObject: |
| case getPrimaryKey: |
| case getUserTransaction: |
| throw new IllegalStateException(methodCategory + |
| "cannot be called in " + currentOperation); |
| } |
| break; |
| |
| case CREATE: |
| case FIND: |
| case HOME: |
| switch(methodCategory){ |
| case getEJBObject: |
| case getPrimaryKey: |
| case getUserTransaction: |
| throw new IllegalStateException(methodCategory + |
| "cannot be called in " + currentOperation); |
| } |
| break; |
| |
| case ACTIVATE: |
| case PASSIVATE: |
| switch(methodCategory){ |
| case getCallerPrincipal: |
| case getRollbackOnly: |
| case isCallerInRole: |
| case setRollbackOnly: |
| case getUserTransaction: |
| throw new IllegalStateException(methodCategory + |
| "cannot be called in " + currentOperation); |
| } |
| break; |
| |
| case POST_CREATE: |
| case REMOVE: |
| case LOAD: |
| case STORE: |
| switch(methodCategory){ |
| case getUserTransaction: |
| throw new IllegalStateException(methodCategory + |
| "cannot be called in " + currentOperation); |
| } |
| break; |
| |
| } |
| |
| } |
| |
| protected EjbObjectProxyHandler newEjbObjectHandler(RpcContainer |
| container, Object pk, Object depID, InterfaceType interfaceType) { |
| return new EntityEjbObjectHandler(container, pk, depID, |
| interfaceType); |
| } |
| |
| } |
| |
| |