All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.hibernate.envers.configuration.internal.metadata.MetadataTools Maven / Gradle / Ivy

/*
 * Hibernate, Relational Persistence for Idiomatic Java
 *
 * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
 * See the lgpl.txt file in the root directory or .
 */
package org.hibernate.envers.configuration.internal.metadata;

import java.util.Iterator;
import javax.persistence.JoinColumn;

import org.hibernate.envers.internal.tools.StringTools;
import org.hibernate.mapping.Column;
import org.hibernate.mapping.Formula;
import org.hibernate.mapping.Selectable;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;

/**
 * @author Adam Warski (adam at warski dot org)
 * @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
 * @author Michal Skowronek (mskowr at o2 dot pl)
 */
public final class MetadataTools {

	private MetadataTools() {
	}

	public static Element addNativelyGeneratedId(
			Element parent, String name, String type,
			boolean useRevisionEntityWithNativeId) {
		final Element idMapping = parent.addElement( "id" );
		idMapping.addAttribute( "name", name ).addAttribute( "type", type );

		final Element generatorMapping = idMapping.addElement( "generator" );
		if ( useRevisionEntityWithNativeId ) {
			generatorMapping.addAttribute( "class", "native" );
		}
		else {
			generatorMapping.addAttribute( "class", "org.hibernate.envers.enhanced.OrderedSequenceGenerator" );
			generatorMapping.addElement( "param" ).addAttribute( "name", "sequence_name" ).setText(
					"REVISION_GENERATOR"
			);
			generatorMapping.addElement( "param" )
					.addAttribute( "name", "table_name" )
					.setText( "REVISION_GENERATOR" );
			generatorMapping.addElement( "param" ).addAttribute( "name", "initial_value" ).setText( "1" );
			generatorMapping.addElement( "param" ).addAttribute( "name", "increment_size" ).setText( "1" );
		}
//        generatorMapping.addAttribute("class", "sequence");
//        generatorMapping.addElement("param").addAttribute("name", "sequence").setText("custom");

		return idMapping;
	}

	public static Element addProperty(
			Element parent,
			String name,
			String type,
			boolean insertable,
			boolean updateable,
			boolean key) {
		final Element propMapping;
		if ( key ) {
			propMapping = parent.addElement( "key-property" );
		}
		else {
			propMapping = parent.addElement( "property" );
			propMapping.addAttribute( "insert", Boolean.toString( insertable ) );
			propMapping.addAttribute( "update", Boolean.toString( updateable ) );
		}

		propMapping.addAttribute( "name", name );

		if ( type != null ) {
			propMapping.addAttribute( "type", type );
		}

		return propMapping;
	}

	public static Element addProperty(Element parent, String name, String type, boolean insertable, boolean key) {
		return addProperty( parent, name, type, insertable, false, key );
	}

	public static Element addModifiedFlagProperty(Element parent, String propertyName, String suffix, String modifiedFlagName) {
		return addProperty(
				parent,
				(modifiedFlagName != null) ? modifiedFlagName : getModifiedFlagPropertyName( propertyName, suffix ),
				"boolean",
				true,
				false,
				false
		);
	}

	public static Element addModifiedFlagPropertyWithColumn(
			Element parent,
			String propertyName,
			String suffix,
			String modifiedFlagName,
			String columnName) {
		final Element property = addProperty(
				parent,
				(modifiedFlagName != null) ? modifiedFlagName : getModifiedFlagPropertyName( propertyName, suffix ),
				"boolean",
				true,
				false,
				false
		);

		addColumn( property, columnName, null, null, null, null, null, null );

		return property;
	}

	public static String getModifiedFlagPropertyName(String propertyName, String suffix) {
		return propertyName + suffix;
	}

	private static void addOrModifyAttribute(Element parent, String name, String value) {
		final Attribute attribute = parent.attribute( name );
		if ( attribute == null ) {
			parent.addAttribute( name, value );
		}
		else {
			attribute.setValue( value );
		}
	}

	/**
	 * Column name shall be wrapped with '`' signs if quotation required.
	 */
	public static Element addOrModifyColumn(Element parent, String name) {
		final Element columnMapping = parent.element( "column" );

		if ( columnMapping == null ) {
			return addColumn( parent, name, null, null, null, null, null, null );
		}

		if ( !StringTools.isEmpty( name ) ) {
			addOrModifyAttribute( columnMapping, "name", name );
		}

		return columnMapping;
	}

