Package org.hibernate.mapping

Source Code of org.hibernate.mapping.Component$ValueGenerationPlan

/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors.  All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA  02110-1301  USA
*/
package org.hibernate.mapping;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.hibernate.EntityMode;
import org.hibernate.MappingException;
import org.hibernate.cfg.Mappings;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.id.CompositeNestedGeneratedValueGenerator;
import org.hibernate.id.IdentifierGenerator;
import org.hibernate.id.PersistentIdentifierGenerator;
import org.hibernate.id.factory.IdentifierGeneratorFactory;
import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.internal.util.collections.JoinedIterator;
import org.hibernate.property.Setter;
import org.hibernate.tuple.component.ComponentMetamodel;
import org.hibernate.type.Type;
import org.hibernate.type.TypeFactory;

/**
* The mapping for a component, composite element,
* composite identifier, etc.
*
* @author Gavin King
* @author Steve Ebersole
*/
public class Component extends SimpleValue implements MetaAttributable {
  private ArrayList properties = new ArrayList();
  private String componentClassName;
  private boolean embedded;
  private String parentProperty;
  private PersistentClass owner;
  private boolean dynamic;
  private Map metaAttributes;
  private String nodeName;
  private boolean isKey;
  private String roleName;

  private java.util.Map tuplizerImpls;

  public Component(Mappings mappings, PersistentClass owner) throws MappingException {
    super( mappings, owner.getTable() );
    this.owner = owner;
  }

  public Component(Mappings mappings, Component component) throws MappingException {
    super( mappings, component.getTable() );
    this.owner = component.getOwner();
  }

  public Component(Mappings mappings, Join join) throws MappingException {
    super( mappings, join.getTable() );
    this.owner = join.getPersistentClass();
  }

  public Component(Mappings mappings, Collection collection) throws MappingException {
    super( mappings, collection.getCollectionTable() );
    this.owner = collection.getOwner();
  }

  public int getPropertySpan() {
    return properties.size();
  }
  public Iterator getPropertyIterator() {
    return properties.iterator();
  }
  public void addProperty(Property p) {
    properties.add(p);
  }
  public void addColumn(Column column) {
    throw new UnsupportedOperationException("Cant add a column to a component");
  }
  public int getColumnSpan() {
    int n=0;
    Iterator iter = getPropertyIterator();
    while ( iter.hasNext() ) {
      Property p = (Property) iter.next();
      n+= p.getColumnSpan();
    }
    return n;
  }
  public Iterator<Selectable> getColumnIterator() {
    Iterator[] iters = new Iterator[ getPropertySpan() ];
    Iterator iter = getPropertyIterator();
    int i=0;
    while ( iter.hasNext() ) {
      iters[i++] = ( (Property) iter.next() ).getColumnIterator();
    }
    return new JoinedIterator(iters);
  }

  public void setTypeByReflection(String propertyClass, String propertyName) {}

  public boolean isEmbedded() {
    return embedded;
  }

  public String getComponentClassName() {
    return componentClassName;
  }

  public Class getComponentClass() throws MappingException {
    try {
      return ReflectHelper.classForName(componentClassName);
    }
    catch (ClassNotFoundException cnfe) {
      throw new MappingException("component class not found: " + componentClassName, cnfe);
    }
  }

  public PersistentClass getOwner() {
    return owner;
  }

  public String getParentProperty() {
    return parentProperty;
  }

  public void setComponentClassName(String componentClass) {
    this.componentClassName = componentClass;
  }

  public void setEmbedded(boolean embedded) {
    this.embedded = embedded;
  }

  public void setOwner(PersistentClass owner) {
    this.owner = owner;
  }

  public void setParentProperty(String parentProperty) {
    this.parentProperty = parentProperty;
  }

  public boolean isDynamic() {
    return dynamic;
  }

  public void setDynamic(boolean dynamic) {
    this.dynamic = dynamic;
  }

  public Type getType() throws MappingException {
    // TODO : temporary initial step towards HHH-1907
    final ComponentMetamodel metamodel = new ComponentMetamodel( this );
    final TypeFactory factory = getMappings().getTypeResolver().getTypeFactory();
    return isEmbedded() ? factory.embeddedComponent( metamodel ) : factory.component( metamodel );
  }

