/**
 * Copyright (c) 2011, 2015 - Lunifera GmbH (Gross Enzersdorf, Austria), Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0 
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *         Florian Pirchner - Initial implementation
 */
package org.eclipse.osbp.dsl.entity.xtext.validation;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.persistence.Persistence;
import javax.persistence.PostPersist;
import javax.persistence.PostRemove;
import javax.persistence.PostUpdate;
import javax.persistence.PrePersist;
import javax.persistence.PreRemove;
import javax.persistence.PreUpdate;

import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.osbp.dsl.entity.xtext.extensions.ModelExtensions;
import org.eclipse.osbp.dsl.entity.xtext.util.PersistenceNamingUtils;
import org.eclipse.osbp.dsl.semantic.common.helper.Bounds;
import org.eclipse.osbp.dsl.semantic.common.types.LDataType;
import org.eclipse.osbp.dsl.semantic.common.types.LEnum;
import org.eclipse.osbp.dsl.semantic.common.types.LFeature;
import org.eclipse.osbp.dsl.semantic.common.types.LPackage;
import org.eclipse.osbp.dsl.semantic.common.types.LReference;
import org.eclipse.osbp.dsl.semantic.common.types.LScalarType;
import org.eclipse.osbp.dsl.semantic.common.types.LType;
import org.eclipse.osbp.dsl.semantic.common.types.LTypedPackage;
import org.eclipse.osbp.dsl.semantic.common.types.OSBPTypesPackage;
import org.eclipse.osbp.dsl.semantic.entity.LBean;
import org.eclipse.osbp.dsl.semantic.entity.LBeanFeature;
import org.eclipse.osbp.dsl.semantic.entity.LBeanReference;
import org.eclipse.osbp.dsl.semantic.entity.LDiscriminatorType;
import org.eclipse.osbp.dsl.semantic.entity.LEntity;
import org.eclipse.osbp.dsl.semantic.entity.LEntityAttribute;
import org.eclipse.osbp.dsl.semantic.entity.LEntityFeature;
import org.eclipse.osbp.dsl.semantic.entity.LEntityInheritanceStrategy;
import org.eclipse.osbp.dsl.semantic.entity.LEntityModel;
import org.eclipse.osbp.dsl.semantic.entity.LEntityPersistenceInfo;
import org.eclipse.osbp.dsl.semantic.entity.LEntityReference;
import org.eclipse.osbp.dsl.semantic.entity.LEntitySuperIndex;
import org.eclipse.osbp.dsl.semantic.entity.LIndex;
import org.eclipse.osbp.dsl.semantic.entity.LTablePerClassStrategy;
import org.eclipse.osbp.dsl.semantic.entity.LTablePerSubclassStrategy;
import org.eclipse.osbp.dsl.semantic.entity.OSBPEntityPackage;
import org.eclipse.osbp.preferences.EnumDatabaseVendor;
import org.eclipse.xtext.common.types.JvmAnnotationReference;
import org.eclipse.xtext.common.types.JvmGenericType;
import org.eclipse.xtext.common.types.JvmOperation;
import org.eclipse.xtext.common.types.TypesPackage;
import org.eclipse.xtext.common.types.util.TypeReferences;
import org.eclipse.xtext.naming.IQualifiedNameProvider;
import org.eclipse.xtext.resource.IContainer;
import org.eclipse.xtext.resource.IEObjectDescription;
import org.eclipse.xtext.resource.IResourceDescription;
import org.eclipse.xtext.resource.IResourceDescriptions;
import org.eclipse.xtext.resource.impl.ResourceDescriptionsProvider;
import org.eclipse.xtext.validation.Check;
import org.eclipse.xtext.validation.CheckType;
import org.eclipse.xtext.validation.NamesAreUniqueValidator;
import org.eclipse.xtext.validation.ValidationMessageAcceptor;
import org.eclipse.xtext.xbase.jvmmodel.IJvmModelAssociations;
import org.eclipse.xtext.xbase.lib.Extension;

import com.google.inject.Inject;

/**
 * Custom validation rules.
 * 
 * see http://www.eclipse.org/Xtext/documentation.html#validation
 */
@SuppressWarnings("restriction")
public class EntityGrammarValidator extends AbstractEntityGrammarValidator {

	public static final String CODE__DIFFERING_INHERITANCE_FROM_SUPERTYPE = "104";
	public static final String CODE__INHERITANCE_PROPERTY_IGNORED = "105";
	public static final String CODE__INHERITANCE_DISCRIMINATOR_VALUE_NOT_UNIQUE = "106";
	public static final String CODE__DUPLICATE_PERSISTENCE = "106";
	public static final String CODE__DUPLICATE_ID = "107";
	public static final String CODE__DUPLICATE_VERSION = "108";
	public static final String CODE__MISSING_ID = "109";
	public static final String CODE__DUPLICATE_PROPERTY_NAME = "110";
	public static final String CODE__MISSING_OPPOSITE_REFERENCE = "111";
	public static final String CODE__BIDIRECTIONAL_CASCADE_INVALID = "112";
	public static final String CODE__CASCADE_DIRECTION_INVALID = "113";
	public static final String CODE__UUID_WRONG_TYPE = "114";
	public static final String CODE__OPPOSITE_WITHOUT_CASCADE = "115";
	public static final String CODE__MISSING_ID_FOR_VERSIONED = "116";
	public static final String CODE__HISTORIZED_IN_SUBCLASS = "117";
	public static final String CODE__TIMEDEPENDENT_IN_SUBCLASS = "118";
	private static final String CODE__DUPLICATE_DOMAIN_KEY = "119";
	private static final String CODE__DUPLICATE_DOMAIN_DESCRIPTION = "120";
	private static final String CODE__DOMAIN_KEY__NO_MANY = "121";
	private static final String CODE__DOMAIN_DESCRIPTION__NO_MANY = "122";
	private static final String CODE__DOMAIN_KEY__TYPE = "123";
	private static final String CODE__DOMAIN_DESCRIPTION__TYPE = "124";
	private static final String CODE__BEAN_TO_ENTITY__NO_MANY_RELATION_SUPPORTED = "125";
	private static final String CODE__BEAN_TO_ENTITY__NO_OPPOSITE_RELATION_SUPPORTED = "126";
	private static final String CODE__ENTITY_TO_BEAN__NO_OPPOSITE_RELATION_SUPPORTED = "127";
	private static final String CODE__DUPLICATE__PERSISTENCE_ANNOTATION = "128";
	public static final String CODE__INHERITANCE_NO_SUB_TYPES = "129";

