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

org.fastnate.generator.context.CollectionProperty Maven / Gradle / Ivy

The newest version!
package org.fastnate.generator.context;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import javax.persistence.AssociationOverride;
import javax.persistence.OrderColumn;

import org.fastnate.generator.converter.EntityConverter;
import org.fastnate.generator.dialect.GeneratorDialect;
import org.fastnate.generator.statements.ColumnExpression;
import org.fastnate.generator.statements.PrimitiveColumnExpression;
import org.fastnate.generator.statements.StatementsWriter;

import lombok.Getter;

/**
 * Describes a property of an {@link EntityClass} that contains more than one value.
 *
 * @author Tobias Liefke
 * @param 
 *            The type of the container entity
 * @param 
 *            The type of the entity inside of the collection
 */
@Getter
public class CollectionProperty extends PluralProperty, T> {

	/**
	 * Indicates that the given attribute references a collection and may be used by an {@link CollectionProperty}.
	 *
	 * @param attribute
	 *            the attribute to check
	 * @return {@code true} if an {@link CollectionProperty} may be created for the given attribute
	 */
	static boolean isCollectionProperty(final AttributeAccessor attribute) {
		return Collection.class.isAssignableFrom(attribute.getType()) && hasPluralAnnotation(attribute);
	}

	/** The name of the column that saves the order of the entries in the collection. */
	private final GeneratorColumn orderColumn;

	/**
	 * Creates a new collection property.
	 *
	 * @param sourceClass
	 *            the description of the current inspected class that contains this property
	 * @param attribute
	 *            accessor to the represented attribute
	 * @param override
	 *            the configured assocation override
	 */
	public CollectionProperty(final EntityClass sourceClass, final AttributeAccessor attribute,
			final AssociationOverride override) {
		super(sourceClass, attribute, override, 0);

		// Read a potentially defined order column
		final OrderColumn orderColumnDef = attribute.getAnnotation(OrderColumn.class);
		this.orderColumn = orderColumnDef == null ? null
				: getTable().resolveColumn(
						orderColumnDef.name().length() == 0 ? attribute.getName() + "_ORDER" : orderColumnDef.name());
	}

	@Override
	public void createPostInsertStatements(final StatementsWriter writer, final E entity) throws IOException {
		if (getMappedBy() == null || this.orderColumn != null) {
			final ColumnExpression sourceId = EntityConverter.getEntityReference(entity, getMappedId(), getContext(),
					false);
			int index = 0;
			final GeneratorDialect dialect = getDialect();
			final Collection collection = getValue(entity);
			for (final T value : collection) {
				createValueStatement(writer, entity, sourceId, PrimitiveColumnExpression.create(index++, dialect),
						value);
			}
		}
	}

	@Override
	public Collection findReferencedEntities(final E entity) {
		if (isEmbedded()) {
			final List result = new ArrayList<>();
			for (final T value : getValue(entity)) {
				for (final Property property : getEmbeddedProperties()) {
					result.addAll(property.findReferencedEntities(value));
				}
			}
			return result;
		} else if (isEntityReference()) {
			return getValue(entity);
		}
		return Collections.emptySet();
	}

	@Override
	protected GeneratorColumn getKeyColumn() {
		return this.orderColumn;
	}

	@Override
	public Collection getValue(final E entity) {
		final Collection value = super.getValue(entity);
		return value == null ? Collections. emptySet() : value;
	}

}