Package com.tll.dao.db4o.test

Source Code of com.tll.dao.db4o.test.Db4oDbShell

/**
* The Logic Lab
* @author jpk
* @since Aug 29, 2009
*/
package com.tll.dao.db4o.test;

import java.io.File;
import java.net.URI;
import java.util.Collection;
import java.util.Iterator;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.db4o.Db4o;
import com.db4o.ObjectContainer;
import com.db4o.config.Configuration;
import com.db4o.ext.ExtObjectContainer;
import com.db4o.reflect.ReflectClass;
import com.db4o.reflect.jdk.JdkClass;
import com.google.inject.Inject;
import com.tll.dao.IDbShell;
import com.tll.model.IEntity;
import com.tll.model.test.EntityGraph;
import com.tll.model.test.IEntityGraphPopulator;

/**
* MockDbShell
* @author jpk
*/
public class Db4oDbShell implements IDbShell {

  private static final Log log = LogFactory.getLog(Db4oDbShell.class);

  /**
   * Clears out all stored data (hopefully) in target given db4o db given a
   * session ref bound to it.
   * @param oc the session ref to the target db to clear
   */
  private static void clearDb4oDb(ObjectContainer oc) {
    if(oc == null) return;
    final ExtObjectContainer s = oc.ext();
    final ReflectClass[] rcs = s.knownClasses();
    if(rcs != null) {
      for(final ReflectClass rc : rcs) {
        if(rc.getDelegate() instanceof JdkClass) {
          final Class<?> objType = ((JdkClass) rc.getDelegate()).getJavaClass();
          final String cn = objType.getName();
          if(cn.indexOf("com.db4o") < 0 && objType != Object.class && cn.indexOf("java") < 0) {
            final Collection<?> clc = s.query(objType);
            if(clc != null) {
              for(final Object o : clc) {
                log.debug("Removing object: " + o);
                s.delete(o);
              }
            }
          }
        }
      }
      s.purge();
    }
  }

  @Inject
  private final URI dbFile;
  @Inject(optional = true)
  private final IEntityGraphPopulator populator;
  @Inject
  private final Configuration c;

  /**
   * Constructor
   * @param dbFile A ref to the db file
   * @param populator The entity graph populator that defines the db "schema"
   *        and content.
   * @param c the db4o configuration
   */
  // @Inject
  public Db4oDbShell(URI dbFile, IEntityGraphPopulator populator, Configuration c) {
    super();
    this.dbFile = dbFile;
    this.populator = populator;
    this.c = c;
  }

  /**
   * @return A {@link File} ref to the db file on the file system irregardless
   *         of whether or not it actually exists.
   */
  private File getHandle() {
    return new File(dbFile);
  }

  /**
   * @return A newly created db4o session.
   */
  private ObjectContainer createDbSession() {
    if(c == null) {
      log.info("Instantiating db4o session for: " + dbFile + " with NO configuration");
      return Db4o.openFile(dbFile.getPath());
    }
    log.info("Instantiating db4o session for: " + dbFile + " with config: " + c);
    return Db4o.openFile(c, dbFile.getPath());
  }

  /**
   * Closes a db session.
   * @param session A db4o session
   */
  private void killDbSession(ObjectContainer session) {
    if(session != null) {
      log.info("Killing db4o session for: " + dbFile);
      while(!session.close()) {
      }
    }
  }

  @Override
  public boolean clear() {
    final File f = getHandle();
    if(!f.exists()) return false;
    log.info("Clearing db4o db: " + f.getPath());
    ObjectContainer oc = null;
    try {
      oc = createDbSession();
      clearDb4oDb(oc);
    }
    finally {
      if(oc != null) killDbSession(oc);
    }
    return true;
  }

  @Override
  public boolean clear(Object dbSession) {
    if(dbSession instanceof ObjectContainer) {
      log.info("Clearing db4o db for session: " + dbSession);
      clearDb4oDb((ObjectContainer) dbSession);
      return true;
    }
    return false;
  }

  @Override
  public boolean create() {
    File f = getHandle();
    if(f.exists()) return false;
    log.info("Creating db4o db: " + f.getPath());
    f = null;
    ObjectContainer db = null;
    try {
      db = createDbSession();
    }
    finally {
      killDbSession(db);
    }
    return true;
  }

  @Override
  public boolean delete() {
    final File f = getHandle();
    if(!f.exists()) return false;
    log.info("Deleting db4o db: " + f.getPath());
    if(!f.delete()) throw new IllegalStateException("Unable to delete db4o file: " + f.getAbsolutePath());
    return true;
  }

  @Override
  public boolean stub() {
    ObjectContainer dbSession = null;
    try {
      log.info("Stubbing db4o db for db4o db: " + dbFile);
      dbSession = createDbSession();
      return doStub(dbSession);
    }
    finally {
      killDbSession(dbSession);
    }
  }

  @Override
  public boolean stub(Object dbSession) {
    if(dbSession instanceof ObjectContainer) {
      log.info("Stubbing db4o db for session: " + dbSession);
      doStub((ObjectContainer) dbSession);
      return true;
    }
    return false;
  }

  /**
   * Stubs a targeted db.
   * @param dbSession the db session ref
   * @return true/false
   */
  private boolean doStub(ObjectContainer dbSession) {
    assert dbSession != null;
    try {
      if(populator == null) throw new IllegalStateException("No populator set");
      populator.populateEntityGraph();
      final EntityGraph eg = populator.getEntityGraph();
      final Iterator<Class<? extends IEntity>> itr = eg.getEntityTypes();
      while(itr.hasNext()) {
        final Class<? extends IEntity> et = itr.next();
        log.info("Storing entities of type: " + et.getSimpleName() + "...");
        final Collection<? extends IEntity> ec = eg.getEntitiesByType(et);
        for(final IEntity e : ec) {
          log.info("Storing entity: " + et + "...");
          dbSession.store(e);
        }
      }
      return true;
    }
    catch(final Exception e) {
      log.error("Unable to stub db: " + e.getMessage(), e);
      return false;
    }
  }

  @Override
  public void restub() {
    create();
    clear();
    stub();
  }

  @Override
  public void restub(Object dbSession) {
    clear(dbSession);
    stub(dbSession);
  }
}
TOP

Related Classes of com.tll.dao.db4o.test.Db4oDbShell

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.