	@Inject
	private IQualifiedNameProvider qnp;
	@Inject
	private ModelExtensions extensions;
	@Inject
	private NamesAreUniqueValidator uniqueValidator;
	@Inject
	private IContainer.Manager containermanager;
	@Inject
	private ResourceDescriptionsProvider resourceDescriptionsProvider;
	@Inject
	private IJvmModelAssociations modelAssociations;

	@Check
	public void checkDatatype_asPrimitive(LDataType dt) {
		super.checkDatatype_asPrimitive(dt);
	}

	@Check
	public void checkJPA_MultiHasOppositeReference(LEntityReference prop) {
		if (extensions.isToMany(prop)) {
			if (prop.getOpposite() == null) {
				error("A 'to-many' association needs an opposite reference.",
						OSBPEntityPackage.Literals.LENTITY_REFERENCE__OPPOSITE,
						ValidationMessageAcceptor.INSIGNIFICANT_INDEX, CODE__MISSING_OPPOSITE_REFERENCE,
						(String[]) null);
			} else if (prop.getOpposite().getOpposite() == null) {
				error("Missing opposite reference", prop.getOpposite(), OSBPTypesPackage.Literals.LFEATURE__NAME,
						ValidationMessageAcceptor.INSIGNIFICANT_INDEX, CODE__MISSING_OPPOSITE_REFERENCE,
						(String[]) null);
			}
		}
	}

	@Check
	public void checkBean_MultiHasOppositeReference(LBeanReference prop) {
		if (prop.getType() instanceof LEntity) {
			if (extensions.isToMany(prop)) {
				error("To-Many-Relations are not supported for bean->entity references.",
						OSBPTypesPackage.Literals.LFEATURE__MULTIPLICITY, ValidationMessageAcceptor.INSIGNIFICANT_INDEX,
						CODE__BEAN_TO_ENTITY__NO_MANY_RELATION_SUPPORTED, (String[]) null);
			}
			if (prop.getOpposite() != null) {
				error("Opposite-Relations are not supported for bean->entity references.",
						OSBPEntityPackage.Literals.LBEAN_REFERENCE__OPPOSITE,
						ValidationMessageAcceptor.INSIGNIFICANT_INDEX,
						CODE__BEAN_TO_ENTITY__NO_OPPOSITE_RELATION_SUPPORTED, (String[]) null);
			}
		}
	}

	@Check
	public void checkEntity_MultiHasOppositeReference(LEntityAttribute prop) {
		if (prop.getType() instanceof LBean) {
			if (prop.getOpposite() != null) {
				error("Opposite-Relations are not supported for embeddables.",
						OSBPEntityPackage.Literals.LENTITY_ATTRIBUTE__OPPOSITE,
						ValidationMessageAcceptor.INSIGNIFICANT_INDEX,
						CODE__ENTITY_TO_BEAN__NO_OPPOSITE_RELATION_SUPPORTED, (String[]) null);
			}
		}
	}

	@Check
	public void checkJPA_OppositeNotAlsoCascadeMergePersist(LEntityReference prop) {
		if (prop.getOpposite() != null) {
			if (prop.isCascadeMergePersist() && prop.getOpposite().isCascadeMergePersist()) {
				error("Only one opposite may be specified as cascade",
						OSBPTypesPackage.Literals.LFEATURE__CASCADE_MERGE_PERSIST, CODE__BIDIRECTIONAL_CASCADE_INVALID,
						(String[]) null);
			}

			if (extensions.isToMany(prop.getOpposite())) {
				if (prop.isCascadeMergePersist()) {
					error("Cascade must not affect the common parent in a many-to-one relation", prop,
							OSBPTypesPackage.Literals.LFEATURE__CASCADE_MERGE_PERSIST, CODE__CASCADE_DIRECTION_INVALID,
							new String[0]);
				}
			}
		}
	}

	@Check
	public void checkJPA_OppositeNotAlsoCascadeRemove(LEntityReference prop) {
		if (prop.getOpposite() != null) {
			if (prop.isCascadeRemove() && prop.getOpposite().isCascadeRemove()) {
				error("Only one opposite may be specified as cascade",
						OSBPTypesPackage.Literals.LFEATURE__CASCADE_REMOVE, CODE__BIDIRECTIONAL_CASCADE_INVALID,
						(String[]) null);
			}

			if (extensions.isToMany(prop.getOpposite())) {
				if (prop.isCascadeRemove()) {
					error("Cascade must not affect the common parent in a many-to-one relation", prop,
							OSBPTypesPackage.Literals.LFEATURE__CASCADE_REMOVE, CODE__CASCADE_DIRECTION_INVALID,
							new String[0]);
				}
			}
		}
	}

