0001: /**
0002: * Licensed to the Apache Software Foundation (ASF) under one or more
0003: * contributor license agreements. See the NOTICE file distributed with
0004: * this work for additional information regarding copyright ownership.
0005: * The ASF licenses this file to You under the Apache License, Version 2.0
0006: * (the "License"); you may not use this file except in compliance with
0007: * the License. You may obtain a copy of the License at
0008: *
0009: * http://www.apache.org/licenses/LICENSE-2.0
0010: *
0011: * Unless required by applicable law or agreed to in writing, software
0012: * distributed under the License is distributed on an "AS IS" BASIS,
0013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014: * See the License for the specific language governing permissions and
0015: * limitations under the License.
0016: */package org.apache.openejb.core;
0017:
0018: import java.lang.reflect.Method;
0019: import java.util.HashMap;
0020: import java.util.HashSet;
0021: import java.util.List;
0022: import java.util.Map;
0023: import java.util.Collection;
0024: import java.util.Collections;
0025: import java.util.Set;
0026: import java.util.ArrayList;
0027: import java.util.TreeSet;
0028: import javax.ejb.EJBHome;
0029: import javax.ejb.EJBLocalHome;
0030: import javax.ejb.EJBLocalObject;
0031: import javax.ejb.SessionSynchronization;
0032: import javax.ejb.MessageDrivenBean;
0033: import javax.ejb.TimedObject;
0034: import javax.ejb.Timer;
0035: import javax.persistence.EntityManagerFactory;
0036: import javax.naming.Context;
0037:
0038: import org.apache.openejb.Container;
0039: import org.apache.openejb.SystemException;
0040: import org.apache.openejb.InterfaceType;
0041: import org.apache.openejb.DeploymentInfo;
0042: import org.apache.openejb.BeanType;
0043: import org.apache.openejb.Injection;
0044: import org.apache.openejb.OpenEJBException;
0045: import org.apache.openejb.core.cmp.KeyGenerator;
0046: import org.apache.openejb.core.ivm.EjbHomeProxyHandler;
0047: import org.apache.openejb.core.stateful.SessionSynchronizationTxPolicy;
0048: import org.apache.openejb.core.stateful.StatefulBeanManagedTxPolicy;
0049: import org.apache.openejb.core.stateful.StatefulContainerManagedTxPolicy;
0050: import org.apache.openejb.core.stateless.StatelessBeanManagedTxPolicy;
0051: import org.apache.openejb.core.transaction.TransactionContainer;
0052: import org.apache.openejb.core.transaction.TransactionPolicy;
0053: import org.apache.openejb.core.transaction.TxMandatory;
0054: import org.apache.openejb.core.transaction.TxNever;
0055: import org.apache.openejb.core.transaction.TxNotSupported;
0056: import org.apache.openejb.core.transaction.TxRequired;
0057: import org.apache.openejb.core.transaction.TxRequiresNew;
0058: import org.apache.openejb.core.transaction.TxSupports;
0059: import org.apache.openejb.core.interceptor.InterceptorData;
0060: import org.apache.openejb.core.mdb.MessageDrivenBeanManagedTxPolicy;
0061: import org.apache.openejb.core.timer.EjbTimerService;
0062: import org.apache.openejb.util.Index;
0063: import org.apache.openejb.util.LogCategory;
0064: import org.apache.openejb.util.Logger;
0065:
0066: /**
0067: * @org.apache.xbean.XBean element="deployment"
0068: */
0069: public class CoreDeploymentInfo implements
0070: org.apache.openejb.DeploymentInfo {
0071:
0072: private boolean destroyed;
0073: private Class homeInterface;
0074: private Class remoteInterface;
0075: private Class localHomeInterface;
0076: private Class localInterface;
0077: private Class beanClass;
0078: private Class pkClass;
0079: private final List<Class> businessLocals = new ArrayList<Class>();
0080: private final List<Class> businessRemotes = new ArrayList<Class>();
0081: private Class mdbInterface;
0082: private Class serviceEndpointInterface;
0083:
0084: private final List<Method> aroundInvoke = new ArrayList<Method>();
0085:
0086: private final List<Method> postConstruct = new ArrayList<Method>();
0087: private final List<Method> preDestroy = new ArrayList<Method>();
0088:
0089: private final List<Method> postActivate = new ArrayList<Method>();
0090: private final List<Method> prePassivate = new ArrayList<Method>();
0091:
0092: private final List<Method> removeMethods = new ArrayList<Method>();
0093:
0094: private Method ejbTimeout;
0095: private EjbTimerService ejbTimerService;
0096:
0097: private boolean isBeanManagedTransaction;
0098: private boolean isReentrant;
0099: private Container container;
0100: private EJBHome ejbHomeRef;
0101: private EJBLocalHome ejbLocalHomeRef;
0102: private BusinessLocalHome businessLocalHomeRef;
0103: private BusinessRemoteHome businessRemoteHomeRef;
0104: private String destinationId;
0105: private final Map<Class, Object> data = new HashMap<Class, Object>();
0106:
0107: private String ejbName;
0108: private String moduleId;
0109: private String runAs;
0110:
0111: private Object containerData;
0112:
0113: private final DeploymentContext context;
0114:
0115: private Method createMethod = null;
0116:
0117: private final Map<Method, Method> postCreateMethodMap = new HashMap<Method, Method>();
0118: private final BeanType componentType;
0119:
0120: private final Map<Method, Collection<String>> methodPermissions = new HashMap<Method, Collection<String>>();
0121: private final Map<Method, Byte> methodTransactionAttributes = new HashMap<Method, Byte>();
0122: private final Map<Method, TransactionPolicy> methodTransactionPolicies = new HashMap<Method, TransactionPolicy>();
0123: private final Map<Method, List<InterceptorData>> methodInterceptors = new HashMap<Method, List<InterceptorData>>();
0124: private final List<InterceptorData> callbackInterceptors = new ArrayList<InterceptorData>();
0125: private final Map<Method, Method> methodMap = new HashMap<Method, Method>();
0126: private final Map<String, String> securityRoleReferenceMap = new HashMap<String, String>();
0127: private String jarPath;
0128: private final Map<String, String> activationProperties = new HashMap<String, String>();
0129: private final List<Injection> injections = new ArrayList<Injection>();
0130: private Index<EntityManagerFactory, Map> extendedEntityManagerFactories;
0131: private final Map<Class, InterfaceType> interfaces = new HashMap<Class, InterfaceType>();
0132: private final Map<Class, ExceptionType> exceptions = new HashMap<Class, ExceptionType>();
0133:
0134: public Class getInterface(InterfaceType interfaceType) {
0135: switch (interfaceType) {
0136: case EJB_HOME:
0137: return getHomeInterface();
0138: case EJB_OBJECT:
0139: return getRemoteInterface();
0140: case EJB_LOCAL_HOME:
0141: return getLocalHomeInterface();
0142: case EJB_LOCAL:
0143: return getLocalInterface();
0144: case BUSINESS_LOCAL:
0145: return getBusinessLocalInterface();
0146: case BUSINESS_REMOTE:
0147: return getBusinessRemoteInterface();
0148: case BUSINESS_REMOTE_HOME:
0149: return DeploymentInfo.BusinessRemoteHome.class;
0150: case BUSINESS_LOCAL_HOME:
0151: return DeploymentInfo.BusinessLocalHome.class;
0152: case SERVICE_ENDPOINT:
0153: return getServiceEndpointInterface();
0154: default:
0155: throw new IllegalStateException(
0156: "Unexpected enum constant: " + interfaceType);
0157: }
0158: }
0159:
0160: public List<Class> getInterfaces(InterfaceType interfaceType) {
0161: switch (interfaceType) {
0162: case BUSINESS_LOCAL:
0163: return getBusinessLocalInterfaces();
0164: case BUSINESS_REMOTE:
0165: return getBusinessRemoteInterfaces();
0166: default: {
0167: List<Class> interfaces = new ArrayList<Class>();
0168: interfaces.add(getInterface(interfaceType));
0169: return interfaces;
0170: }
0171: }
0172: }
0173:
0174: public InterfaceType getInterfaceType(Class clazz) {
0175: InterfaceType type = interfaces.get(clazz);
0176: if (type != null)
0177: return type;
0178:
0179: if (javax.ejb.EJBLocalHome.class.isAssignableFrom(clazz))
0180: return InterfaceType.EJB_LOCAL_HOME;
0181: if (javax.ejb.EJBLocalObject.class.isAssignableFrom(clazz))
0182: return InterfaceType.EJB_LOCAL;
0183: if (javax.ejb.EJBHome.class.isAssignableFrom(clazz))
0184: return InterfaceType.EJB_HOME;
0185: if (javax.ejb.EJBObject.class.isAssignableFrom(clazz))
0186: return InterfaceType.EJB_OBJECT;
0187:
0188: return null;
0189: }
0190:
0191: public CoreDeploymentInfo(DeploymentContext context,
0192: Class beanClass, Class homeInterface,
0193: Class remoteInterface, Class localHomeInterface,
0194: Class localInterface, Class serviceEndpointInterface,
0195: List<Class> businessLocals, List<Class> businessRemotes,
0196: Class pkClass, BeanType componentType)
0197: throws SystemException {
0198:
0199: this .context = context;
0200: this .pkClass = pkClass;
0201:
0202: this .homeInterface = homeInterface;
0203: this .remoteInterface = remoteInterface;
0204: this .localInterface = localInterface;
0205: this .localHomeInterface = localHomeInterface;
0206: if (businessLocals != null) {
0207: this .businessLocals.addAll(businessLocals);
0208: }
0209: if (businessRemotes != null) {
0210: this .businessRemotes.addAll(businessRemotes);
0211: }
0212: this .remoteInterface = remoteInterface;
0213: this .beanClass = beanClass;
0214: this .pkClass = pkClass;
0215: this .serviceEndpointInterface = serviceEndpointInterface;
0216:
0217: this .componentType = componentType;
0218:
0219: // if (businessLocal != null && localHomeInterface == null){
0220: // this.localHomeInterface = BusinessLocalHome.class;
0221: // }
0222: //
0223: // if (businessRemote != null && homeInterface == null){
0224: // this.homeInterface = BusinessRemoteHome.class;
0225: // }
0226:
0227: // createMethodMap();
0228:
0229: if (TimedObject.class.isAssignableFrom(beanClass)) {
0230: try {
0231: this .ejbTimeout = beanClass.getMethod("ejbTimeout",
0232: Timer.class);
0233: } catch (NoSuchMethodException e) {
0234: throw new IllegalStateException(e);
0235: }
0236: }
0237:
0238: addInterface(javax.ejb.EJBHome.class, InterfaceType.EJB_HOME);
0239: addInterface(javax.ejb.EJBObject.class,
0240: InterfaceType.EJB_OBJECT);
0241:
0242: addInterface(javax.ejb.EJBLocalHome.class,
0243: InterfaceType.EJB_LOCAL_HOME);
0244: addInterface(javax.ejb.EJBLocalObject.class,
0245: InterfaceType.EJB_LOCAL);
0246:
0247: addInterface(getHomeInterface(), InterfaceType.EJB_HOME);
0248: addInterface(getRemoteInterface(), InterfaceType.EJB_OBJECT);
0249:
0250: addInterface(getLocalHomeInterface(),
0251: InterfaceType.EJB_LOCAL_HOME);
0252: addInterface(getLocalInterface(), InterfaceType.EJB_LOCAL);
0253:
0254: addInterface(DeploymentInfo.BusinessRemoteHome.class,
0255: InterfaceType.BUSINESS_REMOTE_HOME);
0256: for (Class businessRemote : this .businessRemotes) {
0257: addInterface(businessRemote, InterfaceType.BUSINESS_REMOTE);
0258: }
0259:
0260: addInterface(DeploymentInfo.BusinessLocalHome.class,
0261: InterfaceType.BUSINESS_LOCAL_HOME);
0262: for (Class businessLocal : this .businessLocals) {
0263: addInterface(businessLocal, InterfaceType.BUSINESS_LOCAL);
0264: }
0265:
0266: addInterface(getServiceEndpointInterface(),
0267: InterfaceType.SERVICE_ENDPOINT);
0268: }
0269:
0270: /**
0271: * DMB: This is a not so reliable way to determine the proxy type
0272: * The proxy type really should come with the call in the invoke.
0273: *
0274: * @param interfce
0275: * @param type
0276: */
0277: private void addInterface(Class interfce, InterfaceType type) {
0278: if (interfce == null)
0279: return;
0280: interfaces.put(interfce, type);
0281:
0282: for (Class clazz : interfce.getInterfaces()) {
0283: addInterface(clazz, type);
0284: }
0285: }
0286:
0287: public void addApplicationException(Class exception,
0288: boolean rollback) {
0289: if (rollback) {
0290: exceptions.put(exception,
0291: ExceptionType.APPLICATION_ROLLBACK);
0292: } else {
0293: exceptions.put(exception, ExceptionType.APPLICATION);
0294: }
0295: }
0296:
0297: public ExceptionType getExceptionType(Throwable e) {
0298: // Errors are always system exceptions
0299: if (!(e instanceof Exception)) {
0300: return ExceptionType.SYSTEM;
0301: }
0302:
0303: // check the registered app exceptions
0304: ExceptionType type = exceptions.get(e.getClass());
0305: if (type != null) {
0306: return type;
0307: }
0308:
0309: // Unregistered - runtime exceptions are system exception and the rest are application exceptions
0310: if (e instanceof RuntimeException) {
0311: return ExceptionType.SYSTEM;
0312: } else {
0313: return ExceptionType.APPLICATION;
0314: }
0315: }
0316:
0317: public CoreDeploymentInfo(DeploymentContext context,
0318: Class beanClass, Class mdbInterface,
0319: Map<String, String> activationProperties)
0320: throws SystemException {
0321: this .context = context;
0322: this .beanClass = beanClass;
0323: this .mdbInterface = mdbInterface;
0324: this .activationProperties.putAll(activationProperties);
0325: this .componentType = BeanType.MESSAGE_DRIVEN;
0326:
0327: if (TimedObject.class.isAssignableFrom(beanClass)) {
0328: try {
0329: this .ejbTimeout = beanClass.getMethod("ejbTimeout",
0330: Timer.class);
0331: } catch (NoSuchMethodException e) {
0332: throw new IllegalStateException(e);
0333: }
0334: }
0335: createMethodMap();
0336: }
0337:
0338: public boolean isDestroyed() {
0339: return destroyed;
0340: }
0341:
0342: public void setDestroyed(boolean destroyed) {
0343: this .destroyed = destroyed;
0344: }
0345:
0346: @SuppressWarnings({"unchecked"})
0347: public <T> T get(Class<T> type) {
0348: return (T) data.get(type);
0349: }
0350:
0351: @SuppressWarnings({"unchecked"})
0352: public <T> T set(Class<T> type, T value) {
0353: return (T) data.put(type, value);
0354: }
0355:
0356: public List<Injection> getInjections() {
0357: return injections;
0358: }
0359:
0360: public Index<EntityManagerFactory, Map> getExtendedEntityManagerFactories() {
0361: return extendedEntityManagerFactories;
0362: }
0363:
0364: public void setExtendedEntityManagerFactories(
0365: Index<EntityManagerFactory, Map> extendedEntityManagerFactories) {
0366: this .extendedEntityManagerFactories = extendedEntityManagerFactories;
0367: }
0368:
0369: public Object getContainerData() {
0370: return containerData;
0371: }
0372:
0373: public void setContainerData(Object containerData) {
0374: this .containerData = containerData;
0375: }
0376:
0377: public void setContainer(Container container) {
0378: this .container = container;
0379: }
0380:
0381: public BeanType getComponentType() {
0382: return componentType;
0383: }
0384:
0385: public byte getTransactionAttribute(Method method) {
0386: Byte byteWrapper = methodTransactionAttributes.get(method);
0387: if (byteWrapper == null) {
0388: return TX_NOT_SUPPORTED;// non remote or home interface method
0389: } else {
0390: return byteWrapper;
0391: }
0392: }
0393:
0394: public TransactionPolicy getTransactionPolicy(Method method) {
0395: TransactionPolicy policy = methodTransactionPolicies
0396: .get(method);
0397: if (policy == null && !isBeanManagedTransaction) {
0398: Method beanMethod = getMatchingBeanMethod(method);
0399: if (beanMethod != null) {
0400: policy = methodTransactionPolicies.get(beanMethod);
0401: }
0402: }
0403: if (policy == null && !isBeanManagedTransaction) {
0404: Logger log = Logger.getInstance(LogCategory.OPENEJB,
0405: "org.apache.openejb.util.resources");
0406: log
0407: .debug("The following method doesn't have a transaction policy assigned: "
0408: + method);
0409: }
0410: if (policy == null && container instanceof TransactionContainer) {
0411: if (isBeanManagedTransaction) {
0412: if (componentType == BeanType.STATEFUL) {
0413: policy = new StatefulBeanManagedTxPolicy(
0414: (TransactionContainer) container);
0415: } else if (componentType == BeanType.STATELESS) {
0416: policy = new StatelessBeanManagedTxPolicy(
0417: (TransactionContainer) container);
0418: } else if (componentType == BeanType.MESSAGE_DRIVEN) {
0419: policy = new MessageDrivenBeanManagedTxPolicy(
0420: (TransactionContainer) container);
0421: }
0422: } else if (componentType == BeanType.STATEFUL) {
0423: policy = new TxRequired(
0424: (TransactionContainer) container);
0425: if (!isBeanManagedTransaction
0426: && SessionSynchronization.class
0427: .isAssignableFrom(beanClass)) {
0428: policy = new SessionSynchronizationTxPolicy(policy);
0429: } else {
0430: policy = new StatefulContainerManagedTxPolicy(
0431: policy);
0432: }
0433: } else {
0434: // default transaction policy is required
0435: policy = new TxRequired(
0436: (TransactionContainer) container);
0437: }
0438: methodTransactionPolicies.put(method, policy);
0439: }
0440: if (policy == null) {
0441: policy = new TxSupports((TransactionContainer) container);
0442: }
0443: return policy;
0444: }
0445:
0446: public Collection<String> getAuthorizedRoles(Method method) {
0447: Collection<String> roleSet = methodPermissions.get(method);
0448: if (roleSet == null) {
0449: return Collections.emptySet();
0450: }
0451: return roleSet;
0452: }
0453:
0454: public String[] getAuthorizedRoles(String action) {
0455: return null;
0456: }
0457:
0458: public Container getContainer() {
0459: return container;
0460: }
0461:
0462: public Object getDeploymentID() {
0463: return context.getId();
0464: }
0465:
0466: public boolean isBeanManagedTransaction() {
0467: return isBeanManagedTransaction;
0468: }
0469:
0470: public Class getHomeInterface() {
0471: return homeInterface;
0472: }
0473:
0474: public Class getRemoteInterface() {
0475: return remoteInterface;
0476: }
0477:
0478: public Class getLocalHomeInterface() {
0479: return localHomeInterface;
0480: }
0481:
0482: public Class getLocalInterface() {
0483: return localInterface;
0484: }
0485:
0486: public Class getBeanClass() {
0487: return beanClass;
0488: }
0489:
0490: public Class getBusinessLocalInterface() {
0491: return businessLocals.size() > 0 ? businessLocals.get(0) : null;
0492: }
0493:
0494: public Class getBusinessRemoteInterface() {
0495: return businessRemotes.size() > 0 ? businessRemotes.get(0)
0496: : null;
0497: }
0498:
0499: public List<Class> getBusinessLocalInterfaces() {
0500: return businessLocals;
0501: }
0502:
0503: public List<Class> getBusinessRemoteInterfaces() {
0504: return businessRemotes;
0505: }
0506:
0507: public Class getMdbInterface() {
0508: return mdbInterface;
0509: }
0510:
0511: public Class getServiceEndpointInterface() {
0512: return serviceEndpointInterface;
0513: }
0514:
0515: public Map<String, String> getActivationProperties() {
0516: return activationProperties;
0517: }
0518:
0519: public void setActivationProperties(
0520: Map<String, String> activationProperties) {
0521: this .activationProperties.clear();
0522: this .activationProperties.putAll(activationProperties);
0523: }
0524:
0525: public Class getPrimaryKeyClass() {
0526: return pkClass;
0527: }
0528:
0529: public EJBHome getEJBHome() {
0530: if (getHomeInterface() == null) {
0531: throw new IllegalStateException(
0532: "This component has no home interface: "
0533: + getDeploymentID());
0534: }
0535: if (ejbHomeRef == null) {
0536: ejbHomeRef = (EJBHome) EjbHomeProxyHandler.createHomeProxy(
0537: this , InterfaceType.EJB_HOME);
0538: }
0539: return ejbHomeRef;
0540: }
0541:
0542: public EJBLocalHome getEJBLocalHome() {
0543: if (getLocalHomeInterface() == null) {
0544: throw new IllegalStateException(
0545: "This component has no local home interface: "
0546: + getDeploymentID());
0547: }
0548: if (ejbLocalHomeRef == null) {
0549: ejbLocalHomeRef = (EJBLocalHome) EjbHomeProxyHandler
0550: .createHomeProxy(this , InterfaceType.EJB_LOCAL_HOME);
0551: }
0552: return ejbLocalHomeRef;
0553: }
0554:
0555: public BusinessLocalHome getBusinessLocalHome() {
0556: return getBusinessLocalHome(getBusinessLocalInterfaces());
0557: }
0558:
0559: public BusinessLocalHome getBusinessLocalHome(List<Class> interfaces) {
0560: if (getBusinessLocalInterfaces().size() == 0) {
0561: throw new IllegalStateException(
0562: "This component has no business local interfaces: "
0563: + getDeploymentID());
0564: }
0565: if (interfaces.size() == 0) {
0566: throw new IllegalArgumentException(
0567: "No interface classes were specified");
0568: }
0569: for (Class clazz : interfaces) {
0570: if (!getBusinessLocalInterfaces().contains(clazz)) {
0571: throw new IllegalArgumentException(
0572: "Not a business interface of this bean:"
0573: + clazz.getName());
0574: }
0575: }
0576:
0577: return (BusinessLocalHome) EjbHomeProxyHandler.createHomeProxy(
0578: this , InterfaceType.BUSINESS_LOCAL_HOME, interfaces);
0579: }
0580:
0581: public BusinessRemoteHome getBusinessRemoteHome() {
0582: return getBusinessRemoteHome(getBusinessRemoteInterfaces());
0583: }
0584:
0585: public BusinessRemoteHome getBusinessRemoteHome(
0586: List<Class> interfaces) {
0587: if (getBusinessRemoteInterfaces().size() == 0) {
0588: throw new IllegalStateException(
0589: "This component has no business remote interfaces: "
0590: + getDeploymentID());
0591: }
0592: if (interfaces.size() == 0) {
0593: throw new IllegalArgumentException(
0594: "No interface classes were specified");
0595: }
0596: for (Class clazz : interfaces) {
0597: if (!getBusinessRemoteInterfaces().contains(clazz)) {
0598: throw new IllegalArgumentException(
0599: "Not a business interface of this bean:"
0600: + clazz.getName());
0601: }
0602: }
0603:
0604: return (BusinessRemoteHome) EjbHomeProxyHandler
0605: .createHomeProxy(this ,
0606: InterfaceType.BUSINESS_REMOTE_HOME, interfaces);
0607: }
0608:
0609: public String getDestinationId() {
0610: return destinationId;
0611: }
0612:
0613: public void setDestinationId(String destinationId) {
0614: this .destinationId = destinationId;
0615: }
0616:
0617: public void setBeanManagedTransaction(boolean value) {
0618: isBeanManagedTransaction = value;
0619: }
0620:
0621: public Context getJndiEnc() {
0622: return context.getJndiContext();
0623: }
0624:
0625: public ClassLoader getClassLoader() {
0626: return context.getClassLoader();
0627: }
0628:
0629: public boolean isReentrant() {
0630: return isReentrant;
0631: }
0632:
0633: public void setIsReentrant(boolean reentrant) {
0634: isReentrant = reentrant;
0635: }
0636:
0637: public Method getMatchingBeanMethod(Method interfaceMethod) {
0638: Method method = methodMap.get(interfaceMethod);
0639: return (method == null) ? interfaceMethod : method;
0640: }
0641:
0642: public void appendMethodPermissions(Method m, List<String> roleNames) {
0643: Collection<String> hs = methodPermissions.get(m);
0644: if (hs == null) {
0645: hs = new HashSet<String>();// FIXME: Set appropriate load and intial capacity
0646: methodPermissions.put(m, hs);
0647: }
0648: for (String roleName : roleNames) {
0649: hs.add(roleName);
0650: }
0651: }
0652:
0653: public String getSecurityRole(String securityRoleReference) {
0654: return securityRoleReferenceMap.get(securityRoleReference);
0655: }
0656:
0657: public void addSecurityRoleReference(String securityRoleReference,
0658: String linkedRoleName) {
0659: securityRoleReferenceMap.put(securityRoleReference,
0660: linkedRoleName);
0661: }
0662:
0663: public void setMethodTransactionAttribute(Method method,
0664: String transAttribute) throws OpenEJBException {
0665: Byte byteValue = null;
0666: TransactionPolicy policy = null;
0667:
0668: if (transAttribute.equalsIgnoreCase("Supports")) {
0669: if (container instanceof TransactionContainer) {
0670: policy = new TxSupports(
0671: (TransactionContainer) container);
0672: }
0673: byteValue = new Byte(TX_SUPPORTS);
0674:
0675: } else if (transAttribute.equalsIgnoreCase("RequiresNew")) {
0676: if (container instanceof TransactionContainer) {
0677: policy = new TxRequiresNew(
0678: (TransactionContainer) container);
0679: }
0680: byteValue = new Byte(TX_REQUIRES_NEW);
0681:
0682: } else if (transAttribute.equalsIgnoreCase("Mandatory")) {
0683: if (container instanceof TransactionContainer) {
0684: policy = new TxMandatory(
0685: (TransactionContainer) container);
0686: }
0687: byteValue = new Byte(TX_MANDITORY);
0688:
0689: } else if (transAttribute.equalsIgnoreCase("NotSupported")) {
0690: if (container instanceof TransactionContainer) {
0691: policy = new TxNotSupported(
0692: (TransactionContainer) container);
0693: }
0694: byteValue = new Byte(TX_NOT_SUPPORTED);
0695:
0696: } else if (transAttribute.equalsIgnoreCase("Required")) {
0697: if (container instanceof TransactionContainer) {
0698: policy = new TxRequired(
0699: (TransactionContainer) container);
0700: }
0701: byteValue = new Byte(TX_REQUIRED);
0702:
0703: } else if (transAttribute.equalsIgnoreCase("Never")) {
0704: if (container instanceof TransactionContainer) {
0705: policy = new TxNever((TransactionContainer) container);
0706: }
0707: byteValue = new Byte(TX_NEVER);
0708: } else {
0709: throw new IllegalArgumentException(
0710: "Invalid transaction attribute \"" + transAttribute
0711: + "\" declared for method "
0712: + method.getName()
0713: + ". Please check your configuration.");
0714: }
0715:
0716: /* EJB 1.1 page 55
0717: Only a stateful Session bean with container-managed transaction demarcation may implement the
0718: SessionSynchronization interface. A stateless Session bean must not implement the SessionSynchronization
0719: interface.
0720: */
0721:
0722: if (componentType == BeanType.STATEFUL
0723: && !isBeanManagedTransaction
0724: && container instanceof TransactionContainer) {
0725:
0726: if (SessionSynchronization.class
0727: .isAssignableFrom(beanClass)) {
0728: if (!transAttribute.equals("Never")
0729: && !transAttribute.equals("NotSupported")) {
0730: policy = new SessionSynchronizationTxPolicy(policy);
0731: }
0732: } else {
0733: policy = new StatefulContainerManagedTxPolicy(policy);
0734: }
0735: }
0736:
0737: /**
0738: Only the NOT_SUPPORTED and REQUIRED transaction attributes may be used for message-driven
0739: bean message listener methods. The use of the other transaction attributes is not meaningful
0740: for message-driven bean message listener methods because there is no pre-existing client transaction
0741: context(REQUIRES_NEW, SUPPORTS) and no client to handle exceptions (MANDATORY, NEVER).
0742: */
0743: if (componentType.isMessageDriven()
0744: && !isBeanManagedTransaction
0745: && container instanceof TransactionContainer) {
0746: if (policy.getPolicyType() != TransactionPolicy.Type.NotSupported
0747: && policy.getPolicyType() != TransactionPolicy.Type.Required) {
0748:
0749: if (method.equals(this .ejbTimeout)
0750: && policy.getPolicyType() == TransactionPolicy.Type.RequiresNew) {
0751: // do nothing. This is allowed as the timer callback method for a message driven bean
0752: // can also have a transaction policy of RequiresNew Sec 5.4.12 of Ejb 3.0 Core Spec
0753: } else {
0754: throw new OpenEJBException(
0755: "The transaction attribute "
0756: + policy.policyToString()
0757: + "is not supported for the method "
0758: + method.getName()
0759: + " of the Message Driven Bean "
0760: + beanClass.getName());
0761: }
0762: }
0763: }
0764: methodTransactionAttributes.put(method, byteValue);
0765: methodTransactionPolicies.put(method, policy);
0766: }
0767:
0768: public List<Method> getAroundInvoke() {
0769: return aroundInvoke;
0770: }
0771:
0772: public List<Method> getPostConstruct() {
0773: return postConstruct;
0774: }
0775:
0776: public List<Method> getPreDestroy() {
0777: return preDestroy;
0778: }
0779:
0780: public List<Method> getPostActivate() {
0781: return postActivate;
0782: }
0783:
0784: public List<Method> getPrePassivate() {
0785: return prePassivate;
0786: }
0787:
0788: public List<Method> getRemoveMethods() {
0789: return removeMethods;
0790: }
0791:
0792: private final Map<Method, Boolean> removeExceptionPolicy = new HashMap<Method, Boolean>();
0793:
0794: public void setRetainIfExeption(Method removeMethod, boolean retain) {
0795: if (getRemoveMethods().contains(removeMethod)) {
0796: removeExceptionPolicy.put(removeMethod, retain);
0797: }
0798: }
0799:
0800: public boolean retainIfExeption(Method removeMethod) {
0801: Boolean retain = removeExceptionPolicy.get(removeMethod);
0802: return retain != null && retain;
0803: }
0804:
0805: public List<InterceptorData> getMethodInterceptors(Method method) {
0806: List<InterceptorData> interceptors = methodInterceptors
0807: .get(method);
0808: if (interceptors == null) {
0809: interceptors = new ArrayList<InterceptorData>();
0810: }
0811: return interceptors;
0812: }
0813:
0814: public void setMethodInterceptors(Method method,
0815: List<InterceptorData> interceptors) {
0816: methodInterceptors.put(method, interceptors);
0817: this .interceptors.addAll(interceptors);
0818: }
0819:
0820: private final Set<InterceptorData> interceptors = new HashSet<InterceptorData>();
0821:
0822: public Set<InterceptorData> getAllInterceptors() {
0823: return interceptors;
0824: }
0825:
0826: public List<InterceptorData> getCallbackInterceptors() {
0827: return callbackInterceptors;
0828: }
0829:
0830: public void setCallbackInterceptors(
0831: List<InterceptorData> callbackInterceptors) {
0832: this .callbackInterceptors.clear();
0833: this .callbackInterceptors.addAll(callbackInterceptors);
0834: this .interceptors.addAll(callbackInterceptors);
0835: }
0836:
0837: public void createMethodMap()
0838: throws org.apache.openejb.SystemException {
0839: if (remoteInterface != null) {
0840: mapObjectInterface(remoteInterface);
0841: mapHomeInterface(homeInterface);
0842: }
0843:
0844: if (localInterface != null) {
0845: mapObjectInterface(localInterface);
0846: mapHomeInterface(localHomeInterface);
0847: }
0848:
0849: if (serviceEndpointInterface != null) {
0850: mapObjectInterface(serviceEndpointInterface);
0851: }
0852:
0853: for (Class businessLocal : businessLocals) {
0854: mapObjectInterface(businessLocal);
0855: }
0856:
0857: for (Class businessRemote : businessRemotes) {
0858: mapObjectInterface(businessRemote);
0859: }
0860:
0861: if (componentType == BeanType.MESSAGE_DRIVEN
0862: && MessageDrivenBean.class.isAssignableFrom(beanClass)) {
0863: try {
0864: createMethod = beanClass.getMethod("ejbCreate");
0865: } catch (NoSuchMethodException e) {
0866: // if there isn't an ejbCreate method that is fine
0867: }
0868: }
0869:
0870: try {
0871: // map the remove methods
0872: if (componentType == BeanType.STATEFUL) {
0873:
0874: Method beanMethod = null;
0875: if (javax.ejb.SessionBean.class
0876: .isAssignableFrom(beanClass)) {
0877: beanMethod = javax.ejb.SessionBean.class
0878: .getDeclaredMethod("ejbRemove");
0879: } else {
0880: for (Method method : getRemoveMethods()) {
0881: if (method.getParameterTypes().length == 0) {
0882: beanMethod = method;
0883: break;
0884: }
0885: }
0886: if (beanMethod == null
0887: && (homeInterface != null || localHomeInterface != null)) {
0888: throw new IllegalStateException(
0889: "Bean class has no @Remove methods to match EJBObject.remove() or EJBLocalObject.remove(). A no-arg remove method must be added: beanClass="
0890: + beanClass.getName());
0891: }
0892: }
0893:
0894: Method clientMethod = EJBHome.class.getDeclaredMethod(
0895: "remove", javax.ejb.Handle.class);
0896: mapMethods(clientMethod, beanMethod);
0897: clientMethod = EJBHome.class.getDeclaredMethod(
0898: "remove", java.lang.Object.class);
0899: mapMethods(clientMethod, beanMethod);
0900: clientMethod = javax.ejb.EJBObject.class
0901: .getDeclaredMethod("remove");
0902: mapMethods(clientMethod, beanMethod);
0903: clientMethod = javax.ejb.EJBLocalObject.class
0904: .getDeclaredMethod("remove");
0905: mapMethods(clientMethod, beanMethod);
0906: } else if (componentType == BeanType.BMP_ENTITY
0907: || componentType == BeanType.CMP_ENTITY) {
0908: Method beanMethod = javax.ejb.EntityBean.class
0909: .getDeclaredMethod("ejbRemove");
0910: Method clientMethod = EJBHome.class.getDeclaredMethod(
0911: "remove", javax.ejb.Handle.class);
0912: mapMethods(clientMethod, beanMethod);
0913: clientMethod = EJBHome.class.getDeclaredMethod(
0914: "remove", java.lang.Object.class);
0915: mapMethods(clientMethod, beanMethod);
0916: clientMethod = javax.ejb.EJBObject.class
0917: .getDeclaredMethod("remove");
0918: mapMethods(clientMethod, beanMethod);
0919: clientMethod = javax.ejb.EJBLocalObject.class
0920: .getDeclaredMethod("remove");
0921: mapMethods(clientMethod, beanMethod);
0922: }
0923: } catch (java.lang.NoSuchMethodException nsme) {
0924: throw new org.apache.openejb.SystemException(nsme);
0925: }
0926:
0927: if (mdbInterface != null) {
0928: mapObjectInterface(mdbInterface);
0929: }
0930: }
0931:
0932: private void mapHomeInterface(Class intrface) {
0933: Method[] homeMethods = intrface.getMethods();
0934: for (int i = 0; i < homeMethods.length; i++) {
0935: Method method = homeMethods[i];
0936: Class owner = method.getDeclaringClass();
0937: if (owner == javax.ejb.EJBHome.class
0938: || owner == EJBLocalHome.class) {
0939: continue;
0940: }
0941:
0942: try {
0943: Method beanMethod = null;
0944: if (method.getName().startsWith("create")) {
0945: StringBuilder ejbCreateName = new StringBuilder(
0946: method.getName());
0947: ejbCreateName.replace(0, 1, "ejbC");
0948: beanMethod = beanClass.getMethod(ejbCreateName
0949: .toString(), method.getParameterTypes());
0950: createMethod = beanMethod;
0951: /*
0952: Entity beans have a ejbCreate and ejbPostCreate methods with matching
0953: parameters. This code maps that relationship.
0954: */
0955: if (this .componentType == BeanType.BMP_ENTITY
0956: || this .componentType == BeanType.CMP_ENTITY) {
0957: ejbCreateName.insert(3, "Post");
0958: Method postCreateMethod = beanClass.getMethod(
0959: ejbCreateName.toString(), method
0960: .getParameterTypes());
0961: postCreateMethodMap.put(createMethod,
0962: postCreateMethod);
0963: }
0964: /*
0965: * Stateless session beans only have one create method. The getCreateMethod is
0966: * used by instance manager of the core.stateless.StatelessContainer as a convenience
0967: * method for obtaining the ejbCreate method.
0968: */
0969: } else if (method.getName().startsWith("find")) {
0970: if (this .componentType == BeanType.BMP_ENTITY) {
0971:
0972: String beanMethodName = "ejbF"
0973: + method.getName().substring(1);
0974: beanMethod = beanClass.getMethod(
0975: beanMethodName, method
0976: .getParameterTypes());
0977: }
0978: } else {
0979: String beanMethodName = "ejbHome"
0980: + method.getName().substring(0, 1)
0981: .toUpperCase()
0982: + method.getName().substring(1);
0983: beanMethod = beanClass.getMethod(beanMethodName,
0984: method.getParameterTypes());
0985: }
0986: if (beanMethod != null) {
0987: mapMethods(homeMethods[i], beanMethod);
0988: }
0989: } catch (NoSuchMethodException nsme) {
0990: // throw new RuntimeException("Invalid method [" + method + "] Not declared by " + beanClass.getName() + " class");
0991: }
0992: }
0993: }
0994:
0995: public void mapMethods(Method interfaceMethod, Method beanMethod) {
0996: methodMap.put(interfaceMethod, beanMethod);
0997: }
0998:
0999: private void mapObjectInterface(Class intrface) {
1000: if (intrface == BusinessLocalHome.class
1001: || intrface == BusinessRemoteHome.class
1002: || intrface == ServiceEndpoint.class) {
1003: return;
1004: }
1005:
1006: Method[] interfaceMethods = intrface.getMethods();
1007: for (int i = 0; i < interfaceMethods.length; i++) {
1008: Method method = interfaceMethods[i];
1009: Class declaringClass = method.getDeclaringClass();
1010: if (declaringClass == javax.ejb.EJBObject.class
1011: || declaringClass == EJBLocalObject.class) {
1012: continue;
1013: }
1014: try {
1015: Method beanMethod = beanClass.getMethod(method
1016: .getName(), method.getParameterTypes());
1017: mapMethods(method, beanMethod);
1018: } catch (NoSuchMethodException nsme) {
1019: throw new RuntimeException("Invalid method [" + method
1020: + "]. Not declared by " + beanClass.getName()
1021: + " class");
1022: }
1023: }
1024: }
1025:
1026: public List<Class> getObjectInterface(Class homeInterface) {
1027: if (BusinessLocalHome.class.isAssignableFrom(homeInterface)) {
1028: return getBusinessLocalInterfaces();
1029: } else if (BusinessRemoteHome.class
1030: .isAssignableFrom(homeInterface)) {
1031: return getBusinessRemoteInterfaces();
1032: } else if (EJBLocalHome.class.isAssignableFrom(homeInterface)) {
1033: List<Class> classes = new ArrayList<Class>();
1034: classes.add(getLocalInterface());
1035: return classes;
1036: } else if (EJBHome.class.isAssignableFrom(homeInterface)) {
1037: List<Class> classes = new ArrayList<Class>();
1038: classes.add(getRemoteInterface());
1039: return classes;
1040: } else {
1041: throw new IllegalArgumentException(
1042: "Cannot determine object interface for "
1043: + homeInterface);
1044: }
1045: }
1046:
1047: protected String extractHomeBeanMethodName(String methodName) {
1048: if (methodName.equals("create")) {
1049: return "ejbCreate";
1050: } else if (methodName.startsWith("find")) {
1051: return "ejbF" + methodName.substring(1);
1052: } else {
1053: return "ejbH" + methodName.substring(1);
1054: }
1055: }
1056:
1057: public Method getCreateMethod() {
1058: return createMethod;
1059: }
1060:
1061: public Method getMatchingPostCreateMethod(Method createMethod) {
1062: return this .postCreateMethodMap.get(createMethod);
1063: }
1064:
1065: //
1066: // CMP specific data
1067: //
1068:
1069: private boolean cmp2;
1070: private KeyGenerator keyGenerator;
1071: private String primaryKeyField;
1072: private String[] cmrFields;
1073: private Class cmpImplClass;
1074: private String abstractSchemaName;
1075:
1076: private Map<Method, String> queryMethodMap = new HashMap<Method, String>();
1077: private Set<String> remoteQueryResults = new TreeSet<String>();
1078:
1079: public boolean isCmp2() {
1080: return cmp2;
1081: }
1082:
1083: public void setCmp2(boolean cmp2) {
1084: this .cmp2 = cmp2;
1085: }
1086:
1087: public String getPrimaryKeyField() {
1088: return primaryKeyField;
1089: }
1090:
1091: public void setPrimaryKeyField(String primaryKeyField) {
1092: this .primaryKeyField = primaryKeyField;
1093: }
1094:
1095: public String[] getCmrFields() {
1096: return cmrFields;
1097: }
1098:
1099: public void setCmrFields(String[] cmrFields) {
1100: this .cmrFields = cmrFields;
1101: }
1102:
1103: public KeyGenerator getKeyGenerator() {
1104: return keyGenerator;
1105: }
1106:
1107: public void setKeyGenerator(KeyGenerator keyGenerator) {
1108: this .keyGenerator = keyGenerator;
1109: }
1110:
1111: public void addQuery(Method queryMethod, String queryString) {
1112: queryMethodMap.put(queryMethod, queryString);
1113: }
1114:
1115: public String getQuery(Method queryMethod) {
1116: return queryMethodMap.get(queryMethod);
1117: }
1118:
1119: public void setRemoteQueryResults(String methodSignature) {
1120: remoteQueryResults.add(methodSignature);
1121: }
1122:
1123: public boolean isRemoteQueryResults(String methodSignature) {
1124: return remoteQueryResults.contains(methodSignature);
1125: }
1126:
1127: public Class getCmpImplClass() {
1128: return cmpImplClass;
1129: }
1130:
1131: public void setCmpImplClass(Class cmpImplClass) {
1132: this .cmpImplClass = cmpImplClass;
1133: }
1134:
1135: public String getAbstractSchemaName() {
1136: return abstractSchemaName;
1137: }
1138:
1139: public void setAbstractSchemaName(String abstractSchemaName) {
1140: this .abstractSchemaName = abstractSchemaName;
1141: }
1142:
1143: public void setJarPath(String jarPath) {
1144: this .jarPath = jarPath;
1145: }
1146:
1147: public String getJarPath() {
1148: return jarPath;
1149: }
1150:
1151: public Method getEjbTimeout() {
1152: return ejbTimeout;
1153: }
1154:
1155: public void setEjbTimeout(Method ejbTimeout) {
1156: this .ejbTimeout = ejbTimeout;
1157: }
1158:
1159: public EjbTimerService getEjbTimerService() {
1160: return ejbTimerService;
1161: }
1162:
1163: public void setEjbTimerService(EjbTimerService ejbTimerService) {
1164: this .ejbTimerService = ejbTimerService;
1165: }
1166:
1167: public String getEjbName() {
1168: return ejbName;
1169: }
1170:
1171: public String getModuleID() {
1172: return moduleId;
1173: }
1174:
1175: public String getRunAs() {
1176: return runAs;
1177: }
1178:
1179: public void setEjbName(String ejbName) {
1180: this .ejbName = ejbName;
1181: }
1182:
1183: public void setModuleId(String moduleId) {
1184: this .moduleId = moduleId;
1185: }
1186:
1187: public void setRunAs(String runAs) {
1188: this .runAs = runAs;
1189: }
1190:
1191: public String toString() {
1192: return "DeploymentInfo(id=" + getDeploymentID() + ")";
1193: }
1194:
1195: public void setServiceEndpointInterface(
1196: Class serviceEndpointInterface) {
1197: this.serviceEndpointInterface = serviceEndpointInterface;
1198: mapObjectInterface(serviceEndpointInterface);
1199: }
1200: }
|