  public void setTypeUsingReflection(String className, String propertyName)
    throws MappingException {
  }
 
  public java.util.Map getMetaAttributes() {
    return metaAttributes;
  }
  public MetaAttribute getMetaAttribute(String attributeName) {
    return metaAttributes==null?null:(MetaAttribute) metaAttributes.get(attributeName);
  }

  public void setMetaAttributes(java.util.Map metas) {
    this.metaAttributes = metas;
  }
 
  public Object accept(ValueVisitor visitor) {
    return visitor.accept(this);
  }
 
  public boolean[] getColumnInsertability() {
    boolean[] result = new boolean[ getColumnSpan() ];
    Iterator iter = getPropertyIterator();
    int i=0;
    while ( iter.hasNext() ) {
      Property prop = (Property) iter.next();
      boolean[] chunk = prop.getValue().getColumnInsertability();
      if ( prop.isInsertable() ) {
        System.arraycopy(chunk, 0, result, i, chunk.length);
      }
      i+=chunk.length;
    }
    return result;
  }

  public boolean[] getColumnUpdateability() {
    boolean[] result = new boolean[ getColumnSpan() ];
    Iterator iter = getPropertyIterator();
    int i=0;
    while ( iter.hasNext() ) {
      Property prop = (Property) iter.next();
      boolean[] chunk = prop.getValue().getColumnUpdateability();
      if ( prop.isUpdateable() ) {
        System.arraycopy(chunk, 0, result, i, chunk.length);
      }
      i+=chunk.length;
    }
    return result;
  }
 
  public String getNodeName() {
    return nodeName;
  }
 
  public void setNodeName(String nodeName) {
    this.nodeName = nodeName;
  }
 
  public boolean isKey() {
    return isKey;
  }
 
  public void setKey(boolean isKey) {
    this.isKey = isKey;
  }
 
  public boolean hasPojoRepresentation() {
    return componentClassName!=null;
  }

  public void addTuplizer(EntityMode entityMode, String implClassName) {
    if ( tuplizerImpls == null ) {
      tuplizerImpls = new HashMap();
    }
    tuplizerImpls.put( entityMode, implClassName );
  }

  public String getTuplizerImplClassName(EntityMode mode) {
    // todo : remove this once ComponentMetamodel is complete and merged
    if ( tuplizerImpls == null ) {
      return null;
    }
    return ( String ) tuplizerImpls.get( mode );
  }

  public Map getTuplizerMap() {
    if ( tuplizerImpls == null ) {
      return null;
    }
    return java.util.Collections.unmodifiableMap( tuplizerImpls );
  }

  public Property getProperty(String propertyName) throws MappingException {
    Iterator iter = getPropertyIterator();
    while ( iter.hasNext() ) {
      Property prop = (Property) iter.next();
      if ( prop.getName().equals(propertyName) ) {
        return prop;
      }
    }
    throw new MappingException("component property not found: " + propertyName);
  }

  public String getRoleName() {
    return roleName;
  }

  public void setRoleName(String roleName) {
    this.roleName = roleName;
  }

  public String toString() {
    return getClass().getName() + '(' + properties.toString() + ')';
  }

  private IdentifierGenerator builtIdentifierGenerator;

  public IdentifierGenerator createIdentifierGenerator(
      IdentifierGeneratorFactory identifierGeneratorFactory,
      Dialect dialect,
      String defaultCatalog,
      String defaultSchema,
      RootClass rootClass) throws MappingException {
    if ( builtIdentifierGenerator == null ) {
      builtIdentifierGenerator = buildIdentifierGenerator(
          identifierGeneratorFactory,
          dialect,
          defaultCatalog,
          defaultSchema,
          rootClass
      );
    }
    return builtIdentifierGenerator;
  }