	@Check
	public void checkJPA_Opposite_OneIsCascadeMergePersist(LEntityReference prop) {
		Bounds propBound = extensions.getBounds(prop);
		Bounds oppositeBound = extensions.getBounds(prop.getOpposite());

		if (propBound.isToMany() || oppositeBound.isToMany()) {
			// no check required!
			return;
		}

		if (prop.getOpposite() != null) {
			if (!prop.isCascadeMergePersist() && !prop.getOpposite().isCascadeMergePersist()) {
				error("Opposite references may only defined for cascading relations.", prop,
						OSBPTypesPackage.Literals.LFEATURE__CASCADE_MERGE_PERSIST, CODE__OPPOSITE_WITHOUT_CASCADE,
						new String[0]);
			}
		}
	}

	@Check
	public void checkJPA_Opposite_OneIsCascadeRemove(LEntityReference prop) {
		Bounds propBound = extensions.getBounds(prop);
		Bounds oppositeBound = extensions.getBounds(prop.getOpposite());

		if (propBound.isToMany() || oppositeBound.isToMany()) {
			// no check required!
			return;
		}

		if (prop.getOpposite() != null) {
			if (!prop.isCascadeRemove() && !prop.getOpposite().isCascadeRemove()) {
				error("Opposite references may only defined for cascading relations.", prop,
						OSBPTypesPackage.Literals.LFEATURE__CASCADE_REMOVE, CODE__OPPOSITE_WITHOUT_CASCADE,
						new String[0]);
			}
		}
	}

	@Check
	public void checkBean_OppositeNotAlsoCascadeMergePersist(LBeanReference prop) {
		if (prop.getType() instanceof LBean) {
			if (prop.getOpposite() != null) {
				if (prop.isCascadeMergePersist() && isCascading(prop)) {
					error("Only one opposite may be specified as cascade",
							OSBPTypesPackage.Literals.LFEATURE__CASCADE_MERGE_PERSIST,
							CODE__BIDIRECTIONAL_CASCADE_INVALID, (String[]) null);
				}

				if (extensions.isToMany(prop.getOpposite())) {
					if (prop.isCascadeMergePersist()) {
						error("Cascade must not affect the common parent in a many-to-one relation", prop,
								OSBPTypesPackage.Literals.LFEATURE__CASCADE_MERGE_PERSIST,
								CODE__CASCADE_DIRECTION_INVALID, new String[0]);
					}
				}
			}
		}
	}

	@Check
	public void checkBean_OppositeNotAlsoCascadeRemove(LBeanReference prop) {
		if (prop.getType() instanceof LBean) {
			if (prop.getOpposite() != null) {
				if (prop.isCascadeRemove() && isCascading(prop)) {
					error("Only one opposite may be specified as cascade",
							OSBPTypesPackage.Literals.LFEATURE__CASCADE_REMOVE, CODE__BIDIRECTIONAL_CASCADE_INVALID,
							(String[]) null);
				}

				if (extensions.isToMany(prop.getOpposite())) {
					if (prop.isCascadeRemove()) {
						error("Cascade must not affect the common parent in a many-to-one relation", prop,
								OSBPTypesPackage.Literals.LFEATURE__CASCADE_REMOVE, CODE__CASCADE_DIRECTION_INVALID,
								new String[0]);
					}
				}
			}
		}
	}

	protected boolean isCascading(LBeanReference prop) {
		LFeature opposite = prop.getOpposite();
		if (opposite instanceof LReference) {
			return ((LReference) opposite).isCascadeMergePersist() || ((LReference) opposite).isCascadeRemove();
		} else {
			return false;
		}
	}

	@Check
	public void checkProperties_JavaKeyWord(LFeature lprop) {
		super.checkProperties_JavaKeyWord(lprop);
	}

	@Check
	public void checkDuplicatePackages_InFile(LEntityModel lmodel) {
		Set<String> names = new HashSet<String>();
		int counter = -1;
		for (LPackage pkg : lmodel.getPackages()) {
			counter++;
			String pkgName = qnp.getFullyQualifiedName(pkg).toString();
			if (names.contains(pkgName)) {
				error(String.format("Package %s must not be defined twice!", pkgName),
						OSBPEntityPackage.Literals.LENTITY_MODEL__PACKAGES, counter, CODE__DUPLICATE_LPACKAGE_IN_FILE,
						(String[]) null);
			}
			names.add(pkgName);
		}
	}

	@Check(CheckType.NORMAL)
	public void checkDuplicateType_InProject(LType type) {
		if (type instanceof LDataType) {
			return;
		}
		super.checkDuplicateType_InProject(type);
	}

	@Check(CheckType.NORMAL)
	public void checkDuplicateDatatypeInPackage(LTypedPackage pkg) {
		super.checkDuplicateDatatypeInPackage(pkg);
	}

	@Check(CheckType.NORMAL)
	public void checkDuplicatePackage_InProject(LPackage lPackage) {
		super.checkDuplicatePackage_InProject(lPackage);
	}

	@Check
	public void checkBeanManyToMany(LBeanReference prop) {
		ModelExtensions extension = new ModelExtensions();
		if (prop.getOpposite() != null && extension.isToMany(prop) && extension.isToMany(prop.getOpposite())) {
			error(String.format("ManyToMany relations are not permitted!", qnp.getFullyQualifiedName(prop).toString()),
					OSBPEntityPackage.Literals.LBEAN_REFERENCE__OPPOSITE, ValidationMessageAcceptor.INSIGNIFICANT_INDEX,
					CODE__MANY_TO_MANY__NOT_SUPPORTED, (String[]) null);
		}
	}

	@Check
	public void checkManyToMany(LEntityReference prop) {
		ModelExtensions extension = new ModelExtensions();
		if (prop.getOpposite() != null && extension.isToMany(prop) && extension.isToMany(prop.getOpposite())) {
			error(String.format("ManyToMany relations are not permitted!", qnp.getFullyQualifiedName(prop).toString()),
					OSBPEntityPackage.Literals.LENTITY_REFERENCE__OPPOSITE,
					ValidationMessageAcceptor.INSIGNIFICANT_INDEX, CODE__MANY_TO_MANY__NOT_SUPPORTED, (String[]) null);
		}
	}

