package org.jboss.cache.aop.loader;

import javax.transaction.Transaction;

import junit.framework.Test;
import junit.framework.TestSuite;

import org.jboss.cache.Fqn;
import org.jboss.cache.aop.PojoCache;
import org.jboss.cache.aop.test.Person;
import org.jboss.cache.aop.test.Address;
import org.jboss.cache.loader.CacheLoader;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * Commons tests for all CacheLoaders. Aop version.
 *
 * @author bwang
 * @version $Id: ObjectGraphTestsBase.java,v 1.3 2006/04/09 12:33:49 bwang Exp $
 */
abstract public class ObjectGraphTestsBase extends AbstractCacheLoaderTestBase {
   Log log=LogFactory.getLog(ObjectGraphTestsBase.class);
   PojoCache cache;
   CacheLoader loader = null;
   Transaction tx = null;
   static final Fqn FQN = new Fqn("key");

   protected void setUp() throws Exception {
      super.setUp();
      cache = new PojoCache();
      cache.setCacheMode("local");
      configureCache();
      cache.setTransactionManagerLookupClass("org.jboss.cache.DummyTransactionManagerLookup");
      cache.createService();
      cache.startService();
      loader = cache.getCacheLoader();
   }

   abstract protected void configureCache() throws Exception;

   protected void tearDown() throws Exception {
      super.tearDown();
      if (tx != null) {
         try {
            tx.commit();
         } catch (Throwable e) {
            e.printStackTrace();
         }
      }
      cache.remove("/");
      loader.remove(Fqn.fromString("/"));
      cache.stopService();
      cache.destroyService();
   }

   protected void addDelay() {
      ; // returns immediately in this case.  Subclasses may override where a delay is needed.
   }

   protected Person createPerson(String name, int age)
   {
      Person p = new Person();
      p.setName(name);
      p.setAge(age);
      return p;
   }

   public void testMultipleRefence() throws Exception
   {
      log.info("testMultipleReference() ...");
      cache.putObject("/person/joe", createPerson("Joe Black", 31));
      Person joe = (Person) cache.getObject("/person/joe");
      cache.putObject("/person/ben", createPerson("Ben Hogan", 51));
      Person ben = (Person) cache.getObject("/person/ben");

      Address addr = new Address();
      addr.setStreet("123 Albert Ave.");
      addr.setCity("Sunnyvale");
      addr.setZip(94087);

      // They share the sub-object: address
      log.info("testMultipleReference(): set Joe address");
      joe.setAddress(addr);
      log.info("testMultipleReference(): set Ben address");
      ben.setAddress(addr);

      log.info("testMultipleReference(): verify");
      Address add1 = (Address) ((Person)cache.getObject("/person/joe")).getAddress();
      Address add2 = (Address) ((Person)cache.getObject("/person/ben")).getAddress();
      assertEquals(add1.getCity(), add2.getCity());
      addr.setCity("Santa Clara");
      assertEquals(add1.getCity(), add2.getCity());

      cache.evict(Fqn.fromString("/person/joe"));
      cache.evict(Fqn.fromString("/person/ben"));

      log.info("testMultipleReference(): after eviction");
      add1 = (Address) ((Person)cache.getObject("/person/joe")).getAddress();
      add2 = (Address) ((Person)cache.getObject("/person/ben")).getAddress();
      assertEquals(add1.getCity(), add2.getCity());
      add1.setCity("Santa Clara");
      // Still not working now. Will need to support it. JCACHE-223
//      assertEquals(add1.getCity(), add2.getCity());
   }

   public static Test suite() {
      return new TestSuite(ObjectGraphTestsBase.class);
   }

   public static void main(String[] args) {
      junit.textui.TestRunner.run(suite());
   }

}