	/**
	 * Adds new column element. Method assumes that the value of name attribute is already
	 * wrapped with '`' signs if quotation required. It shall be invoked when column name is taken directly from configuration
	 * file and not from {@link org.hibernate.mapping.PersistentClass} descriptor.
	 */
	public static Element addColumn(
			Element parent,
			String name,
			Integer length,
			Integer scale,
			Integer precision,
			String sqlType,
			String customRead,
			String customWrite) {
		return addColumn( parent, name, length, scale, precision, sqlType, customRead, customWrite, false );
	}

	public static Element addColumn(
			Element parent,
			String name,
			Integer length,
			Integer scale,
			Integer precision,
			String sqlType,
			String customRead,
			String customWrite,
			boolean quoted) {
		final Element columnMapping = parent.addElement( "column" );

		columnMapping.addAttribute( "name", quoted ? "`" + name + "`" : name );
		if ( length != null ) {
			columnMapping.addAttribute( "length", length.toString() );
		}
		if ( scale != null ) {
			columnMapping.addAttribute( "scale", Integer.toString( scale ) );
		}
		if ( precision != null ) {
			columnMapping.addAttribute( "precision", Integer.toString( precision ) );
		}
		if ( !StringTools.isEmpty( sqlType ) ) {
			columnMapping.addAttribute( "sql-type", sqlType );
		}

		if ( !StringTools.isEmpty( customRead ) ) {
			columnMapping.addAttribute( "read", customRead );
		}
		if ( !StringTools.isEmpty( customWrite ) ) {
			columnMapping.addAttribute( "write", customWrite );
		}

		return columnMapping;
	}

	private static Element createEntityCommon(
			Document document,
			String type,
			AuditTableData auditTableData,
			String discriminatorValue,
			Boolean isAbstract) {
		final Element hibernateMapping = document.addElement( "hibernate-mapping" );
		hibernateMapping.addAttribute( "auto-import", "false" );

		final Element classMapping = hibernateMapping.addElement( type );

		if ( auditTableData.getAuditEntityName() != null ) {
			classMapping.addAttribute( "entity-name", auditTableData.getAuditEntityName() );
		}

		if ( discriminatorValue != null ) {
			classMapping.addAttribute( "discriminator-value", discriminatorValue );
		}

		if ( !StringTools.isEmpty( auditTableData.getAuditTableName() ) ) {
			classMapping.addAttribute( "table", auditTableData.getAuditTableName() );
		}

		if ( !StringTools.isEmpty( auditTableData.getSchema() ) ) {
			classMapping.addAttribute( "schema", auditTableData.getSchema() );
		}

		if ( !StringTools.isEmpty( auditTableData.getCatalog() ) ) {
			classMapping.addAttribute( "catalog", auditTableData.getCatalog() );
		}

		if ( isAbstract != null ) {
			classMapping.addAttribute( "abstract", isAbstract.toString() );
		}

		return classMapping;
	}

	public static Element createEntity(
			Document document,
			AuditTableData auditTableData,
			String discriminatorValue,
			Boolean isAbstract) {
		return createEntityCommon( document, "class", auditTableData, discriminatorValue, isAbstract );
	}

	public static Element createSubclassEntity(
			Document document,
			String subclassType,
			AuditTableData auditTableData,
			String extendsEntityName,
			String discriminatorValue,
			Boolean isAbstract) {
		final Element classMapping = createEntityCommon(
				document,
				subclassType,
				auditTableData,
				discriminatorValue,
				isAbstract
		);

		classMapping.addAttribute( "extends", extendsEntityName );

		return classMapping;
	}

	public static Element createJoin(
			Element parent,
			String tableName,
			String schema,
			String catalog) {
		final Element joinMapping = parent.addElement( "join" );

		joinMapping.addAttribute( "table", tableName );

		if ( !StringTools.isEmpty( schema ) ) {
			joinMapping.addAttribute( "schema", schema );
		}

		if ( !StringTools.isEmpty( catalog ) ) {
			joinMapping.addAttribute( "catalog", catalog );
		}

		return joinMapping;
	}

