001: package org.mockejb;
002:
003: import java.lang.reflect.*;
004:
005: import javax.ejb.*;
006:
007: /**
008: * Supports invocations of the home methods specific for entity beans, such as
009: * finders and ejbHome.
010: *
011: * @author Alexander Ananiev
012: */
013: class EntityBeanHome extends BasicEjbHome {
014:
015: // bean and method that will be used as the target for methods that MockEJB does not implement itself
016: private DummyCMPBean dummyCmpBean = new DummyCMPBean();
017:
018: private EntityDatabase entityDatabase;
019:
020: EntityBeanHome(BasicEjbDescriptor descriptor,
021: final EntityDatabase entityDatabase) {
022: super (descriptor);
023: this .entityDatabase = entityDatabase;
024: }
025:
026: /**
027: * Creates entity bean. It involves instantiating it, setting the context and
028: * calling "create".
029: */
030: public Object create(BasicEjbDescriptor basicDescriptor,
031: MockEjbObject ejbObject, Method createMethod,
032: Object[] paramVals) throws Exception {
033:
034: EntityBeanDescriptor descriptor = (EntityBeanDescriptor) basicDescriptor;
035:
036: MockEjbContext ejbContext = new MockEjbContext(getHomeProxy());
037:
038: Object bean = createBeanInstance(descriptor, createMethod,
039: ejbContext);
040:
041: Object pk = null;
042: if (!createMethod.getDeclaringClass().equals(GenericHome.class)) {
043:
044: pk = invokeBeanCreateMethod(bean, createMethod, paramVals);
045: ejbContext.setPrimaryKey(pk);
046:
047: // ejbPostCreate
048: invokeBeanMethodWithPrefix("ejbPost", bean, createMethod,
049: paramVals);
050: }
051:
052: Object ejbObjectProxy = ejbObject.createProxy(bean, ejbContext);
053:
054: // TODO: refactor - FindByPKHandler should handle create as well
055: if (pk != null) {
056: entityDatabase.add(descriptor.getHomeClass(), pk,
057: ejbObjectProxy);
058: }
059:
060: return ejbObjectProxy;
061: }
062:
063: /**
064: * Creates the bean without calling its create method and creating proxy.
065: * @param basicDescriptor
066: * @return new bean instance
067: */
068: private Object createBeanInstance(EntityBeanDescriptor descriptor,
069: Method method, MockEjbContext ejbContext) throws Exception {
070:
071: // if the bean class is an abstract class - use the helper class to create the subclass
072: Class beanClass = descriptor.getBeanClass();
073:
074: Object bean;
075:
076: if (beanClass != null && descriptor.isCMP()) {
077: EntityBeanSubclass subclassFactory = EntityBeanSubclass
078: .newInstance(beanClass);
079: bean = subclassFactory.create();
080: } else {
081: bean = createBean(descriptor);
082: }
083:
084: if (bean instanceof EntityBean) {
085:
086: Class paramTypes[] = { EntityContext.class };
087: Object args[] = { ejbContext };
088:
089: invokeBeanMethod(bean, null, "setEntityContext",
090: paramTypes, args);
091: }
092:
093: return bean;
094: }
095:
096: public Object invokeHomeMethod(BasicEjbDescriptor basicDescriptor,
097: Method homeMethod, Object[] paramVals) throws Exception {
098:
099: Object returnObj = null;
100:
101: EntityBeanDescriptor descriptor = (EntityBeanDescriptor) basicDescriptor;
102: if (homeMethod.getName().startsWith("find"))
103: returnObj = invokeFinder(descriptor, homeMethod, paramVals);
104: else {
105: // consider everything else a home method
106:
107: // create a bean that we can use to call a home method on
108: Object bean = createBeanInstance(descriptor, homeMethod,
109: getMockEjbContext());
110:
111: // try to find this method on the target bean
112: returnObj = invokeBeanMethodWithPrefix("ejbHome", bean,
113: homeMethod, paramVals);
114:
115: }
116:
117: return returnObj;
118:
119: }
120:
121: protected Object invokeFinder(EntityBeanDescriptor descriptor,
122: Method finderMethod, Object[] paramVals) throws Exception {
123:
124: Object returnObj = null;
125:
126: if (descriptor.isCMP()) {
127:
128: // this is to make sure that there is a context
129: getMockEjbContext();
130:
131: try {
132: returnObj = interceptorInvoker.invoke(getHomeProxy(),
133: finderMethod, dummyCmpBean, dummyCmpBean
134: .getTargetMethod(), paramVals);
135:
136: } catch (MustBeInterceptedException mbie) {
137: // translate it into more meaningful error message
138: throw new MustBeInterceptedException(finderMethod);
139: }
140:
141: } else {
142: // create a bean that we can use to call a finder method on
143: Object bean = createBeanInstance(descriptor, finderMethod,
144: getMockEjbContext());
145:
146: returnObj = invokeBeanMethodWithPrefix("ejb", bean,
147: finderMethod, paramVals);
148: }
149:
150: return returnObj;
151:
152: }
153:
154: private MockEjbContext getMockEjbContext() {
155: MockEjbContext context = new MockEjbContext(getHomeProxy());
156: interceptorInvoker.setContext(MockEjbContext.class.getName(),
157: context);
158: return context;
159: }
160: }
|