Package com.tll.model.key

Source Code of com.tll.model.key.BusinessKeyFactory$BusinessKeyDefinition

/**
* The Logic Lab
* @author jpk
* Jun 26, 2008
*/
package com.tll.model.key;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.BeanWrapperImpl;
import org.springframework.beans.NullValueInNestedPathException;

import com.tll.model.EntityUtil;
import com.tll.model.IEntity;
import com.tll.model.schema.BusinessKeyDef;
import com.tll.model.schema.BusinessObject;

/**
* BusinessKeyFactory - Defines all entity business keys in the application and
* provides utility methods relating to them.
* @author jpk
*/
@SuppressWarnings("unchecked")
public final class BusinessKeyFactory {

  /**
   * BusinessKeyDefinition - Local impl of {@link IBusinessKeyDefinition}.
   * @author jpk
   * @param <E>
   */
  private static final class BusinessKeyDefinition<E extends IEntity> implements IBusinessKeyDefinition<E> {

    private final Class<E> entityClass;
    private final String[] propertyNames;
    private final String businessKeyName;

    public BusinessKeyDefinition(Class<E> entityClass, String businessKeyName, String[] propertyNames) {
      if(entityClass == null) throw new IllegalArgumentException("An entity type must be specified.");
      if(propertyNames == null || propertyNames.length < 1) {
        throw new IllegalArgumentException("At least one property must be specified in a business key");
      }
      this.entityClass = entityClass;
      this.propertyNames = propertyNames;
      this.businessKeyName = businessKeyName;
    }

    public Class<E> getType() {
      return entityClass;
    }

    public String getBusinessKeyName() {
      return businessKeyName;
    }

    public String[] getPropertyNames() {
      return propertyNames;
    }
  }

  /**
   * The cache of discovered business key definitions.
   */
  private static final Map<Class<? extends IEntity>, Set<IBusinessKeyDefinition<? extends IEntity>>> map =
      new HashMap<Class<? extends IEntity>, Set<IBusinessKeyDefinition<? extends IEntity>>>();

  /**
   * Interrogates an entity class' annotations creating a set of
   * {@link BusinessKeyDefinition}s.
   * @param <E>
   * @param entityClass
   * @return Set of bk definitions or <code>null</code> if no business keys are
   *         defined for the given entity class.
   */
  private static <E extends IEntity> Set<IBusinessKeyDefinition<E>> discoverBusinessKeys(Class<E> entityClass) {
    BusinessObject bo = entityClass.getAnnotation(BusinessObject.class);
    if(bo == null) {
      // try the root entity
      bo = EntityUtil.getRootEntityClass(entityClass).getAnnotation(BusinessObject.class);
    }
    if(bo == null) {
      // no bks defined
      return null;
    }
    final Set<IBusinessKeyDefinition<E>> set = new HashSet<IBusinessKeyDefinition<E>>();
    for(final BusinessKeyDef def : bo.businessKeys()) {
      set.add(new BusinessKeyDefinition<E>(entityClass, def.name(), def.properties()));
    }
    return set;
  }
 
  /**
   * Does the given entity type have any defined business keys?
   * @param <E>
   * @param entityClass
   * @return true/false
   */
  public static <E extends IEntity> boolean hasBusinessKeys(Class<E> entityClass) {
    try {
      definitions(entityClass);
      return true;
    }
    catch(final BusinessKeyNotDefinedException e) {
      return false;
    }
  }

  /**
   * Provides all defined business key definitions for the given entity type.
   * @param <E> The entity type
   * @param entityClass The entity class
   * @return All defined business key definitions
   * @throws BusinessKeyNotDefinedException Whe no business keys are defined for
   *         the given entity type.
   */
  public static <E extends IEntity> IBusinessKeyDefinition<E>[] definitions(Class<E> entityClass)
      throws BusinessKeyNotDefinedException {

    if(!map.containsKey(entityClass)) {
      map.put(entityClass, (Set) discoverBusinessKeys(entityClass));
    }

    final Set set = map.get(entityClass);
    if(set == null) {
      throw new BusinessKeyNotDefinedException(entityClass);
    }
   
    return (IBusinessKeyDefinition<E>[]) set.toArray(new IBusinessKeyDefinition[set.size()]);
  }

  /**
   * Resolves a business key name to its definition for a given entity type.
   * @param <E>
   * @param entityClass
   * @param businessKeyName
   * @return The found definition or <code>null</code> if none exist for the
   *         given name of the given entity type.
   * @throws BusinessKeyNotDefinedException When no business keys are defined
   *         for the given entity type.
   */
  public static <E extends IEntity> IBusinessKeyDefinition<E> getDefinition(Class<E> entityClass, String businessKeyName)
      throws BusinessKeyNotDefinedException {
    final IBusinessKeyDefinition<E>[] defs = definitions(entityClass);
    for(final IBusinessKeyDefinition<E> def : defs) {
      if(def.getBusinessKeyName().equals(businessKeyName)) {
        return def;
      }
    }
    return null;
  }

