/*******************************************************************************
 * Copyright (c) 2006, 2013 Oracle and/or its affiliates. All rights reserved.
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
 * which accompanies this distribution.
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
 * and the Eclipse Distribution License is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * Contributors:
 *     Oracle - initial API and implementation
 *
 ******************************************************************************/
package org.eclipse.persistence.tools.mapping.orm.dom;

import java.util.ArrayList;
import java.util.List;
import javax.persistence.InheritanceType;
import org.eclipse.persistence.tools.mapping.orm.ExternalAssociationOverride;
import org.eclipse.persistence.tools.mapping.orm.ExternalAttributeOverride;
import org.eclipse.persistence.tools.mapping.orm.ExternalBasicNamedQuery;
import org.eclipse.persistence.tools.mapping.orm.ExternalDiscriminatorColumn;
import org.eclipse.persistence.tools.mapping.orm.ExternalEmbeddable;
import org.eclipse.persistence.tools.mapping.orm.ExternalEntity;
import org.eclipse.persistence.tools.mapping.orm.ExternalEntityTable;
import org.eclipse.persistence.tools.mapping.orm.ExternalNamedQuery;
import org.eclipse.persistence.tools.mapping.orm.ExternalNativeQuery;
import org.eclipse.persistence.tools.mapping.orm.ExternalPrimaryKeyJoinColumn;
import org.eclipse.persistence.tools.mapping.orm.ExternalSecondaryTable;
import org.eclipse.persistence.tools.mapping.orm.ExternalSQLResultSetMapping;
import org.eclipse.persistence.tools.mapping.orm.ExternalStoredProcedureQuery;
import org.eclipse.persistence.tools.utility.ObjectTools;
import org.eclipse.persistence.tools.utility.TextRange;
import org.w3c.dom.Element;

/**
 * The external form of an entity, which is a child of an ORM configuration.
 *
 * @see ORMConfiguration
 *
 * @version 2.6
 */
