Package org.hibernate.envers.configuration.internal.metadata

Source Code of org.hibernate.envers.configuration.internal.metadata.IdMetadataGenerator

/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2008, 2013, 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.envers.configuration.internal.metadata;

import java.util.Iterator;

import org.dom4j.Element;
import org.dom4j.tree.DefaultElement;

import org.hibernate.MappingException;
import org.hibernate.envers.ModificationStore;
import org.hibernate.envers.RelationTargetAuditMode;
import org.hibernate.envers.configuration.internal.metadata.reader.PropertyAuditingData;
import org.hibernate.envers.internal.entities.IdMappingData;
import org.hibernate.envers.internal.entities.PropertyData;
import org.hibernate.envers.internal.entities.mapper.SimpleMapperBuilder;
import org.hibernate.envers.internal.entities.mapper.id.EmbeddedIdMapper;
import org.hibernate.envers.internal.entities.mapper.id.MultipleIdMapper;
import org.hibernate.envers.internal.entities.mapper.id.SimpleIdMapperBuilder;
import org.hibernate.envers.internal.entities.mapper.id.SingleIdMapper;
import org.hibernate.envers.internal.tools.ReflectionTools;
import org.hibernate.mapping.Component;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property;
import org.hibernate.type.ManyToOneType;
import org.hibernate.type.Type;

/**
* Generates metadata for primary identifiers (ids) of versions entities.
*
* @author Adam Warski (adam at warski dot org)
*/
public final class IdMetadataGenerator {
  private final AuditMetadataGenerator mainGenerator;

  IdMetadataGenerator(AuditMetadataGenerator auditMetadataGenerator) {
    mainGenerator = auditMetadataGenerator;
  }

  @SuppressWarnings({"unchecked"})
  private boolean addIdProperties(
      Element parent,
      Iterator<Property> properties,
      SimpleMapperBuilder mapper,
      boolean key,
      boolean audited) {
    while ( properties.hasNext() ) {
      final Property property = properties.next();
      final Type propertyType = property.getType();
      if ( !"_identifierMapper".equals( property.getName() ) ) {
        boolean added = false;
        if ( propertyType instanceof ManyToOneType ) {
          added = mainGenerator.getBasicMetadataGenerator().addManyToOne(
              parent,
              getIdPersistentPropertyAuditingData( property ),
              property.getValue(),
              mapper
          );
        }
        else {
          // Last but one parameter: ids are always insertable
          added = mainGenerator.getBasicMetadataGenerator().addBasic(
              parent,
              getIdPersistentPropertyAuditingData( property ),
              property.getValue(),
              mapper,
              true,
              key
          );
        }
        if ( !added ) {
          // If the entity is audited, and a non-supported id component is used, throwing an exception.
          // If the entity is not audited, then we simply don't support this entity, even in
          // target relation mode not audited.
          if ( audited ) {
            throw new MappingException( "Type not supported: " + propertyType.getClass().getName() );
          }
          else {
            return false;
          }
        }
      }
    }

    return true;
  }

  @SuppressWarnings({"unchecked"})
  IdMappingData addId(PersistentClass pc, boolean audited) {
    // Xml mapping which will be used for relations
    final Element relIdMapping = new DefaultElement( "properties" );
    // Xml mapping which will be used for the primary key of the versions table
    final Element origIdMapping = new DefaultElement( "composite-id" );

    final Property idProp = pc.getIdentifierProperty();
    final Component idMapper = pc.getIdentifierMapper();

    // Checking if the id mapping is supported
    if ( idMapper == null && idProp == null ) {
      return null;
    }

    SimpleIdMapperBuilder mapper;
    if ( idMapper != null ) {
      // Multiple id
      final Class componentClass = ReflectionTools.loadClass(
          ( (Component) pc.getIdentifier() ).getComponentClassName(),
          mainGenerator.getClassLoaderService()
      );
      mapper = new MultipleIdMapper( componentClass );
      if ( !addIdProperties(
          relIdMapping,
          (Iterator<Property>) idMapper.getPropertyIterator(),
          mapper,
          false,
          audited
      ) ) {
        return null;
      }

      // null mapper - the mapping where already added the first time, now we only want to generate the xml
      if ( !addIdProperties(
          origIdMapping,
          (Iterator<Property>) idMapper.getPropertyIterator(),
          null,
          true,
          audited
      ) ) {
        return null;
      }
    }
    else if ( idProp.isComposite() ) {
      // Embedded id
      final Component idComponent = (Component) idProp.getValue();
      final Class embeddableClass = ReflectionTools.loadClass(
          idComponent.getComponentClassName(),
          mainGenerator.getClassLoaderService()
      );
      mapper = new EmbeddedIdMapper( getIdPropertyData( idProp ), embeddableClass );
      if ( !addIdProperties(
          relIdMapping,
          (Iterator<Property>) idComponent.getPropertyIterator(),
          mapper,
          false,
          audited
      ) ) {
        return null;
      }

      // null mapper - the mapping where already added the first time, now we only want to generate the xml
      if ( !addIdProperties(
          origIdMapping,
          (Iterator<Property>) idComponent.getPropertyIterator(),
          null,
          true,
          audited
      ) ) {
        return null;
      }
    }
    else {
      // Single id
      mapper = new SingleIdMapper();

      // Last but one parameter: ids are always insertable
      mainGenerator.getBasicMetadataGenerator().addBasic(
          relIdMapping,
          getIdPersistentPropertyAuditingData( idProp ),
          idProp.getValue(),
          mapper,
          true,
          false
      );

      // null mapper - the mapping where already added the first time, now we only want to generate the xml
      mainGenerator.getBasicMetadataGenerator().addBasic(
          origIdMapping,
          getIdPersistentPropertyAuditingData( idProp ),
          idProp.getValue(),
          null,
          true,
          true
      );
    }

    origIdMapping.addAttribute( "name", mainGenerator.getVerEntCfg().getOriginalIdPropName() );

    // Adding a relation to the revision entity (effectively: the "revision number" property)
    mainGenerator.addRevisionInfoRelation( origIdMapping );

    return new IdMappingData( mapper, origIdMapping, relIdMapping );
  }

  private PropertyData getIdPropertyData(Property property) {
    return new PropertyData(
        property.getName(), property.getName(), property.getPropertyAccessorName(),
        ModificationStore.FULL
    );
  }

  private PropertyAuditingData getIdPersistentPropertyAuditingData(Property property) {
    return new PropertyAuditingData(
        property.getName(), property.getPropertyAccessorName(),
        ModificationStore.FULL, RelationTargetAuditMode.AUDITED, null, null, false
    );
  }
}
TOP

Related Classes of org.hibernate.envers.configuration.internal.metadata.IdMetadataGenerator

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.