	@Check(CheckType.NORMAL)
	public void checkJPA_ConsistentInheritanceStrategy(LEntity entity) {
		// no checks required - inheritance is inherited
		if (entity.getInheritanceStrategy() == null) {
			return;
		}

		LEntityInheritanceStrategy differingSuperStgy = searchDifferingSuperStrategy(entity.getInheritanceStrategy(),
				entity);
		if (differingSuperStgy != null) {
			LEntity superType = (LEntity) differingSuperStgy.eContainer();
			warning(String.format(
					"The supertype %s uses the inheritance strategy %s. The inheritance of this entity is ignored!",
					qnp.getFullyQualifiedName(superType).toString(), getStrategyName(differingSuperStgy)),
					OSBPEntityPackage.Literals.LENTITY__INHERITANCE_STRATEGY,
					ValidationMessageAcceptor.INSIGNIFICANT_INDEX, CODE__DIFFERING_INHERITANCE_FROM_SUPERTYPE,
					(String[]) null);
		}
	}

	@Check(CheckType.NORMAL)
	public void checkJPA_Features(LEntityAttribute prop) {
		if (prop.isUuid()) {
			boolean typeOK = false;
			if (prop.getType() instanceof LDataType) {
				LDataType type = (LDataType) prop.getType();
				String typename = type.getJvmTypeReference().getQualifiedName();
				if (typename.equals("java.lang.String")) {
					typeOK = true;
				}
			}

			if (!typeOK) {
				error("UUIDs must be of type String.", OSBPTypesPackage.Literals.LATTRIBUTE__UUID,
						CODE__UUID_WRONG_TYPE, new String[0]);
			}
		}

		if (prop.isDomainKey()) {
			if (extensions.isToMany(prop)) {
				error("DomainKey is not valid for one to many relations.",
						OSBPTypesPackage.Literals.LATTRIBUTE__DOMAIN_KEY, CODE__DOMAIN_KEY__NO_MANY, new String[0]);
			}

			if (prop.getType() instanceof LDataType) {
				LDataType type = (LDataType) prop.getType();
				if (type.getJvmTypeReference() == null
						|| !"java.lang.String".equals(type.getJvmTypeReference().getQualifiedName())) {
					error("DomainKey must be of type String.", OSBPTypesPackage.Literals.LATTRIBUTE__DOMAIN_KEY,
							CODE__DOMAIN_KEY__TYPE, new String[0]);
				}
			}
		}

		if (prop.isDomainDescription()) {
			if (extensions.isToMany(prop)) {
				error("DomainDescription is not valid for one to many relations.",
						OSBPTypesPackage.Literals.LATTRIBUTE__DOMAIN_DESCRIPTION, CODE__DOMAIN_DESCRIPTION__NO_MANY,
						new String[0]);
			}

			if (prop.getType() instanceof LDataType) {
				LDataType type = (LDataType) prop.getType();
				String typename = type.getJvmTypeReference().getQualifiedName();
				if (!typename.equals("java.lang.String")) {
					error("DomainDescription must be of type String.",
							OSBPTypesPackage.Literals.LATTRIBUTE__DOMAIN_DESCRIPTION, CODE__DOMAIN_DESCRIPTION__TYPE,
							new String[0]);
				}
			}
		}
	}

	@Check(CheckType.NORMAL)
	public void checkJPA_Historized(LEntity entity) {
		if (entity.isHistorized()) {
			if (entity.getSuperType() != null && !entity.getSuperType().isMappedSuperclass()) {
				error("Keyword historized may only be used in toplevel entities of inheritance hierarchy",
						OSBPEntityPackage.Literals.LENTITY__HISTORIZED, CODE__HISTORIZED_IN_SUBCLASS, new String[0]);
			}
		}

		if (entity.isTimedependent()) {
			if (entity.getSuperType() != null && !entity.getSuperType().isMappedSuperclass()) {
				error("Keyword timedependent may only be used in toplevel entities of inheritance hierarchy",
						OSBPEntityPackage.Literals.LENTITY__TIMEDEPENDENT, CODE__TIMEDEPENDENT_IN_SUBCLASS,
						new String[0]);
			}
		}
	}

	@Check(CheckType.NORMAL)
	public void checkIndex_Features(LIndex index) {
	}

	@Check(CheckType.NORMAL)
	public void checkEntity_Index(LEntity entity) {
	}

