001: package com.mockrunner.mock.ejb;
002:
003: import javax.naming.Context;
004: import javax.naming.NameNotFoundException;
005: import javax.naming.NamingException;
006: import javax.transaction.UserTransaction;
007:
008: import org.mockejb.MockContainer;
009:
010: import com.mockrunner.ejb.Configuration;
011: import com.mockrunner.ejb.JNDIUtil;
012:
013: /**
014: * Used to create all types of EJB mock objects.
015: * Maintains the necessary dependencies between the mock objects.
016: * If you use the mock objects returned by this factory in your tests
017: * you can be sure that they are all up to date.
018: * This factory takes the <code>UserTransaction</code> from the JNDI context.
019: * If there's no transaction bound to the context, the factory will create a
020: * {@link com.mockrunner.mock.ejb.MockUserTransaction} and bind it to the context.
021: * If the bound transaction is no
022: * {@link com.mockrunner.mock.ejb.MockUserTransaction},
023: * the method {@link #getMockUserTransaction} returns <code>null</code>.
024: * Use {@link #getUserTransaction} instead in this case.
025: * You can configure the JNDI name of the <code>UserTransaction</code> and
026: * the JNDI <code>Context</code> with the class
027: * {@link com.mockrunner.ejb.Configuration}.
028: */
029: public class EJBMockObjectFactory {
030: private Configuration configuration;
031: private UserTransaction transaction;
032: private MockContainer container;
033: private Context context;
034:
035: /**
036: * Creates a new set of mock objects.
037: */
038: public EJBMockObjectFactory() {
039: this (new Configuration());
040: }
041:
042: /**
043: * Creates a new set of mock objects based on the specified configuration.
044: */
045: public EJBMockObjectFactory(Configuration configuration) {
046: this .configuration = configuration;
047: initializeContext();
048: initializeEJBContainer();
049: initializeUserTransaction();
050: }
051:
052: private void initializeContext() {
053: context = JNDIUtil.getContext(configuration);
054: }
055:
056: private void initializeUserTransaction() {
057: try {
058: try {
059: transaction = (UserTransaction) context
060: .lookup(configuration
061: .getUserTransactionJNDIName());
062: } catch (NameNotFoundException nameExc) {
063: transaction = createMockUserTransaction();
064: JNDIUtil.bindUserTransaction(configuration, context,
065: transaction);
066: }
067: } catch (Exception exc) {
068: transaction = createMockUserTransaction();
069: }
070: if (transaction instanceof MockUserTransaction) {
071: ((MockUserTransaction) transaction).reset();
072: }
073: }
074:
075: private void initializeEJBContainer() {
076: container = new MockContainer(context);
077: }
078:
079: /**
080: * Creates the {@link com.mockrunner.mock.ejb.MockUserTransaction} using <code>new</code>.
081: * This method can be overridden to return a subclass of {@link com.mockrunner.mock.ejb.MockUserTransaction}.
082: * @return the {@link com.mockrunner.mock.ejb.MockUserTransaction}
083: */
084: public MockUserTransaction createMockUserTransaction() {
085: return new MockUserTransaction();
086: }
087:
088: /**
089: * Calls <code>MockContextFactory.setAsInitial()</code>, if
090: * <code>MockContextFactory</code> is not already the current
091: * context factory.
092: */
093: public void initMockContextFactory() throws NamingException {
094: JNDIUtil.initMockContextFactory();
095: }
096:
097: /**
098: * Calls <code>MockContextFactory.revertSetAsInitial()</code>, if
099: * <code>MockContextFactory</code> is the current context factory.
100: */
101: public void resetMockContextFactory() {
102: JNDIUtil.resetMockContextFactory();
103: }
104:
105: /**
106: * Returns the {@link com.mockrunner.mock.ejb.MockUserTransaction}.
107: * If the bound transaction is no {@link com.mockrunner.mock.ejb.MockUserTransaction},
108: * this method returns <code>null</code>.
109: * @return the {@link com.mockrunner.mock.ejb.MockUserTransaction}
110: */
111: public MockUserTransaction getMockUserTransaction() {
112: if (!(transaction instanceof MockUserTransaction))
113: return null;
114: return (MockUserTransaction) transaction;
115: }
116:
117: /**
118: * Returns the <code>UserTransaction</code>.
119: * @return the <code>UserTransaction</code>
120: */
121: public UserTransaction getUserTransaction() {
122: return transaction;
123: }
124:
125: /**
126: * Returns the MockEJB <code>MockContainer</code>.
127: * @return the <code>MockContainer</code>
128: */
129: public MockContainer getMockContainer() {
130: return container;
131: }
132:
133: /**
134: * Returns the JNDI context that is used by this factory. If you do not set
135: * a <code>Context</code> using {@link com.mockrunner.ejb.Configuration#setContext}},
136: * the JNDI implementation of MockEJB is used.
137: * @return the JNDI context
138: */
139: public Context getContext() {
140: return context;
141: }
142: }
|