  /**
   * Creates new and empty business keys for the given entity type.
   * @param <E> The entity type
   * @param entityClass The entity class
   * @return Array of empty business keys.
   * @throws BusinessKeyNotDefinedException When no business keys are defined
   *         for the given entity type.
   */
  public static <E extends IEntity> IBusinessKey<E>[] create(Class<E> entityClass)
      throws BusinessKeyNotDefinedException {
    final IBusinessKeyDefinition<E>[] defs = definitions(entityClass);
    final BusinessKey<E>[] bks = new BusinessKey[defs.length];
    for(int i = 0; i < defs.length; ++i) {
      bks[i] = new BusinessKey<E>(defs[i]);
    }
    return bks;
  }

  /**
   * Creates a new and empty business key for the given entity type and business
   * key name.
   * @param <E> The entity type.
   * @param def The business key definition
   * @return The created business key
   * @throws BusinessKeyNotDefinedException When no business keys exist for the
   *         given entity type or no business key is found having the specified
   *         name.
   */
  public static <E extends IEntity> IBusinessKey<E> create(IBusinessKeyDefinition<E> def)
      throws BusinessKeyNotDefinedException {
    return new BusinessKey<E>(def);
  }

  /**
   * Creates a new and empty business key for the given entity type and business
   * key name.
   * @param <E> The entity type.
   * @param entityClass The entity class
   * @param businessKeyName The business key name
   * @return The created business key
   * @throws BusinessKeyNotDefinedException When no business keys exist for the
   *         given entity type or no business key is found having the specified
   *         name.
   */
  public static <E extends IEntity> IBusinessKey<E> create(Class<E> entityClass, String businessKeyName)
      throws BusinessKeyNotDefinedException {
    return create(getDefinition(entityClass, businessKeyName));
  }

  /**
   * Creates all defined business keys with state extracted from the given
   * entity.
   * @param <E> The entity type
   * @param entity The entity from which business keys are created
   * @return Array of business keys with state extracted from the entity.
   * @throws BusinessKeyNotDefinedException When no business keys are defined
   *         for the given entity type.
   * @throws BusinessKeyPropertyException When a business key property is unable
   *         to be set.
   */
  public static <E extends IEntity> IBusinessKey<E>[] create(E entity) throws BusinessKeyNotDefinedException,
      BusinessKeyPropertyException {
    final IBusinessKeyDefinition<E>[] defs = definitions((Class<E>) entity.entityClass());
    final BusinessKey<E>[] bks = new BusinessKey[defs.length];
    for(int i = 0; i < defs.length; ++i) {
      bks[i] = new BusinessKey<E>(defs[i]);
    }
    fill(entity, bks);
    return bks;
  }

  /**
   * Creates a single business key for the given entity type and business key
   * name.
   * @param <E> The entity type.
   * @param entity The entity instance
   * @param def The business key definition
   * @return The created business key
   * @throws BusinessKeyNotDefinedException When no business keys exist for the
   *         given entity type or no business key is found having the specified
   *         name.
   * @throws BusinessKeyPropertyException When a business key property is unable
   *         to be set.
   */
  public static <E extends IEntity> IBusinessKey<E> create(E entity, IBusinessKeyDefinition<E> def)
      throws BusinessKeyNotDefinedException, BusinessKeyPropertyException {
    final IBusinessKey<E> bk = create(def);
    fill(new BeanWrapperImpl(entity), bk);
    return bk;
  }

  /**
   * Creates a single business key for the given entity type and business key
   * name.
   * @param <E> The entity type.
   * @param entity The entity instance
   * @param businessKeyName The business key name
   * @return The created business key
   * @throws BusinessKeyNotDefinedException When no business keys exist for the
   *         given entity type or no business key is found having the specified
   *         name.
   * @throws BusinessKeyPropertyException When a business key property is unable
   *         to be set.
   */
  public static <E extends IEntity> BusinessKey<E> create(E entity, String businessKeyName)
      throws BusinessKeyNotDefinedException, BusinessKeyPropertyException {
    final IBusinessKeyDefinition<E> theDef = getDefinition((Class<E>) entity.entityClass(), businessKeyName);
    final BusinessKey<E>[] bks = new BusinessKey[] { new BusinessKey(theDef) };
    fill(entity, bks);
    return bks[0];
  }
 
  /**
   * Fills the given business key with values held in the given entity.
   * @param <E> The entity type
   * @param entity The entity whose state is applied to the given business keys.
   * @param bks The business keys.
   */
  private static <E extends IEntity> void fill(E entity, IBusinessKey<E>[] bks) {
    final BeanWrapperImpl wrappedEntity = new BeanWrapperImpl(entity);
    for(final IBusinessKey<E> bk : bks) {
      fill(wrappedEntity, bk);
    }
  }

  /**
   * Fills the given business key with values held in the given entity.
   * @param <E> The entity type
   * @param wrappedEntity The entity whose state is applied to the given
   *        business key.
   * @param bk The business key.
   */
  private static <E extends IEntity> void fill(BeanWrapperImpl wrappedEntity, IBusinessKey<E> bk) {
    for(final String pname : bk.getPropertyNames()) {
      try {
        bk.setPropertyValue(pname, wrappedEntity.getPropertyValue(pname));
      }
      catch(final NullValueInNestedPathException e) {
        // ok
      }
    }
  }
}
TOP

Related Classes of com.tll.model.key.BusinessKeyFactory$BusinessKeyDefinition

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.