Package com.tll.di

Source Code of com.tll.di.Db4oDaoModule

package com.tll.di;

import java.io.File;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springextensions.db4o.Db4oTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.aspectj.AnnotationTransactionAspect;

import com.db4o.Db4o;
import com.db4o.ObjectContainer;
import com.db4o.config.ConfigScope;
import com.db4o.config.Configuration;
import com.google.inject.AbstractModule;
import com.google.inject.BindingAnnotation;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Scopes;
import com.tll.config.Config;
import com.tll.config.IConfigAware;
import com.tll.config.IConfigKey;
import com.tll.dao.IEntityDao;
import com.tll.dao.db4o.IDb4oNamedQueryTranslator;

/**
* Db4oDaoModule - Db4o dao impl module.
* @author jpk
*/
public abstract class Db4oDaoModule extends AbstractModule implements IConfigAware {

  public static final int DEFAULT_TRANS_TIMEOUT = 60; // seconds

  public static final String DEFAULT_DB4O_FILENAME = "db4o";

  public static final boolean DEFAULT_DB4O_EMPLOY_SPRING_TRANSACTIONS = false;

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

  /**
   * Db4oFile annotation
   */
  @Retention(RetentionPolicy.RUNTIME)
  @Target( {
    ElementType.FIELD, ElementType.PARAMETER
  })
  @BindingAnnotation
  public @interface Db4oFile {
  }

  /**
   * ConfigKeys.
   * @author jpk
   */
  public static enum ConfigKeys implements IConfigKey {

    DB4O_FILENAME("db.db4o.filename"),
    DB_TRANS_TIMEOUT("db.transaction.timeout"),
    DB4O_EMPLOY_SPRING_TRANSACTIONS("db.db4o.springTransactions");

    private final String key;

    private ConfigKeys(String key) {
      this.key = key;
    }

    @Override
    public String getKey() {
      return key;
    }
  }

  Config config;

  /**
   * Constructor
   */
  public Db4oDaoModule() {
    super();
  }

  /**
   * Constructor
   * @param config
   */
  public Db4oDaoModule(Config config) {
    super();
    this.config = config;
  }

  @Override
  public void setConfig(Config config) {
    this.config = config;
  }

  /**
   * @return The db4o named query translator implmentation type.
   */
  protected abstract Class<? extends IDb4oNamedQueryTranslator> getNamedQueryTranslatorImpl();

  /**
   * @return The desired db4o config instance to employ. May be overridden.
   */
  protected Configuration getConfiguration() {
    final Configuration c = Db4o.newConfiguration();
    c.generateVersionNumbers(ConfigScope.GLOBALLY);
    c.updateDepth(3);
    return c;
  }

  @Override
  protected final void configure() {
    log.info("Loading db4o dao module...");

    // db40 db file URI
    final String path = config == null ? DEFAULT_DB4O_FILENAME : config.getString(ConfigKeys.DB4O_FILENAME.getKey());
    //if(path.indexOf('/') >= 0) thr
    try {
      // first attempt to load existing file
      final URL url = Db4oDaoModule.class.getClassLoader().getResource(path);
      URI uri = url == null ? null : url.toURI();
      if(uri == null) {
        // create in working dir
        final File f = new File(path);
        uri = f.toURI();
      }
      bind(URI.class).annotatedWith(Db4oFile.class).toInstance(uri);
    }
    catch(final URISyntaxException e) {
      throw new IllegalStateException(e);
    }

    // Configuration (db4o)
    bind(Configuration.class).toProvider(new Provider<Configuration>() {

      @Override
      public Configuration get() {
        return getConfiguration();
      }

    });

    // ObjectContainer
    bind(ObjectContainer.class).toProvider(new Provider<ObjectContainer>() {

      @Inject
      @Db4oFile
      URI db4oUri;

      @Inject
      Configuration c;

      @Override
      public ObjectContainer get() {
        log.info("Creating db4o session for: " + db4oUri);
        return Db4o.openFile(c, db4oUri.getPath());
      }
    }).in(Scopes.SINGLETON);

    // determine whether we do spring transactions
    // this is necessary to avoid un-necessary instantiation of an ObjectContainer instance
    // which locks the db4o db file which is problematic when working with the db4o db shell
    final boolean dst =
      config == null ? DEFAULT_DB4O_EMPLOY_SPRING_TRANSACTIONS : config.getBoolean(
          ConfigKeys.DB4O_EMPLOY_SPRING_TRANSACTIONS.getKey(), DEFAULT_DB4O_EMPLOY_SPRING_TRANSACTIONS);
    if(dst) {
      log.info("Binding Spring's Db4oTransactionManager to Spring's @Transactional annotation..");
      // PlatformTransactionManager (for transactions)
      bind(PlatformTransactionManager.class).toProvider(new Provider<PlatformTransactionManager>() {

        @Inject
        ObjectContainer oc;

        @Override
        public PlatformTransactionManager get() {
          final Db4oTransactionManager db4oTm = new Db4oTransactionManager(oc);

          // set the transaction timeout
          final int timeout =
            config == null ? DEFAULT_TRANS_TIMEOUT : config.getInteger(ConfigKeys.DB_TRANS_TIMEOUT.getKey(),
                DEFAULT_TRANS_TIMEOUT);
          db4oTm.setDefaultTimeout(timeout);
          log.info("Set DB4O default transaction timeout to: " + timeout);

          // validate configuration
          try {
            db4oTm.afterPropertiesSet();
          }
          catch(final Exception e) {
            throw new IllegalStateException(e);
          }

          // required for AspectJ weaving of Spring's @Transactional annotation
          // (must be invoked PRIOR to an @Transactional method call
          AnnotationTransactionAspect.aspectOf().setTransactionManager(db4oTm);

          return db4oTm;
        }
      }).in(Scopes.SINGLETON);
    }

    // IDb4oNamedQueryTranslator
    bind(IDb4oNamedQueryTranslator.class).to(getNamedQueryTranslatorImpl()).in(Scopes.SINGLETON);

    // IEntityDao
    bind(IEntityDao.class).to(com.tll.dao.db4o.Db4oEntityDao.class).in(Scopes.SINGLETON);
  }

}
TOP

Related Classes of com.tll.di.Db4oDaoModule

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.