/*
 * JBoss, the OpenSource J2EE webOS
 * 
 * Distributable under LGPL license.
 * See terms of license at gnu.org.
 */
package org.jboss.cache.loader;

import org.jboss.cache.TreeCache;
import org.jboss.cache.TreeCacheMBean;
import org.jboss.cache.transaction.DummyTransactionManager;
import org.w3c.dom.Element;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NameNotFoundException;
import javax.sql.DataSource;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;

public class DataSourceIntegrationTest extends AbstractCacheLoaderTestBase
{
   private String old_factory = null;
   private final String FACTORY = "org.jboss.cache.transaction.DummyContextFactory";
   private final String JNDI_NAME = "java:/MockDS";
   private TreeCacheMBean cache;

   protected void setUp() throws Exception {
      super.setUp();
      old_factory = System.getProperty(Context.INITIAL_CONTEXT_FACTORY);
      System.setProperty(Context.INITIAL_CONTEXT_FACTORY, FACTORY);
      DummyTransactionManager.getInstance();

   }


    protected Element getCacheLoaderConfig(String jndi) throws Exception
    {
        String props = "cache.jdbc.datasource=" + jndi + "\ncache.jdbc.table.create=false\ncache.jdbc.table.drop=false";
        return getSingleCacheLoaderConfig("", "org.jboss.cache.loader.JDBCCacheLoader", props, false, false,false);
    }

   /**
    * Tests fix for JBCACHE-303, ensuring that JDBCCacheLoader works if
    * its DataSource is not in JNDI until startService is called.
    * 
    * @throws Exception
    */
   public void testDataSourceIntegration() throws Exception
   {
      Context context = new InitialContext();
      try
      {
         Object obj = context.lookup(JNDI_NAME);
         assertNull(JNDI_NAME + " not bound", obj);
      }
      catch (NameNotFoundException n) {
         // expected
      }
      cache=new TreeCache();
      cache.setCacheMode("local");
      cache.setTransactionManagerLookupClass("org.jboss.cache.DummyTransactionManagerLookup");
       cache.setCacheLoaderConfiguration(getCacheLoaderConfig(JNDI_NAME));
      cache.createService();


      context.bind(JNDI_NAME, new MockDataSource());
      assertNotNull(JNDI_NAME + " bound", context.lookup(JNDI_NAME));
      cache.startService();

      assertNotNull("Cache has a cache loader", cache.getCacheLoader());
   }

   protected void tearDown() throws Exception
   {
      super.tearDown();

      Context ctx = new InitialContext();
      ctx.unbind(JNDI_NAME);
      if (old_factory != null) {
         System.setProperty(Context.INITIAL_CONTEXT_FACTORY, old_factory);
      }
      else {
         System.getProperties().remove(Context.INITIAL_CONTEXT_FACTORY);
      }


      if (cache != null) {
         cache.stopService();
         cache.destroyService();
      }
   }

   private static class MockDataSource implements DataSource
   {

      public Connection getConnection() throws SQLException
      {
         return null;
      }

      public Connection getConnection(String user, String password) throws SQLException
      {
         return null;
      }

      public int getLoginTimeout() throws SQLException
      {
         return 0;
      }

      public PrintWriter getLogWriter() throws SQLException
      {
         return null;
      }

      public void setLoginTimeout(int seconds) throws SQLException {}

      public void setLogWriter(PrintWriter printWriter) throws SQLException {}

   }
}