final class Entity extends MappedSuperClassEntity
                   implements ExternalEntity {

	/**
	 * Creates a new <code>Entity</code>.
	 *
	 * @param parent The parent of this external form
	 * @param index The position of the element within the list of children with the same type owned by the parent
	 */
	Entity(ORMConfiguration parent, int index) {
		super(parent, index);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalAssociationOverride addAssociationOverride(String name) {
		AssociationOverride associationOverride = buildAssociationOverride(-1);
		associationOverride.addSelf();
		associationOverride.setName(name);
		return associationOverride;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalAttributeOverride addAttributeOverride(String name) {
		AttributeOverride attributeOverride = buildAttributeOverride(-1);
		attributeOverride.addSelf();
		attributeOverride.setName(name);
		return attributeOverride;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalDiscriminatorColumn addDiscriminatorColumn(String columnName) {

		DiscriminatorColumn column = getDiscriminatorColumn();

		if (column == null) {
			column = buildDiscriminatorColumn();
			column.addSelf();
		}

		column.setName(columnName);
		return column;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalNamedQuery addNamedQuery(String name) {
		NamedQuery namedQuery = buildNamedQuery(-1);
		namedQuery.addSelf();
		namedQuery.setName(name);
		return namedQuery;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalNativeQuery addNativeQuery(String name) {
		NamedNativeQuery namedNativeQuery = buildNamedNativeQuery(-1);
		namedNativeQuery.addSelf();
		namedNativeQuery.setName(name);
		return namedNativeQuery;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalPrimaryKeyJoinColumn addPrimaryKeyJoinColumn(String name) {
		PrimaryKeyJoinColumn pkJoinColumn = buildPrimaryKeyJoinColumn(-1);
		pkJoinColumn.addSelf();
		pkJoinColumn.setName(name);
		return pkJoinColumn;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalEntityTable addPrimaryTable(String tableName) {
		PrimaryTable primaryTable = buildPrimaryTable();
		primaryTable.addSelf();
		primaryTable.setName(tableName);
		return primaryTable;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalSecondaryTable addSecondaryTable(String name, String catalog, String schema) {
		SecondaryTable secondaryTable = buildSecondaryTable(-1);
		secondaryTable.addSelf();
		secondaryTable.setName(name);
		secondaryTable.setCatalogName(catalog);
		secondaryTable.setSchemaName(schema);
		return secondaryTable;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalSQLResultSetMapping addSqlResultSetMapping(String name) {
		SQLResultSetMapping sqlResultSetMapping = buildSqlResultSetMapping(-1);
		sqlResultSetMapping.addSelf();
		sqlResultSetMapping.setName(name);
		return sqlResultSetMapping;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalStoredProcedureQuery addStoredProcedureQuery(String name, String procedureName) {
		NamedStoredProcedureQuery storedProcedureQuery = buildStoredProcedureQuery(-1);
		storedProcedureQuery.addSelf();
		storedProcedureQuery.setName(name);
		storedProcedureQuery.setProcedureName(procedureName);
		return storedProcedureQuery;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public List<ExternalAssociationOverride> associationOverrides() {

		int count = associationOverridesSize();
		List<ExternalAssociationOverride> associationOverrides = new ArrayList<ExternalAssociationOverride>(count);

		for (int index = 0; index < count; index++) {
			associationOverrides.add(buildAssociationOverride(index));
		}

		return associationOverrides;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public int associationOverridesSize() {
		return getChildrenSize(AttributeOverride.ATTRIBUTE_OVERRIDE);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public List<ExternalAttributeOverride> attributeOverrides() {

		int count = attributeOverridesSize();
		List<ExternalAttributeOverride> attributeOverrides = new ArrayList<ExternalAttributeOverride>(count);

		for (int index = 0; index < count; index++) {
			attributeOverrides.add(buildAttributeOverride(index));
		}

		return attributeOverrides;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public int attributeOverridesSize() {
		return getChildrenSize(AssociationOverride.ASSOCIATION_OVERRIDE);
	}

	private AssociationOverride buildAssociationOverride(int index) {
		return new AssociationOverride(this, index);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	protected List<String> buildAttributeNamesOrder() {
		List<String> names = new ArrayList<String>();
		names.add(NAME);
		names.add(ExternalEmbeddable.CLASS);
		names.add(PARENT_CLASS);
		names.add(ACCESS);
		names.add(CACHEABLE);
		names.add(METADATA_COMPLETE);
		names.add(READ_ONLY);
		names.add(EXISTENCE_CHECKING);
		names.add(EXCLUDE_DEFAULT_MAPPINGS);
		return names;
	}

	private AttributeOverride buildAttributeOverride(int index) {
		return new AttributeOverride(this, index);
	}

	private DiscriminatorColumn buildDiscriminatorColumn() {
		return new DiscriminatorColumn(this);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	protected List<String> buildElementNamesOrder() {
		List<String> names = new ArrayList<String>();
		names.add(ExternalEmbeddable.DESCRIPTION);
		names.add(CUSTOMIZER);
		names.add(CHANGE_TRACKING);
		names.add(PrimaryTable.TABLE);
		names.add(SecondaryTable.SECONDARY_TABLE);
		names.add(PrimaryKeyJoinColumn.PRIMARY_KEY_JOIN_COLUMN);
		names.add(NoSql.NO_SQL);
		names.add(ID_CLASS);
		names.add(PrimaryKey.PRIMARY_KEY);
		names.add(INHERITANCE);
		names.add(DISCRIMINATOR_VALUE);
		names.add(DiscriminatorColumn.DISCRIMINATOR_COLUMN);
		names.add(CLASS_EXTRACTOR);
		names.add(OptimisticLocking.OPTIMISTIC_LOCKING);
		names.add(Cache.CACHE);
		names.add(Converter.CONVERTER);
		names.add(TypeConverter.TYPE_CONVERTER);
		names.add(ObjectTypeConverter.OBJECT_TYPE_CONVERTER);
		names.add(StructConverter.STRUCT_CONVERTER);
		names.add(CopyPolicy.COPY_POLICY);
		names.add(InstantiationCopyPolicy.INSTANTIATION_COPY_POLICY);
		names.add(CloneCopyPolicy.CLONE_COPY_POLICY);
		names.add(SequenceGenerator.SEQUENCE_GENERATOR);
		names.add(TableGenerator.TABLE_GENERATOR);
		names.add(NamedQuery.NAMED_QUERY);
		names.add(NamedNativeQuery.NAMED_NATIVE_QUERY);
		names.add(NamedStoredProcedureQuery.NAMED_STORED_PROCEDURE_QUERY);
		names.add(SQLResultSetMapping.SQL_RESULT_SET_MAPPING);
		names.add(EXCLUDE_DEFAULT_LISTENERS);
		names.add(EXCLUDE_SUPERCLASS_LISTENERS);
		names.add(EntityListener.ENTITY_LISTENERS);
		names.add(PRE_PERSIST);
		names.add(POST_PERSIST);
		names.add(PRE_REMOVE);
		names.add(POST_REMOVE);
		names.add(PRE_UPDATE);
		names.add(POST_UPDATE);
		names.add(POST_LOAD);
		names.add(Property.PROPERTY);
		names.add(AttributeOverride.ATTRIBUTE_OVERRIDE);
		names.add(AssociationOverride.ASSOCIATION_OVERRIDE);
		names.add(Mapping.ATTRIBUTES);
		return names;
	}

	private NamedNativeQuery buildNamedNativeQuery(int index) {
		return new NamedNativeQuery(this, index);
	}

	private NamedQuery buildNamedQuery(int index) {
		return new NamedQuery(this, index);
	}

	private PrimaryKeyJoinColumn buildPrimaryKeyJoinColumn(int index) {
		return new PrimaryKeyJoinColumn(this, index);
	}

	private PrimaryTable buildPrimaryTable() {
		return new PrimaryTable(this);
	}

	private SecondaryTable buildSecondaryTable(int index) {
		return new SecondaryTable(this, index);
	}

	private SQLResultSetMapping buildSqlResultSetMapping(int index) {
		return new SQLResultSetMapping(this, index);
	}

	private NamedStoredProcedureQuery buildStoredProcedureQuery(int index) {
		return new NamedStoredProcedureQuery(this, index);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalAssociationOverride getAssociationOverride(int index) {

		Element element = getChild(AssociationOverride.ASSOCIATION_OVERRIDE, index);

		if (element != null) {
			return buildAssociationOverride(index);
		}

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalAttributeOverride getAttributeOverride(int index) {

		Element element = getChild(AttributeOverride.ATTRIBUTE_OVERRIDE, index);

		if (element != null) {
			return buildAttributeOverride(index);
		}

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public String getClassExtractorClassName() {
		return getChildAttribute(CLASS_EXTRACTOR, ExternalEmbeddable.CLASS);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public TextRange getClassExtractorClassNameTextRange() {
		return getChildAttributeTextRange(CLASS_EXTRACTOR, ExternalEmbeddable.CLASS);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public DiscriminatorColumn getDiscriminatorColumn() {

		if (hasChild(DiscriminatorColumn.DISCRIMINATOR_COLUMN)) {
			return buildDiscriminatorColumn();
		}

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public String getDiscriminatorValue() {
		return getChildTextNode(DISCRIMINATOR_VALUE);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public TextRange getDiscriminatorValueTextRange() {
		return getChildTextNodeTextRange(DISCRIMINATOR_VALUE);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	protected String getElementName() {
		return ENTITY;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public InheritanceType getInheritenceStrategy() {

		Element element = getChild(INHERITANCE);

		if (element != null) {
			return getEnumAttribute(element, STRATEGY, InheritanceType.class);
		}

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public TextRange getInheritenceStrategyTextRange() {
		return getChildAttributeTextRange(INHERITANCE, STRATEGY);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public String getName() {
		return getAttribute(NAME);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalBasicNamedQuery getNamedQuery(int index) {

		if (hasChild(NamedQuery.NAMED_QUERY, index)) {
			return buildNamedQuery(index);
		}

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalBasicNamedQuery getNamedQuery(int index, String name) {

		ExternalBasicNamedQuery namedQuery = getNamedQuery(index);

		if (namedQuery == null) {
			return null;
		}

		if (ObjectTools.notEquals(name, namedQuery.getName())) {
			namedQuery = null;
		}

		return namedQuery;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public TextRange getNameTextRange() {
		return getAttributeTextRange(NAME);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalNativeQuery getNativeQuery(int index) {

		if (hasChild(NamedNativeQuery.NAMED_NATIVE_QUERY, index)) {
			return buildNamedNativeQuery(index);
		}

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalNativeQuery getNativeQuery(int index, String name) {

		ExternalNativeQuery nativeQuery = getNativeQuery(index);

		if (nativeQuery == null) {
			return null;
		}

		if (ObjectTools.notEquals(name, nativeQuery.getName())) {
			nativeQuery = null;
		}

		return nativeQuery;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalPrimaryKeyJoinColumn getPrimaryKeyJoinColumn(int index) {

		if (hasChild(PrimaryKeyJoinColumn.PRIMARY_KEY_JOIN_COLUMN, index)) {
			return buildPrimaryKeyJoinColumn(index);
		}

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalEntityTable getPrimaryTable() {

		if (hasChild(PrimaryTable.TABLE)) {
			return buildPrimaryTable();
		}

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalSecondaryTable getSecondaryTable(int index) {

		if (hasChild(SecondaryTable.SECONDARY_TABLE)) {
			return buildSecondaryTable(index);
		}

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalSQLResultSetMapping getSqlResultSetMapping(int index) {

		if (hasChild(SQLResultSetMapping.SQL_RESULT_SET_MAPPING, index)) {
			return buildSqlResultSetMapping(index);
		}

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalStoredProcedureQuery getStoredProcedureQuery(int index) {

		if (hasChild(NamedStoredProcedureQuery.NAMED_STORED_PROCEDURE_QUERY, index)) {
			return buildStoredProcedureQuery(index);
		}

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalStoredProcedureQuery getStoredProcedureQuery(int index, String name) {

		ExternalStoredProcedureQuery storedProcedureQuery = getStoredProcedureQuery(index);

		if (storedProcedureQuery == null) {
			return null;
		}

		if (ObjectTools.notEquals(name, storedProcedureQuery.getName())) {
			storedProcedureQuery = null;
		}

		return storedProcedureQuery;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public List<ExternalNamedQuery> namedQueries() {

		int count = namedQueriesSize();
		List<ExternalNamedQuery> namedQueries = new ArrayList<ExternalNamedQuery>(count);

		for (int index = 0; index < count; index++) {
			namedQueries.add(buildNamedQuery(index));
		}

		return namedQueries;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public int namedQueriesSize() {
		return getChildrenSize(NamedQuery.NAMED_QUERY);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public List<ExternalNativeQuery> nativeQueries() {

		int count = nativeQueriesSize();
		List<ExternalNativeQuery> nativeQueries = new ArrayList<ExternalNativeQuery>(count);

		for (int index = 0; index < count; index++) {
			nativeQueries.add(buildNamedNativeQuery(index));
		}

		return nativeQueries;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public int nativeQueriesSize() {
		return getChildrenSize(NamedNativeQuery.NAMED_NATIVE_QUERY);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public List<ExternalPrimaryKeyJoinColumn> primaryKeyJoinColumns() {

		int count = primaryKeyJoinColumnsSize();
		List<ExternalPrimaryKeyJoinColumn> pkJoinColumns = new ArrayList<ExternalPrimaryKeyJoinColumn>(count);

		for (int index = 0; index < count; index++) {
			pkJoinColumns.add(buildPrimaryKeyJoinColumn(index));
		}

		return pkJoinColumns;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public int primaryKeyJoinColumnsSize() {
		return getChildrenSize(PrimaryKeyJoinColumn.PRIMARY_KEY_JOIN_COLUMN);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void removeAssociationOverride(int index) {
		AssociationOverride associationOverride = buildAssociationOverride(index);
		associationOverride.removeSelf();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void removeAttributeOverride(int index) {
		AttributeOverride attributeOverride = buildAttributeOverride(index);
		attributeOverride.removeSelf();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void removeNamedQuery(int index) {
		NamedQuery namedQuery = buildNamedQuery(index);
		namedQuery.removeSelf();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void removeNativeQuery(int index) {
		NamedNativeQuery namedNativeQuery = buildNamedNativeQuery(index);
		namedNativeQuery.removeSelf();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void removePrimaryKeyJoinColumn(int index) {
		PrimaryKeyJoinColumn pkJoinColumn = buildPrimaryKeyJoinColumn(index);
		pkJoinColumn.removeSelf();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void removePrimaryTable() {
		PrimaryTable primaryTable = buildPrimaryTable();
		primaryTable.removeSelf();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void removeSecondaryTable(int index) {
		SecondaryTable secondaryTable = buildSecondaryTable(index);
		secondaryTable.removeSelf();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void removeSqlResultSetMapping(int index) {
		SQLResultSetMapping sqlResultSetMapping = buildSqlResultSetMapping(index);
		sqlResultSetMapping.removeSelf();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void removeStoredProcedureQuery(int index) {
		NamedStoredProcedureQuery storedProcedureQuery = buildStoredProcedureQuery(index);
		storedProcedureQuery.removeSelf();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public List<ExternalSecondaryTable> secondaryTables() {

		int count = secondaryTablesSize();
		List<ExternalSecondaryTable> secondaryTables = new ArrayList<ExternalSecondaryTable>(count);

		for (int index = 0; index < count; index++) {
			secondaryTables.add(buildSecondaryTable(index));
		}

		return secondaryTables;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public int secondaryTablesSize() {
		return getChildrenSize(SecondaryTable.SECONDARY_TABLE);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setClassExtractorClassName(String className) {
		updateChildAttribute(CLASS_EXTRACTOR, ExternalEmbeddable.CLASS, className);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setDiscriminatorValue(String discriminatorValue) {
		updateChildTextNode(DISCRIMINATOR_VALUE, discriminatorValue);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setInheritanceStrategy(InheritanceType value) {
		updateChildAttribute(INHERITANCE, STRATEGY, value);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setName(String name) {
		setAttribute(NAME, name);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public List<ExternalSQLResultSetMapping> sqlResultSetMappings() {

		int count = sqlResultSetMappingsSize();
		List<ExternalSQLResultSetMapping> sqlResultSetMappings = new ArrayList<ExternalSQLResultSetMapping>(count);

		for (int index = 0; index < count; index++) {
			sqlResultSetMappings.add(buildSqlResultSetMapping(index));
		}

		return sqlResultSetMappings;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public int sqlResultSetMappingsSize() {
		return getChildrenSize(SQLResultSetMapping.SQL_RESULT_SET_MAPPING);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public List<ExternalStoredProcedureQuery> storedProcedureQueries() {

		int count = storedProcedureQueriesSize();
		List<ExternalStoredProcedureQuery> storedProcedureQueries = new ArrayList<ExternalStoredProcedureQuery>(count);

		for (int index = 0; index < count; index++) {
			storedProcedureQueries.add(buildStoredProcedureQuery(index));
		}

		return storedProcedureQueries;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public int storedProcedureQueriesSize() {
		return getChildrenSize(NamedStoredProcedureQuery.NAMED_STORED_PROCEDURE_QUERY);
	}
}