001 package com.mockrunner.mock.ejb;
002
003 import javax.naming.InitialContext;
004 import javax.naming.NameNotFoundException;
005 import javax.transaction.UserTransaction;
006
007 import org.apache.commons.logging.Log;
008 import org.apache.commons.logging.LogFactory;
009 import org.mockejb.MockContainer;
010 import org.mockejb.jndi.MockContextFactory;
011
012 import com.mockrunner.ejb.Configuration;
013
014 /**
015 * Used to create all types of EJB mock objects.
016 * Maintains the necessary dependencies between the mock objects.
017 * If you use the mock objects returned by this
018 * factory in your tests you can be sure, they are all
019 * up to date.
020 * This factory takes the <code>UserTransaction</code>
021 * from the MockEJB mock context. If there's no transaction
022 * bound to the mock context, the factory will create and bind a
023 * {@link com.mockrunner.mock.ejb.MockUserTransaction}.
024 * If the bound transaction is no
025 * {@link com.mockrunner.mock.ejb.MockUserTransaction},
026 * the method {@link #getMockUserTransaction} returns <code>null</code>.
027 * Use {@link #getUserTransaction} instead in this case.
028 * You can configure the JNDI name of the <code>UserTransaction</code>
029 * with the class {@link com.mockrunner.ejb.Configuration}.
030 */
031 public class EJBMockObjectFactory
032 {
033 private final static Log log = LogFactory.getLog(EJBMockObjectFactory.class);
034 private Configuration configuration;
035 private UserTransaction transaction;
036 private MockContainer container;
037
038 /**
039 * Creates a new set of mock objects.
040 */
041 public EJBMockObjectFactory()
042 {
043 this(new Configuration());
044 }
045
046 /**
047 * Creates a new set of mock objects based on the specified configuration.
048 */
049 public EJBMockObjectFactory(Configuration configuration)
050 {
051 this.configuration = configuration;
052 initializeMockEJB();
053 }
054
055 private void initializeMockEJB()
056 {
057 try
058 {
059 MockContextFactory.setAsInitial();
060 InitialContext context = new InitialContext();
061 container = new MockContainer(context);
062 try
063 {
064 transaction = (UserTransaction)context.lookup(configuration.getUserTransactionJNDIName());
065 }
066 catch(NameNotFoundException nameExc)
067 {
068 transaction = new MockUserTransaction();
069 if(configuration.getBindMockUserTransactionToJNDI())
070 {
071 context.rebind(configuration.getUserTransactionJNDIName(), transaction);
072 context.rebind("javax.transaction.UserTransaction", transaction);
073 context.rebind("java:comp/UserTransaction", transaction);
074 }
075 }
076 }
077 catch(Exception exc)
078 {
079 log.error(exc.getMessage(), exc);
080 transaction = new MockUserTransaction();
081 }
082 if(transaction instanceof MockUserTransaction)
083 {
084 ((MockUserTransaction)transaction).reset();
085 }
086 }
087
088 /**
089 * Returns the {@link com.mockrunner.mock.ejb.MockUserTransaction}.
090 * If the bound transaction is no {@link com.mockrunner.mock.ejb.MockUserTransaction},
091 * this method returns <code>null</code>.
092 * @return the {@link com.mockrunner.mock.ejb.MockUserTransaction}
093 */
094 public MockUserTransaction getMockUserTransaction()
095 {
096 if(!(transaction instanceof MockUserTransaction)) return null;
097 return (MockUserTransaction)transaction;
098 }
099
100 /**
101 * Returns the <code>UserTransaction</code>.
102 * @return the <code>UserTransaction</code>
103 */
104 public UserTransaction getUserTransaction()
105 {
106 return transaction;
107 }
108
109 /**
110 * Returns the MockEJB <code>MockContainer</code>.
111 * @return the <code>MockContainer</code>
112 */
113 public MockContainer getMockContainer()
114 {
115 return container;
116 }
117 }