	@Check(CheckType.NORMAL)
	public void checkJPA_Features(LEntity entity) {

		int idCounter = 0;
		int versionCounter = 0;
		int domainKeyCounter = 0;
		int domainDescriptionCounter = 0;
		Map<String, Integer> attNames = new HashMap<String, Integer>();
		for (LEntityFeature feature : entity.getAllFeatures()) {
			if (feature instanceof LEntityAttribute) {
				LEntityAttribute att = (LEntityAttribute) feature;
				if (att.isId() || att.isUuid()) {
					idCounter++;
				}
				if (att.isVersion()) {
					versionCounter++;
				}
				if (att.isDomainKey()) {
					domainKeyCounter++;
				}
				if (att.isDomainDescription()) {
					domainDescriptionCounter++;
				}
			}

			if (!attNames.containsKey(feature.getName())) {
				attNames.put(feature.getName(), 1);
			} else {
				int value = attNames.get(feature.getName());
				attNames.put(feature.getName(), ++value);
			}
		}

		if (idCounter == 0 && (entity.isHistorized() || entity.isTimedependent())) {
			error("An historized or timedependent entity must have an ID property",
					OSBPEntityPackage.Literals.LENTITY__FEATURES, CODE__MISSING_ID_FOR_VERSIONED);
		} else

		if (idCounter == 0) {
			warning("An entity should have an ID property", OSBPEntityPackage.Literals.LENTITY__FEATURES,
					CODE__MISSING_ID);
		} else if (idCounter > 1) {
			int i = 0;
			for (LEntityFeature feature : entity.getFeatures()) {
				if (feature instanceof LEntityAttribute) {
					if (((LEntityAttribute) feature).isId() || ((LEntityAttribute) feature).isUuid()) {
						error("An entity must only have one ID property.", OSBPEntityPackage.Literals.LENTITY__FEATURES,
								i, CODE__DUPLICATE_ID, new String[0]);
						break;
					}
				}

				i++;
			}
		}
		if (versionCounter > 1) {
			int i = 0;
			for (LEntityFeature feature : entity.getFeatures()) {
				if (feature instanceof LEntityAttribute) {
					if (((LEntityAttribute) feature).isVersion()) {
						error("An entity must only have one Version property.",
								OSBPEntityPackage.Literals.LENTITY__FEATURES, i, CODE__DUPLICATE_VERSION,
								new String[0]);
						break;
					}
				}
				i++;
			}
		}

		if (domainKeyCounter > 1) {
			int i = 0;
			for (LEntityFeature feature : entity.getFeatures()) {
				if (feature instanceof LEntityAttribute) {
					if (((LEntityAttribute) feature).isDomainKey()) {
						error("An entity must only have one DomainKey property.",
								OSBPEntityPackage.Literals.LENTITY__FEATURES, i, CODE__DUPLICATE_DOMAIN_KEY,
								new String[0]);
						break;
					}
				}
				i++;
			}
		}

		if (domainDescriptionCounter > 1) {
			int i = 0;
			for (LEntityFeature feature : entity.getFeatures()) {
				if (feature instanceof LEntityAttribute) {
					if (((LEntityAttribute) feature).isDomainDescription()) {
						error("An entity must only have one DomainDescription property.",
								OSBPEntityPackage.Literals.LENTITY__FEATURES, i, CODE__DUPLICATE_DOMAIN_DESCRIPTION,
								new String[0]);
						break;
					}
				}
				i++;
			}
		}

		for (Map.Entry<String, Integer> entry : attNames.entrySet()) {
			if (entry.getValue() > 1) {
				int i = 0;
				for (LEntityFeature feature : entity.getFeatures()) {
					if (feature.getName().equals(entry.getKey())) {
						error(String.format("The property \"%s\" must only be defined once!", feature.getName()),
								OSBPEntityPackage.Literals.LENTITY__FEATURES, i, CODE__DUPLICATE_PROPERTY_NAME,
								new String[0]);
						break;
					}
					i++;
				}
			}
		}
	}

	protected String getStrategyName(LEntityInheritanceStrategy stgy) {
		if (LTablePerClassStrategy.class.isAssignableFrom(stgy.getClass())) {
			return "Table-Per-Class";
		} else {
			return "Table-Per-Subclass";
		}
	}

	protected LEntityInheritanceStrategy searchDifferingSuperStrategy(LEntityInheritanceStrategy stgy, LEntity entity) {
		LEntity superEntity = entity.getSuperType();
		if (superEntity == null) {
			return null;
		}

		LEntityInheritanceStrategy superStgy = superEntity.getInheritanceStrategy();
		if (superStgy == null) {
			return searchDifferingSuperStrategy(stgy, superEntity);
		}

		if (!stgy.getClass().getName().equals(superStgy.getClass().getName())) {
			return superStgy;
		}

		return searchDifferingSuperStrategy(stgy, superEntity);
	}

	@Check(CheckType.NORMAL)
	public void checkJPA_IgnoredInheritanceStrategyProperties(LEntity entity) {
		// no checks required - inheritance is inherited
		LEntityInheritanceStrategy stgy = entity.getInheritanceStrategy();
		if (stgy == null) {
			return;
		}

		if (entity.getSuperType() != null && !extensions.checkIsMappedSuperclass(entity.getSuperType())) {
			if (LTablePerClassStrategy.class.isAssignableFrom(stgy.getClass())) {
				LTablePerClassStrategy castStgy = (LTablePerClassStrategy) stgy;
				if (castStgy.getDiscriminatorColumn() != null) {
					sendIgnoredInheritancePropertyWarning(stgy,
							OSBPEntityPackage.Literals.LTABLE_PER_CLASS_STRATEGY__DISCRIMINATOR_COLUMN);
				}
				if (castStgy.getDiscriminatorType() != LDiscriminatorType.INHERIT) {
					sendIgnoredInheritancePropertyWarning(stgy,
							OSBPEntityPackage.Literals.LTABLE_PER_CLASS_STRATEGY__DISCRIMINATOR_TYPE);
				}
			} else {
				LTablePerSubclassStrategy castStgy = (LTablePerSubclassStrategy) stgy;
				if (castStgy.getDiscriminatorColumn() != null) {
					sendIgnoredInheritancePropertyWarning(stgy,
							OSBPEntityPackage.Literals.LTABLE_PER_SUBCLASS_STRATEGY__DISCRIMINATOR_COLUMN);
				}
				if (castStgy.getDiscriminatorType() != LDiscriminatorType.INHERIT) {
					sendIgnoredInheritancePropertyWarning(stgy,
							OSBPEntityPackage.Literals.LTABLE_PER_SUBCLASS_STRATEGY__DISCRIMINATOR_TYPE);
				}
			}
		}
	}

