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

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

There is a newer version: 7.0.0.Beta1
Show newest version
/*
 * 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 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( "name", name );
		propMapping.addAttribute( "insert", Boolean.toString( insertable ) );
		propMapping.addAttribute( "update", Boolean.toString( updateable ) );

		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) {
		return addProperty(
				parent,
				getModifiedFlagPropertyName( propertyName, suffix ),
				"boolean",
				true,
				false,
				false
		);
	}

	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 column element with the following attributes (unless empty): name,
	 * length, scale, precision, sql-type, read
	 * and 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() );
				}

				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 static abstract 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