Package co.pishfa.accelerate.initializer.api

Source Code of co.pishfa.accelerate.initializer.api.InitializerFactory

/**
*
*/
package co.pishfa.accelerate.initializer.api;

import java.io.InputStream;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.el.ExpressionFactory;

import org.apache.commons.lang3.Validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import co.pishfa.accelerate.initializer.core.AnnotationMetaDataReader;
import co.pishfa.accelerate.initializer.core.DefaultInitializer;
import co.pishfa.accelerate.initializer.core.XmlMetaDataReader;
import co.pishfa.accelerate.initializer.model.InitEntity;
import co.pishfa.accelerate.initializer.model.InitEntityMetaData;
import co.pishfa.accelerate.initializer.util.Input;

/**
* A thread-safe factory for {@link Initializer}. It also holds the configurations. This factory has a fluent interface
* e.g you may use it in the following way to obtain an initializer instance:
*
* <p>
* Initializer initializer = new
* InitializerFactory().entityClasses(Book.class,Category.class).configFile(config).uniquePropertyName
* ("name").create(initListener);
* </p>
*
* @author Taha Ghasemi
*
*/
public class InitializerFactory {

  private static final Logger log = LoggerFactory.getLogger(InitializerFactory.class);

  private final Map<String, InitEntityMetaData> aliasToInitEntity = new HashMap<>();
  private final Map<Class<?>, InitEntityMetaData> classToInitEntity = new HashMap<>();

  private ExpressionFactory expressionFactory;
  private boolean incremental = false;
  private boolean autoAnchor = true;
  private String key = null;

  public InitializerFactory() {
    expressionFactory = ExpressionFactory.newInstance();
  }

  /**
   * List of entity classes for annotation processing. It is not required that the provided classes are annotated with
   * InitEnity. If an init entity with the same alias is already exits, it will be overridden. If the parent class of
   * an entity class is annotated with {@link InitEntity}, its parent is also processed.
   */
  public InitializerFactory entityClasses(Class<?>... entityClasses) {
    Validate.notNull(entityClasses);
    processEntityClasses(Arrays.asList(entityClasses));
    return this;
  }

  /**
   * List of entity classes for annotation processing. It is not required that the provided classes are annotated with
   * InitEnity. If an init entity with the same alias is already exits, it will be overridden. If the parent class of
   * an entity class is annotated with {@link InitEntity}, its parent is also processed.
   */
  public InitializerFactory entityClasses(List<Class<?>> entityClasses) {
    Validate.notNull(entityClasses);
    processEntityClasses(entityClasses);
    return this;
  }

  protected void processEntityClasses(List<Class<?>> entityClasses) {
    new AnnotationMetaDataReader(this).processEntityClasses(entityClasses);
  }

  /**
   * Xml-file based configuration which conforms to initializer-config.xsd. If an init entity with the same alias is
   * already exits, it will be overridden.
   */
  public InitializerFactory metadata(String reasourceName) throws Exception {
    processMetadataFile(Input.resource(reasourceName), true);
    return this;
  }

  /**
   * Xml-file based configuration which conforms to initializer-config.xsd. The encoding is determined from xml
   * declaration. Note that you are responsible to close this resource if autoClose if false. If an init entity with
   * the same alias is already exits, it will be overridden.
   */
  public InitializerFactory metadata(InputStream metadataFile, boolean autoClose) throws Exception {
    Validate.notNull(metadataFile);

    processMetadataFile(metadataFile, autoClose);
    return this;

  }

  protected void processMetadataFile(InputStream input, boolean autoClose) throws Exception {
    try {
      new XmlMetaDataReader(this).processMetadata(input);
    } finally {
      if (autoClose) {
        input.close();
      }
    }
  }

  /**
   * Comma separated list of property names that make an instance of this entity unique. Can be * which means all
   * properties with not null value. This is used in both auto-anchoring and loading of objects. If the specified
   * value is null or empty, it means that entities by default should not participate in auto-anchoring or loading
   * modes unless they provide their own anchoring. Default value is null. Each entity type may override this property
   * by using key attribute.
   */
  public InitializerFactory key(String key) {
    this.key = key;
    return this;
  }

  /**
   * Initializer automatically creates an anchor like this for each entity EntityAlias:unique1_unique2_uniqe3,
   * provided that all unique values (which their property names are either specified here or per entity) are not
   * null. Default value is true.
   */
  public InitializerFactory autoAnchor(boolean autoAnchor) {
    this.autoAnchor = autoAnchor;
    return this;
  }

  /**
   * If true, {@link Initializer} first tries to find objects by supplying unique values (which their property names
   * are either specified here or per entity) to the listener and if it fails, then creates them. Default value is
   * false.
   */
  public InitializerFactory incremental(boolean incremental) {
    this.incremental = incremental;
    return this;
  }

  /**
   * Introduces a new initEntity. If an initEntity with the same alias already exists, this will override it.
   *
   * @param initEntity
   */
  public void addInitEntity(InitEntityMetaData initEntity) {
    Validate.notNull(initEntity);

    String alias = initEntity.getAlias();
    if (aliasToInitEntity.containsKey(alias)) {
      log.warn("Duplicate entity alias {} this will override the previose one.", alias);
    }
    aliasToInitEntity.put(alias, initEntity);
    classToInitEntity.put(initEntity.getEntityClass(), initEntity);
  }

  /**
   * Sets the javax.el.ExpressionFactory for evaluating dynamic expressions.
   */
  public InitializerFactory expressionFactory(ExpressionFactory expressionFactory) {
    this.expressionFactory = expressionFactory;
    return this;
  }

  /**
   * @return the expression engine
   */
  public ExpressionFactory getExpressionFactory() {
    return expressionFactory;
  }

  /**
   * @return the incremental
   */
  public boolean isIncremental() {
    return incremental;
  }

  /**
   * @return the autoAnchor
   */
  public boolean isAutoAnchor() {
    return autoAnchor;
  }

  public String getKey() {
    return key;
  }

  public Initializer create(InitListener listener, Map<String, Object> contextVars) {
    return new DefaultInitializer(this, listener, contextVars);
  }

  public Initializer create(InitListener listener) {
    return new DefaultInitializer(this, listener, null);
  }

  public Initializer create() {
    return new DefaultInitializer(this, null, null);
  }

  /**
   * @return the InitEntityMetaData with the given alias.
   */
  public InitEntityMetaData getInitEntityByAlias(String alias) {
    // null key is allowed
    return aliasToInitEntity.get(alias);
  }

  /**
   * @return the InitEntityMetaData corresponding to the entityClass provided
   */
  public InitEntityMetaData getInitEntityByClass(Class<?> entityClass) {
    // null key is allowed
    return classToInitEntity.get(entityClass);

  }

}
TOP

Related Classes of co.pishfa.accelerate.initializer.api.InitializerFactory

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.