	@Check(CheckType.NORMAL)
	public void checkJPA_InheritanceStrategy_NotUniqueDiscriminatorValue(LEntity entity) {
		if (entity.getSuperType() == null) {
			return;
		}

		String currentValue = extensions.toDiscriminatorValue(extensions.toInheritanceStrategy(entity));

		// collect all super type strategies
		List<LEntityInheritanceStrategy> stgies = extensions.collectAllInheritanceStrategies(entity.getSuperType());

		for (LEntityInheritanceStrategy stgy : stgies) {
			String value = extensions.toDiscriminatorValue(stgy);
			if (value.equals(currentValue)) {
				error(String.format("The discrimator value %s is already used by supertype!", value), entity,
						OSBPEntityPackage.Literals.LENTITY__INHERITANCE_STRATEGY,
						ValidationMessageAcceptor.INSIGNIFICANT_INDEX, CODE__INHERITANCE_DISCRIMINATOR_VALUE_NOT_UNIQUE,
						(String[]) null);
			}
		}
	}

	@Check(CheckType.NORMAL)
	public void checkJPA_InheritanceStrategy(LEntity entity) {
		LEntityInheritanceStrategy stgy = entity.getInheritanceStrategy();
		if (stgy == null) {
			return;
		}

		if (entity.getSubTypes().isEmpty()) {
			error("Inheritance is only allowed for entities with sub types.", entity,
					OSBPEntityPackage.Literals.LENTITY__INHERITANCE_STRATEGY,
					ValidationMessageAcceptor.INSIGNIFICANT_INDEX, CODE__INHERITANCE_NO_SUB_TYPES, (String[]) null);
		}
	}

	@Check(CheckType.NORMAL)
	public void checkFilteringAndRange(LEntityAttribute attribute) {
		if (attribute.isFiltering() || attribute.isRangeFiltering()) {
			LScalarType type = attribute.getType();
			if (type instanceof LDataType) {
				LDataType dt = (LDataType) type;
				if (!dt.isAsBlob() && !dt.isSyntheticFlag()) {
					return;
				}
			}
			if (attribute.isFiltering()) {
				error("Filter keyword not allowed for this type", attribute,
						OSBPTypesPackage.Literals.LATTRIBUTE__RANGE_FILTERING);
			} else {
				error("Range keyword not allowed for this type", attribute,
						OSBPTypesPackage.Literals.LATTRIBUTE__FILTERING);
			}
		}
	}

	@Check(CheckType.NORMAL)
	public void checkDuplicatePersistentFQN_InProject(LEntity entity) {
		LEntityPersistenceInfo info = entity.getPersistenceInfo();
		if (info == null) {
			return;
		}
		Map<IContainer, List<LEntityPersistenceInfo>> lTypes = getAllPersistentFQNsFor(info);
		for (Map.Entry<IContainer, List<LEntityPersistenceInfo>> temp : lTypes.entrySet())
			if (temp.getValue().size() > 1) {
				error(String.format("Persistence type %s is already defined!",
						qnp.getFullyQualifiedName(info).toString()), entity,
						OSBPEntityPackage.Literals.LENTITY__PERSISTENCE_INFO,
						ValidationMessageAcceptor.INSIGNIFICANT_INDEX, CODE__DUPLICATE_PERSISTENCE, (String[]) null);
			}
	}

	private void sendIgnoredInheritancePropertyWarning(LEntityInheritanceStrategy stgy, EAttribute att) {
		warning("Inherited from parent entity. Will be ignored.", stgy, att,
				ValidationMessageAcceptor.INSIGNIFICANT_INDEX, CODE__DIFFERING_INHERITANCE_FROM_SUPERTYPE,
				(String[]) null);
	}

	public Map<IContainer, List<LEntityPersistenceInfo>> getAllPersistentFQNsFor(LEntityPersistenceInfo info) {
		Map<IContainer, List<LEntityPersistenceInfo>> allEntities = new HashMap<IContainer, List<LEntityPersistenceInfo>>();
		IResourceDescriptions resourceDescriptions = resourceDescriptionsProvider
				.getResourceDescriptions(info.eResource());
		IResourceDescription resourceDescription = resourceDescriptions
				.getResourceDescription(info.eResource().getURI());
		List<IContainer> visiblecontainers = containermanager.getVisibleContainers(resourceDescription,
				resourceDescriptions);
		for (IContainer container : visiblecontainers) {
			List<LEntityPersistenceInfo> types = new ArrayList<LEntityPersistenceInfo>();
			allEntities.put(container, types);
			for (IEObjectDescription eObjectDescription : container.getExportedObjects(
					OSBPEntityPackage.Literals.LENTITY_PERSISTENCE_INFO, qnp.getFullyQualifiedName(info), true)) {
				types.add((LEntityPersistenceInfo) eObjectDescription.getEObjectOrProxy());
			}
		}
		return allEntities;
	}

	@Check
	public void checkClassPath(LTypedPackage entityModel) {
		TypeReferences typeReferences = getServices().getTypeReferences();
		final JvmGenericType listType = (JvmGenericType) typeReferences.findDeclaredType(List.class, entityModel);
		if (listType == null || listType.getTypeParameters().isEmpty()) {
			error("Couldn't find a JDK 1.5 or higher on the project's classpath.", entityModel,
					OSBPTypesPackage.Literals.LPACKAGE__NAME, CODE__MISSING__JDK_1_5);
		}
		if (typeReferences.findDeclaredType(Persistence.class, entityModel) == null) {
			error("Couldn't find the mandatory library 'javax.persistence' 2.1.0 or higher on the project's classpath.",
					entityModel, OSBPTypesPackage.Literals.LPACKAGE__NAME, CODE__MISSING__JAVAX_PERSISTENCE);
		}
		if (typeReferences.findDeclaredType("org.eclipse.osbp.runtime.common.annotations.Dispose",
				entityModel) == null) {
			error("Couldn't find the mandatory library 'org.eclipse.osbp.runtime.common' on the project's classpath.",
					entityModel, OSBPTypesPackage.Literals.LPACKAGE__NAME, CODE__MISSING__L_RUNTIME_COMMON);
		}
		if (typeReferences.findDeclaredType(Extension.class, entityModel) == null) {
			error("Couldn't find the mandatory library 'org.eclipse.xtext.xbase.lib' 2.11.0 or higher on the project's classpath.",
					entityModel, OSBPTypesPackage.Literals.LPACKAGE__NAME, CODE__MISSING__XBASE_LIB);
		}
		if (typeReferences.findDeclaredType("org.eclipse.osbp.dsl.common.datatypes.IDatatypeConstants",
				entityModel) == null) {
			warning("Couldn't find the optional library 'org.eclipse.osbp.dsl.datatype.lib' on the project's classpath. This may cause resolving problems.",
					entityModel, OSBPTypesPackage.Literals.LPACKAGE__NAME, CODE__MISSING__DATATYPE_LIB);
		}
		if (typeReferences.findDeclaredType("javax.validation.Valid", entityModel) == null) {
			error("Couldn't find the library 'javax.validation' on the project's classpath. This may cause resolving problems.",
					entityModel, OSBPTypesPackage.Literals.LPACKAGE__NAME, CODE__MISSING__DATATYPE_LIB);
		}
	}

