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    }