  private IdentifierGenerator buildIdentifierGenerator(
      IdentifierGeneratorFactory identifierGeneratorFactory,
      Dialect dialect,
      String defaultCatalog,
      String defaultSchema,
      RootClass rootClass) throws MappingException {
    final boolean hasCustomGenerator = ! DEFAULT_ID_GEN_STRATEGY.equals( getIdentifierGeneratorStrategy() );
    if ( hasCustomGenerator ) {
      return super.createIdentifierGenerator(
          identifierGeneratorFactory, dialect, defaultCatalog, defaultSchema, rootClass
      );
    }

    final Class entityClass = rootClass.getMappedClass();
    final Class attributeDeclarer; // what class is the declarer of the composite pk attributes
    CompositeNestedGeneratedValueGenerator.GenerationContextLocator locator;

    // IMPL NOTE : See the javadoc discussion on CompositeNestedGeneratedValueGenerator wrt the
    //    various scenarios for which we need to account here
    if ( rootClass.getIdentifierMapper() != null ) {
      // we have the @IdClass / <composite-id mapped="true"/> case
      attributeDeclarer = resolveComponentClass();
    }
    else if ( rootClass.getIdentifierProperty() != null ) {
      // we have the "@EmbeddedId" / <composite-id name="idName"/> case
      attributeDeclarer = resolveComponentClass();
    }
    else {
      // we have the "straight up" embedded (again the hibernate term) component identifier
      attributeDeclarer = entityClass;
    }

    locator = new StandardGenerationContextLocator( rootClass.getEntityName() );
    final CompositeNestedGeneratedValueGenerator generator = new CompositeNestedGeneratedValueGenerator( locator );

    Iterator itr = getPropertyIterator();
    while ( itr.hasNext() ) {
      final Property property = (Property) itr.next();
      if ( property.getValue().isSimpleValue() ) {
        final SimpleValue value = (SimpleValue) property.getValue();

        if ( DEFAULT_ID_GEN_STRATEGY.equals( value.getIdentifierGeneratorStrategy() ) ) {
          // skip any 'assigned' generators, they would have been handled by
          // the StandardGenerationContextLocator
          continue;
        }

        final IdentifierGenerator valueGenerator = value.createIdentifierGenerator(
            identifierGeneratorFactory,
            dialect,
            defaultCatalog,
            defaultSchema,
            rootClass
        );
        generator.addGeneratedValuePlan(
            new ValueGenerationPlan(
                property.getName(),
                valueGenerator,
                injector( property, attributeDeclarer )
            )
        );
      }
    }
    return generator;
  }

  private Setter injector(Property property, Class attributeDeclarer) {
    return property.getPropertyAccessor( attributeDeclarer )
        .getSetter( attributeDeclarer, property.getName() );
  }

  private Class resolveComponentClass() {
    try {
      return getComponentClass();
    }
    catch ( Exception e ) {
      return null;
    }
  }

  public static class StandardGenerationContextLocator
      implements CompositeNestedGeneratedValueGenerator.GenerationContextLocator {
    private final String entityName;

    public StandardGenerationContextLocator(String entityName) {
      this.entityName = entityName;
    }

    public Serializable locateGenerationContext(SessionImplementor session, Object incomingObject) {
      return session.getEntityPersister( entityName, incomingObject ).getIdentifier( incomingObject, session );
    }
  }

  public static class ValueGenerationPlan implements CompositeNestedGeneratedValueGenerator.GenerationPlan {
    private final String propertyName;
    private final IdentifierGenerator subGenerator;
    private final Setter injector;

    public ValueGenerationPlan(
        String propertyName,
        IdentifierGenerator subGenerator,
        Setter injector) {
      this.propertyName = propertyName;
      this.subGenerator = subGenerator;
      this.injector = injector;
    }

    /**
     * {@inheritDoc}
     */
    public void execute(SessionImplementor session, Object incomingObject, Object injectionContext) {
      final Object generatedValue = subGenerator.generate( session, incomingObject );
      injector.set( injectionContext, generatedValue, session.getFactory() );
    }

    public void registerPersistentGenerators(Map generatorMap) {
      if ( PersistentIdentifierGenerator.class.isInstance( subGenerator ) ) {
        generatorMap.put( ( (PersistentIdentifierGenerator) subGenerator ).generatorKey(), subGenerator );
      }
    }
  }

}
TOP

Related Classes of org.hibernate.mapping.Component$ValueGenerationPlan

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.