	@Check
	public void checkDuplicatePersistenceAnnotation(LEntityModel entityModel) {

		for (JvmGenericType jvmType : EcoreUtil.<JvmGenericType>getObjectsByType(entityModel.eResource().getContents(),
				TypesPackage.Literals.JVM_GENERIC_TYPE)) {

			int prePersist = 0;
			JvmOperation op_prePersist = null;
			int preUpdate = 0;
			JvmOperation op_preUpdate = null;
			int preRemove = 0;
			JvmOperation op_preRemove = null;
			int postPersist = 0;
			JvmOperation op_postPersist = null;
			int postUpdate = 0;
			JvmOperation op_postUpdate = null;
			int postRemove = 0;
			JvmOperation op_postRemove = null;

			for (JvmOperation op : jvmType.getDeclaredOperations()) {
				for (JvmAnnotationReference ann : op.getAnnotations()) {
					String fqn = ann.getAnnotation().getIdentifier();
					if (fqn.equals(PrePersist.class.getCanonicalName())) {
						prePersist++;
						op_prePersist = op;
					} else if (fqn.equals(PreUpdate.class.getCanonicalName())) {
						preUpdate++;
						op_preUpdate = op;
					} else if (fqn.equals(PreRemove.class.getCanonicalName())) {
						preRemove++;
						op_preRemove = op;
					} else if (fqn.equals(PostPersist.class.getCanonicalName())) {
						postPersist++;
						op_postPersist = op;
					} else if (fqn.equals(PostUpdate.class.getCanonicalName())) {
						postUpdate++;
						op_postUpdate = op;
					} else if (fqn.equals(PostRemove.class.getCanonicalName())) {
						postRemove++;
						op_postRemove = op;
					}
				}
			}

			if (prePersist > 1) {
				error("Only one @PrePersist allowed per entity.",
						modelAssociations.getPrimarySourceElement(op_prePersist),
						OSBPTypesPackage.Literals.LANNOTATION_TARGET__ANNOTATIONS,
						CODE__DUPLICATE__PERSISTENCE_ANNOTATION);
			}
			if (preUpdate > 1) {
				error("Only one @PreUpdate allowed per entity.",
						modelAssociations.getPrimarySourceElement(op_preUpdate),
						OSBPTypesPackage.Literals.LANNOTATION_TARGET__ANNOTATIONS,
						CODE__DUPLICATE__PERSISTENCE_ANNOTATION);
			}
			if (preRemove > 1) {
				error("Only one @PreRemove allowed per entity.",
						modelAssociations.getPrimarySourceElement(op_preRemove),
						OSBPTypesPackage.Literals.LANNOTATION_TARGET__ANNOTATIONS,
						CODE__DUPLICATE__PERSISTENCE_ANNOTATION);
			}
			if (postPersist > 1) {
				error("Only one @PostPersist allowed per entity.",
						modelAssociations.getPrimarySourceElement(op_postPersist),
						OSBPTypesPackage.Literals.LANNOTATION_TARGET__ANNOTATIONS,
						CODE__DUPLICATE__PERSISTENCE_ANNOTATION);
			}
			if (postUpdate > 1) {
				error("Only one @PostUpdate allowed per entity.",
						modelAssociations.getPrimarySourceElement(op_postUpdate),
						OSBPTypesPackage.Literals.LANNOTATION_TARGET__ANNOTATIONS,
						CODE__DUPLICATE__PERSISTENCE_ANNOTATION);
			}
			if (postRemove > 1) {
				error("Only one @PostRemove allowed per entity.",
						modelAssociations.getPrimarySourceElement(op_postRemove),
						OSBPTypesPackage.Literals.LANNOTATION_TARGET__ANNOTATIONS,
						CODE__DUPLICATE__PERSISTENCE_ANNOTATION);
			}
		}
	}

	@Check(CheckType.NORMAL)
	public void check_KanbanState(LEntity entity) {

		int counter = 0;
		for (LEntityFeature feature : entity.getAllFeatures()) {
			if (feature instanceof LEntityAttribute) {
				LEntityAttribute att = (LEntityAttribute) feature;
				if (att.isAsKanbanState()) {
					counter++;
				}
			}
		}

		if (counter > 1) {
			int i = 0;
			for (LEntityFeature feature : entity.getFeatures()) {
				if (feature instanceof LEntityAttribute) {
					if (((LEntityAttribute) feature).isAsKanbanState()) {
						error("An entity must only have one kanban state.",
								OSBPEntityPackage.Literals.LENTITY__FEATURES, i, "", new String[0]);
					}
				}
				i++;
			}
		}
	}

	@Check(CheckType.NORMAL)
	public void check_KanbanStateType(LEntityAttribute att) {
		if (att.isAsKanbanState() && !(att.getType() instanceof LEnum)) {
			error("Kanban states must be of type Enum", OSBPEntityPackage.Literals.LENTITY_ATTRIBUTE__AS_KANBAN_STATE,
					"", new String[0]);
		}
	}

	@Check
	public void check_PersistenceUnitTag(LEntity entity) {
		if (!entity.isMappedSuperclass()) {
			if (entity.getPersistenceUnit() == null) {
				error("An entity must have a persistence unit.", OSBPEntityPackage.Literals.LENTITY__FEATURES);
			}
			if (entity.getPersistenceUnit() != null && entity.getPersistenceUnit().trim().isEmpty()) {
				error("A persistence unit can't be empty.", entity,
						OSBPEntityPackage.Literals.LENTITY__PERSISTENCE_UNIT);
			}
		}
	}

	@Check
	private void check_EntityIdentifiersLength(LEntity entity) {
		if (entity != null && entity.getPersistenceUnit() != null && !entity.getPersistenceUnit().isEmpty()) {
			int maxTableNameLength = EnumDatabaseVendor.getMaxTableNameLength();
			int maxColumnNameLength = EnumDatabaseVendor.getMaxColumnNameLength();
			int maxIndexNameLength = EnumDatabaseVendor.getMaxIndexNameLength();
			
			String expectedFeatureName = PersistenceNamingUtils.camelCaseToUpperCase(entity.getName());

			if (entity.getName() != null && !entity.getName().isEmpty()	&& expectedFeatureName.length() >= maxTableNameLength) {
				warning("The entity name '" + entity.getName() + "' results to the table name '" + expectedFeatureName
						+ "', which should not exceed " + maxTableNameLength
						+ " characters. Please rename this entity according to the OS.bee naming conventions: http://download.osbee.org/documentation/index.php/Entity_DSL", entity,
						OSBPEntityPackage.Literals.LENTITY__PERSISTENCE_INFO);
			}
			for (LEntityFeature attr : entity.getFeatures()) {
				if (attr.getName() != null && !attr.getName().isEmpty()) {

					expectedFeatureName = PersistenceNamingUtils.camelCaseToUpperCase(attr.getName());

					if (expectedFeatureName.length() >= maxColumnNameLength && attr instanceof LEntityReference) {
						warning("The reference name '" + attr.getName() + "' results to the column name '"
								+ expectedFeatureName + "', which should not exceed " + maxColumnNameLength
								+ " characters. Please rename this reference according to the OS.bee naming conventions: http://download.osbee.org/documentation/index.php/Entity_DSL", attr,
								OSBPEntityPackage.Literals.LENTITY_REFERENCE__TYPE);
					} else if (expectedFeatureName.length() >= maxColumnNameLength	&& attr instanceof LEntityAttribute) {
						warning("The attribute name '" + attr.getName() + "' results to the column name '"
								+ expectedFeatureName + "', which should not exceed " + maxColumnNameLength
								+ " characters. Please rename this attribute according to the OS.bee naming conventions: http://download.osbee.org/documentation/index.php/Entity_DSL", attr,
								OSBPEntityPackage.Literals.LENTITY_ATTRIBUTE__TYPED_NAME);
						
					} else if (attr.getName().length() < maxColumnNameLength && attr instanceof LEntityAttribute) {
						LScalarType type = ((LEntityAttribute) attr).getType();

						if (type instanceof LBean) {
							for (LBeanFeature feature : ((LBean) type).getFeatures()) {
								
								expectedFeatureName = type.getName().toUpperCase() + "_" + feature.getName().toUpperCase();

								if (feature.getName() != null && !feature.getName().isEmpty()
										&& expectedFeatureName.length() >= maxColumnNameLength) {

									warning("The attribute name '" + attr.getName()
											+ "' combined with the bean feature name '" + feature.getName()
											+ "' results to the column name '" + expectedFeatureName
											+ "', which should not exceed " + maxColumnNameLength
											+ " characters. Please rename this attribute according to the OS.bee naming conventions: http://download.osbee.org/documentation/index.php/Entity_DSL", attr,
											OSBPEntityPackage.Literals.LENTITY_ATTRIBUTE__TYPED_NAME);
								}
							}
						}
					}
				}
			}
			for (LIndex idx : entity.getIndexes()) {
				expectedFeatureName = PersistenceNamingUtils.camelCaseToUpperCase(entity.getName() + idx.getName());
				if (idx.getName() != null && !idx.getName().isEmpty()
						&& expectedFeatureName.length() >= maxIndexNameLength) {
					warning("The index id '" + idx.getName() + "' results to the column name '" + expectedFeatureName
							+ "', which should not exceed " + maxIndexNameLength
							+ " characters. Please rename this index according to the OS.bee naming conventions: http://download.osbee.org/documentation/index.php/Entity_DSL", idx, OSBPEntityPackage.Literals.LINDEX__NAME);
				}
			}
			for (LEntitySuperIndex superidx : entity.getSuperIndex()) {
				// TODO check naming policy after super indexes fully implemented
				expectedFeatureName = PersistenceNamingUtils
						.camelCaseToUpperCase(entity.getName() + superidx.getName());
				if (superidx.getName() != null && !superidx.getName().isEmpty()
						&& expectedFeatureName.length() >= maxIndexNameLength) {
					warning("The super index id '" + superidx.getName() + "'  results to the column name '"
							+ expectedFeatureName + "', which should not exceed " + maxIndexNameLength
							+ " characters. Please rename this super index according to the OS.bee naming conventions: http://download.osbee.org/documentation/index.php/Entity_DSL", superidx,
							OSBPEntityPackage.Literals.LENTITY_SUPER_INDEX__NAME);
				}
			}
		}
	}
}