	public static void addColumns(Element anyMapping, Iterator selectables) {
		while ( selectables.hasNext() ) {
			final Selectable selectable = (Selectable) selectables.next();
			if ( selectable.isFormula() ) {
				throw new FormulaNotSupportedException();
			}
			addColumn( anyMapping, (Column) selectable );
		}
	}

	/**
	 * Adds {@code column} element with the following attributes (unless empty):
	 * 
    *
  • name
  • > *
  • length
  • *
  • scale
  • *
  • precision
  • *
  • sql-type
  • *
  • read
  • *
  • write
  • * *
* * @param anyMapping parent element * @param column column descriptor */ public static void addColumn(Element anyMapping, Column column) { addColumn( anyMapping, column.getName(), column.getLength(), column.getScale(), column.getPrecision(), column.getSqlType(), column.getCustomRead(), column.getCustomWrite(), column.isQuoted() ); } @SuppressWarnings({"unchecked"}) private static void changeNamesInColumnElement(Element element, ColumnNameIterator columnNameIterator) { final Iterator properties = element.elementIterator(); while ( properties.hasNext() ) { final Element property = properties.next(); if ( "column".equals( property.getName() ) ) { final Attribute nameAttr = property.attribute( "name" ); if ( nameAttr != null ) { nameAttr.setText( columnNameIterator.next() ); } } } } @SuppressWarnings({"unchecked"}) public static void prefixNamesInPropertyElement( Element element, String prefix, ColumnNameIterator columnNameIterator, boolean changeToKey, boolean insertable) { final Iterator properties = element.elementIterator(); while ( properties.hasNext() ) { final Element property = properties.next(); if ( "property".equals( property.getName() ) || "many-to-one".equals( property.getName() ) ) { final Attribute nameAttr = property.attribute( "name" ); if ( nameAttr != null ) { nameAttr.setText( prefix + nameAttr.getText() ); } changeNamesInColumnElement( property, columnNameIterator ); if ( changeToKey ) { property.setName( "key-" + property.getName() ); // HHH-11463 when cloning a many-to-one to be a key-many-to-one, the FK attribute // should be explicitly set to 'none' or added to be 'none' to avoid issues with // making references to the main schema. if ( property.getName().equals( "key-many-to-one" ) ) { final Attribute foreignKey = property.attribute( "foreign-key" ); if ( foreignKey == null ) { property.addAttribute( "foreign-key", "none" ); } else { foreignKey.setValue( "none" ); } } } if ( "property".equals( property.getName() ) ) { final Attribute insert = property.attribute( "insert" ); insert.setText( Boolean.toString( insertable ) ); } } } } /** * Adds formula element. * * @param element Parent element. * @param formula Formula descriptor. */ public static void addFormula(Element element, Formula formula) { element.addElement( "formula" ).setText( formula.getText() ); } /** * Adds all column or formula elements. * * @param element Parent element. * @param columnIterator Iterator pointing at {@link org.hibernate.mapping.Column} and/or * {@link org.hibernate.mapping.Formula} objects. */ public static void addColumnsOrFormulas(Element element, Iterator columnIterator) { while ( columnIterator.hasNext() ) { final Object o = columnIterator.next(); if ( o instanceof Column ) { addColumn( element, (Column) o ); } else if ( o instanceof Formula ) { addFormula( element, (Formula) o ); } } } /** * An iterator over column names. */ public abstract static class ColumnNameIterator implements Iterator { } public static ColumnNameIterator getColumnNameIterator(final Iterator selectableIterator) { return new ColumnNameIterator() { public boolean hasNext() { return selectableIterator.hasNext(); } public String next() { final Selectable next = selectableIterator.next(); if ( next.isFormula() ) { throw new FormulaNotSupportedException(); } return ( (Column) next ).getName(); } public void remove() { selectableIterator.remove(); } }; } public static ColumnNameIterator getColumnNameIterator(final JoinColumn[] joinColumns) { return new ColumnNameIterator() { int counter; public boolean hasNext() { return counter < joinColumns.length; } public String next() { return joinColumns[counter++].name(); } public void remove() { throw new UnsupportedOperationException(); } }; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy