/*******************************************************************************
 * 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.Collections;
import java.util.List;
import org.eclipse.persistence.annotations.ChangeTrackingType;
import org.eclipse.persistence.tools.mapping.AbstractExternalForm;
import org.eclipse.persistence.tools.mapping.ExternalProperty;
import org.eclipse.persistence.tools.mapping.orm.AccessType;
import org.eclipse.persistence.tools.mapping.orm.ExternalAccessMethods;
import org.eclipse.persistence.tools.mapping.orm.ExternalAssociationOverride;
import org.eclipse.persistence.tools.mapping.orm.ExternalAttributeOverride;
import org.eclipse.persistence.tools.mapping.orm.ExternalBasicCollectionMapping;
import org.eclipse.persistence.tools.mapping.orm.ExternalBasicMapMapping;
import org.eclipse.persistence.tools.mapping.orm.ExternalBasicMapping;
import org.eclipse.persistence.tools.mapping.orm.ExternalClassConverter;
import org.eclipse.persistence.tools.mapping.orm.ExternalCloneCopyPolicy;
import org.eclipse.persistence.tools.mapping.orm.ExternalCopyPolicy;
import org.eclipse.persistence.tools.mapping.orm.ExternalElementCollectionMapping;
import org.eclipse.persistence.tools.mapping.orm.ExternalEmbeddable;
import org.eclipse.persistence.tools.mapping.orm.ExternalEmbeddedMapping;
import org.eclipse.persistence.tools.mapping.orm.ExternalIDMapping;
import org.eclipse.persistence.tools.mapping.orm.ExternalInstantiationCopyPolicy;
import org.eclipse.persistence.tools.mapping.orm.ExternalManyToManyMapping;
import org.eclipse.persistence.tools.mapping.orm.ExternalManyToOneMapping;
import org.eclipse.persistence.tools.mapping.orm.ExternalMapping;
import org.eclipse.persistence.tools.mapping.orm.ExternalNoSql;
import org.eclipse.persistence.tools.mapping.orm.ExternalObjectTypeConverter;
import org.eclipse.persistence.tools.mapping.orm.ExternalOneToManyMapping;
import org.eclipse.persistence.tools.mapping.orm.ExternalOneToOneMapping;
import org.eclipse.persistence.tools.mapping.orm.ExternalStructConverter;
import org.eclipse.persistence.tools.mapping.orm.ExternalTransientMapping;
import org.eclipse.persistence.tools.mapping.orm.ExternalTypeConverter;
import org.eclipse.persistence.tools.utility.NameTools;
import org.eclipse.persistence.tools.utility.ObjectTools;
import org.eclipse.persistence.tools.utility.TextRange;
import org.w3c.dom.Element;

/**
 * The external form of an embeddable entity, which is a child of an ORM configuration.
 *
 * @see ORMConfiguration
 *
 * @version 2.6
 */
@SuppressWarnings("nls")
class Embeddable extends AbstractExternalForm
                 implements ExternalEmbeddable {

	/**
	 * The position of the element within the list of children with the same type owned by the parent.
	 */
	private int index;

	/**
	 * The order of the mapping element names in the attributes element.
	 */
	private List<String> mappingElementNamesOrder;

	/**
	 * Creates a new <code>Embeddable</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
	 */
	Embeddable(ORMConfiguration parent, int index) {
		super(parent);
		this.index = index;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalAccessMethods addAccessMethods(String getMethodName, String setMethodName) {
		AccessMethods accessMethods = buildAccessMethods();
		accessMethods.addSelf();
		accessMethods.setGetMethod(getMethodName);
		accessMethods.setSetMethod(setMethodName);
		return accessMethods;
	}

	/**
	 * {@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 final ExternalBasicCollectionMapping addBasicCollectionMapping(String name) {
		BasicCollectionMapping mapping = buildBasicCollectionMapping();
		mapping.addSelf();
		mapping.setName(name);
		return mapping;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalBasicMapMapping addBasicMapMapping(String name) {
		BasicMapMapping mapping = buildBasicMapMapping();
		mapping.addSelf();
		mapping.setName(name);
		return mapping;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalBasicMapping addBasicMapping(String name) {
		BasicMapping mapping = buildBasicMapping();
		mapping.addSelf();
		mapping.setName(name);
		return mapping;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalCloneCopyPolicy addCloneCopyPolicy() {
		CloneCopyPolicy cloneCopyPolicy = buildCloneCopyPolicy();
		cloneCopyPolicy.addSelf();
		return cloneCopyPolicy;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalClassConverter addConverter() {
		ClassConverter converter = buildConverter(-1);
		converter.addSelf();
		return converter;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalCopyPolicy addCopyPolicy() {
		CopyPolicy copyPolicy = buildCopyPolicy();
		copyPolicy.addSelf();
		return copyPolicy;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalElementCollectionMapping addElementCollectionMapping(String name) {
		ElementCollectionMapping mapping = buildElementCollectionMapping();
		mapping.addSelf();
		mapping.setName(name);
		return mapping;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalEmbeddedMapping addEmbeddedMapping(String name) {
		EmbeddedMapping mapping = buildEmbeddedMapping();
		mapping.addSelf();
		mapping.setName(name);
		return mapping;
	}

	/**
	 * Embeddables don't currently support ID, but the implementation is here for convenience.
	 *
	 * {@inheritDoc}
	 */
	@Override
	public ExternalIDMapping addIdMapping(String name) {
		throw new UnsupportedOperationException("An ID mapping is not supported on an embeddable.");
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalInstantiationCopyPolicy addInstantiationCopyPolicy() {
		InstantiationCopyPolicy instantiationCopyPolicy = buildInstantiationCopyPolicy();
		instantiationCopyPolicy.addSelf();
		return instantiationCopyPolicy;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalManyToManyMapping addManyToManyMapping(String name) {
		ManyToManyMapping mapping = buildManyToManyMapping();
		mapping.addSelf();
		mapping.setName(name);
		return mapping;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalManyToOneMapping addManyToOneMapping(String name) {
		ManyToOneMapping mapping = buildManyToOneMapping();
		mapping.addSelf();
		mapping.setName(name);
		return mapping;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalNoSql addNoSql() {
		NoSql noSql = buildNoSql();
		noSql.addSelf();
		return noSql;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalObjectTypeConverter addObjectTypeConverter() {
		ObjectTypeConverter converter = buildObjectTypeConverter(-1);
		converter.addSelf();
		return converter;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalOneToManyMapping addOneToManyMapping(String name) {
		OneToManyMapping mapping = buildOneToManyMapping();
		mapping.addSelf();
		mapping.setName(name);
		return mapping;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalOneToOneMapping addOneToOneMapping(String name) {
		OneToOneMapping mapping = buildOneToOneMapping();
		mapping.addSelf();
		mapping.setName(name);
		return mapping;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalProperty addProperty(String name, String value) {
		Property property = buildProperty(-1);
		property.addSelf();
		property.setName(name);
		property.setValue(value);
		return property;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalStructConverter addStructConverter() {
		StructConverter converter = buildStructConverter(-1);
		converter.addSelf();
		return converter;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalTransientMapping addTransientMapping(String name) {
		TransientMapping mapping = buildTransientMapping();
		mapping.addSelf();
		mapping.setName(name);
		return mapping;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalTypeConverter addTypeConverter() {
		TypeConverter converter = buildTypeConverter(-1);
		converter.addSelf();
		return converter;
	}

	/**
	 * {@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(AssociationOverride.ASSOCIATION_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(AttributeOverride.ATTRIBUTE_OVERRIDE);
	}

	private AccessMethods buildAccessMethods() {
		return new AccessMethods(this);
	}

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

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

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

	private BasicCollectionMapping buildBasicCollectionMapping() {
		return new BasicCollectionMapping(this);
	}

	private BasicMapMapping buildBasicMapMapping() {
		return new BasicMapMapping(this);
	}

	private BasicMapping buildBasicMapping() {
		return new BasicMapping(this);
	}

	private CloneCopyPolicy buildCloneCopyPolicy() {
		return new CloneCopyPolicy(this);
	}

	private ClassConverter buildConverter(int index) {
		return new ClassConverter(this, index);
	}

	private CopyPolicy buildCopyPolicy() {
		return new CopyPolicy(this);
	}

	private ElementCollectionMapping buildElementCollectionMapping() {
		return new ElementCollectionMapping(this);
	}


	/**
	 * {@inheritDoc}
	 */
	@Override
	protected List<String> buildElementNamesOrder() {

		List<String> names = new ArrayList<String>();
		names.add(DESCRIPTION);
		names.add(AccessMethods.ACCESS_METHODS);
		names.add(CUSTOMIZER);
		names.add(CHANGE_TRACKING);
		names.add("struct");
		names.add(NoSql.NO_SQL);
		names.add(ClassConverter.CONVERTER);
		names.add(TypeConverter.TYPE_CONVERTER);
		names.add(ObjectTypeConverter.OBJECT_TYPE_CONVERTER);
		names.add("serialized-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("oracle-object");
		names.add("oracle-array");
		names.add("plsql-record");
		names.add("plsql-table");
		names.add(Property.PROPERTY);
		names.add(ExternalAttributeOverride.ATTRIBUTE_OVERRIDE);
		names.add(ExternalAssociationOverride.ASSOCIATION_OVERRIDE);
		names.add(Mapping.ATTRIBUTES);
		return names;
	}

	private EmbeddedMapping buildEmbeddedMapping() {
		return new EmbeddedMapping(this);
	}

	private InstantiationCopyPolicy buildInstantiationCopyPolicy() {
		return new InstantiationCopyPolicy(this);
	}

	private ManyToManyMapping buildManyToManyMapping() {
		return new ManyToManyMapping(this);
	}

	private ManyToOneMapping buildManyToOneMapping() {
		return new ManyToOneMapping(this);
	}

	Mapping buildMapping(String elementName) {

		// Basic
		if (ObjectTools.equals(elementName, BasicMapping.BASIC)) {
			return buildBasicMapping();
		}

		// Basic Collection
		if (ObjectTools.equals(elementName, BasicCollectionMapping.BASIC_COLLECTION)) {
			return buildBasicCollectionMapping();
		}

		// Basic Map
		if (ObjectTools.equals(elementName, BasicMapMapping.BASIC_MAP)) {
			return buildBasicMapMapping();
		}

		// Embedded
		if (ObjectTools.equals(elementName, EmbeddedMapping.EMBEDDED)) {
			return buildEmbeddedMapping();
		}

		// Element Collection
		if (ObjectTools.equals(elementName, ElementCollectionMapping.ELEMENT_COLLECTION)) {
			return buildElementCollectionMapping();
		}

		// M:M
		if (ObjectTools.equals(elementName, ManyToManyMapping.MANY_TO_MANY)) {
			return buildManyToManyMapping();
		}

		// M:1
		if (ObjectTools.equals(elementName, ManyToOneMapping.MANY_TO_ONE)) {
			return buildManyToOneMapping();
		}

		// 1:M
		if (ObjectTools.equals(elementName, OneToManyMapping.ONE_TO_MANY)) {
			return buildOneToManyMapping();
		}

		// 1:1
		if (ObjectTools.equals(elementName, OneToOneMapping.ONE_TO_ONE)) {
			return buildOneToOneMapping();
		}

		// Transient
		if (ObjectTools.equals(elementName, TransientMapping.TRANSIENT)) {
			return buildTransientMapping();
		}

		return null;
	}

	/**
	 * Creates a collection of element names for the supported mappings.
	 *
	 * @return The mapping names
	 */
	final List<String> buildMappingElementNamesOrder() {

		List<String> names = new ArrayList<String>();
		names.add(DESCRIPTION);
		names.add(IdMapping.ID);
		names.add(EmbeddedIDMapping.EMBEDDED_ID);
		names.add(BasicMapping.BASIC);
		names.add(BasicCollectionMapping.BASIC_COLLECTION);
		names.add(BasicMapMapping.BASIC_MAP);
		names.add(VersionMapping.VERSION);
		names.add(ManyToOneMapping.MANY_TO_ONE);
		names.add(OneToManyMapping.ONE_TO_MANY);
		names.add(OneToOneMapping.ONE_TO_ONE);
		names.add(VariableOneToOneMapping.VARIABLE_ONE_TO_ONE);
		names.add(ManyToManyMapping.MANY_TO_MANY);
		names.add(ElementCollectionMapping.ELEMENT_COLLECTION);
		names.add(EmbeddedMapping.EMBEDDED);
		names.add(TransformationMapping.TRANSFORMATION);
		names.add(TransientMapping.TRANSIENT);
		names.add("structure");
		names.add("array");
		return names;
	}

	private List<ExternalMapping> buildMappings(Element element) {

		List<ExternalMapping> mappings = new ArrayList<ExternalMapping>();

		for (Element childElement : getChildren(element)) {

			String elementName = getNodeName(childElement);
			Mapping mapping = buildMapping(elementName);

			if (mapping != null) {
				mapping.calculateInsertionIndex(element, childElement, elementName);
				mappings.add(mapping);
			}
		}

		return mappings;
	}

	private NoSql buildNoSql() {
		return new NoSql(this);
	}

	private ObjectTypeConverter buildObjectTypeConverter(int index) {
		return new ObjectTypeConverter(this, index);
	}

	private OneToManyMapping buildOneToManyMapping() {
		return new OneToManyMapping(this);
	}

	private OneToOneMapping buildOneToOneMapping() {
		return new OneToOneMapping(this);
	}

	private Property buildProperty(int index) {
		return new Property(this, index);
	}

	private StructConverter buildStructConverter(int index) {
		return new StructConverter(this, index);
	}

	private TransientMapping buildTransientMapping() {
		return new TransientMapping(this);
	}

	private TypeConverter buildTypeConverter(int index) {
		return new TypeConverter(this, index);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	protected void calculateInsertionIndex(Element parent, Element child, String elementName) {
		if (elementName == getElementName()) {
			index = index(parent, child, elementName);
		}
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final List<ExternalClassConverter> converters() {

		int count = convertersSize();
		List<ExternalClassConverter> converters = new ArrayList<ExternalClassConverter>(count);

		for (int index = 0; index < count; index++) {
			converters.add(buildConverter(index));
		}

		return converters;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final int convertersSize() {
		return getChildrenSize(ClassConverter.CONVERTER);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalAccessMethods getAccessMethods() {

		if (hasChild(AccessMethods.ACCESS_METHODS)) {
			return buildAccessMethods();
		}

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final AccessType getAccessType() {
		return getEnumAttribute(ACCESS, AccessType.class);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final TextRange getAccessTypeTextRange() {
		return getAttributeTextRange(ACCESS);
	}

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

		if (hasChild(AssociationOverride.ASSOCIATION_OVERRIDE, index)) {
			return buildAssociationOverride(index);
		}

		return null;
	}

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

		if (hasChild(AttributeOverride.ATTRIBUTE_OVERRIDE, index)) {
			return buildAttributeOverride(index);
		}

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ChangeTrackingType getChangeTrackingType() {
		return getChildEnumAttribute(CHANGE_TRACKING, TYPE, ChangeTrackingType.class);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final TextRange getChangeTrackingTypeTextRange() {
		return getChildAttributeTextRange(CHANGE_TRACKING, TYPE);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final String getClassName() {
		return getAttribute(CLASS);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final TextRange getClassNameTextRange() {
		return getAttributeTextRange(CLASS);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final String getClassShortName() {
		return NameTools.shortNameForClassNamed(getClassName());
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalCloneCopyPolicy getCloneCopyPolicy() {

		if (hasChild(CloneCopyPolicy.CLONE_COPY_POLICY)) {
			return buildCloneCopyPolicy();
		}

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalClassConverter getConverter(int index) {

		if (hasChild(ClassConverter.CONVERTER, index)) {
			return buildConverter(index);
		}

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalCopyPolicy getCopyPolicy() {

		if (hasChild(CopyPolicy.COPY_POLICY)) {
			return buildCopyPolicy();
		}

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final String getCustomizerClassName() {
		return getChildAttribute(CUSTOMIZER, CLASS);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final TextRange getCustomizerClassNameTextRange() {
		return getChildAttributeTextRange(CUSTOMIZER, CLASS);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final String getDescription() {
		return getChildTextNode(DESCRIPTION);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final TextRange getDescriptionTextRange() {
		return getChildTextNodeTextRange(DESCRIPTION);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final Element getElement() {
		return getChild(getParent(), getElementName(), index);
	}

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

	/**
	 * {@inheritDoc}
	 */
	@Override
	public TextRange getExcludeDefaultMappingsTextRange() {
		return getAttributeTextRange(EXCLUDE_DEFAULT_MAPPINGS);
	}

	@Override
	@Deprecated
	public int getIndex() {
		return index;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalInstantiationCopyPolicy getInstantiationCopyPolicy() {

		if (hasChild(InstantiationCopyPolicy.INSTANTIATION_COPY_POLICY)) {
			return buildInstantiationCopyPolicy();
		}

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final Mapping getMapping(int index) {

		Element element = getChild(ExternalMapping.ATTRIBUTES);

		if (element != null) {
			Element childElement = getChild(element, index);

			if (childElement != null) {
				String elementName = getNodeName(childElement);

				Mapping mapping = buildMapping(elementName);
				mapping.calculateInsertionIndex(element, childElement, elementName);
				return mapping;
			}
		}

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalMapping getMapping(String name) {

		Element element = getChild(ExternalMapping.ATTRIBUTES);

		if (element != null) {

			for (Element mappingNode : getChildren(element)) {
				String mappingName = getAttribute(mappingNode, ExternalMapping.NAME);

				if (mappingName.equals(name)) {
					String elementName = getNodeName(mappingNode);
					Mapping mapping = buildMapping(elementName);
					mapping.calculateInsertionIndex(element, mappingNode, elementName);
					return mapping;
				}
			}
		}

		return null;
	}

	protected List<String> getMappingElementNamesOrder() {
		return mappingElementNamesOrder;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final TextRange getMetadataCompleteTextRange() {
		return getAttributeTextRange(METADATA_COMPLETE);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalNoSql getNoSql() {

		if (hasChild(NoSql.NO_SQL)) {
			return buildNoSql();
		}

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalObjectTypeConverter getObjectTypeConverter(int index) {

		if (hasChild(ObjectTypeConverter.OBJECT_TYPE_CONVERTER, index)) {
			return buildObjectTypeConverter(index);
		}

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final String getParentClassName() {
		return getAttribute(PARENT_CLASS);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public TextRange getParentClassNameTextRange() {
		return getAttributeTextRange(PARENT_CLASS);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final List<ExternalProperty> getProperties(String name) {

		List<ExternalProperty> properties = new ArrayList<ExternalProperty>();

		for (ExternalProperty property : properties()) {
			if (ObjectTools.equals(property.getName(), name)) {
				properties.add(property);
			}
		}

		return properties;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalProperty getProperty(int index) {

		if (hasChild(Property.PROPERTY, index)) {
			return buildProperty(index);
		}

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalProperty getProperty(String name) {

		for (ExternalProperty property : properties()) {
			if (ObjectTools.equals(property.getName(), name)) {
				return property;
			}
		}

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalProperty getProperty(String name, int index) {

		ExternalProperty property = getProperty(index);

		if ((property != null) && ObjectTools.equals(name, property.getName())) {
			return property;
		}

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalProperty getProperty(String name, String value) {

		for (ExternalProperty property : properties()) {

			if (ObjectTools.equals(property.getName(),  name) &&
			    ObjectTools.equals(property.getValue(), value)) {

				return property;
			}
		}

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final TextRange getPropertyNameTextRange(String name) {

		for (ExternalProperty property : properties()) {

			if (ObjectTools.equals(property.getName(), name)) {
				return property.getNameTextRange();
			}
		}

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final TextRange getPropertyTextRange(String name) {

		for (ExternalProperty property : properties()) {

			if (ObjectTools.equals(property.getName(), name)) {
				return property.getTextRange();
			}
		}

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final TextRange getPropertyTextRange(String name, String value) {

		for (ExternalProperty property : properties()) {

			if (ObjectTools.equals(property.getName(),  name) &&
			    ObjectTools.equals(property.getValue(), value)) {

				return property.getTextRange();
			}
		}

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final TextRange getPropertyValueTextRange(String name) {

		for (ExternalProperty property : properties()) {

			if (ObjectTools.equals(property.getName(), name)) {
				return property.getValueTextRange();
			}
		}

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalStructConverter getStructConverter(int index) {

		if (hasChild(StructConverter.STRUCT_CONVERTER, index)) {
			return buildStructConverter(index);
		}

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalTypeConverter getTypeConverter(int index) {

		if (hasChild(TypeConverter.TYPE_CONVERTER, index)) {
			return buildTypeConverter(index);
		}

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final boolean hasAccessMethods() {
		return hasChild(ExternalAccessMethods.ACCESS_METHODS);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final boolean hasCloneCopyPolicy() {
		return hasChild(ExternalCloneCopyPolicy.CLONE_COPY_POLICY);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final boolean hasCopyPolicy() {
		return hasChild(ExternalCopyPolicy.COPY_POLICY);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final boolean hasInstantiationCopyPolicy() {
		return hasChild(ExternalInstantiationCopyPolicy.INSTANTIATION_COPY_POLICY);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final boolean hasNoSql() {
		return hasChild(ExternalNoSql.NO_SQL);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final List<ExternalIDMapping> idMappings() {

		List<ExternalIDMapping> idMappings = new ArrayList<ExternalIDMapping>();

		// TODO: Use a filter
		for (ExternalMapping mapping : mappings()) {
			if (mapping instanceof ExternalIDMapping) {
				idMappings.add((ExternalIDMapping)mapping);
			}
		}

		return idMappings;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	protected void initialize() {
		super.initialize();
		mappingElementNamesOrder = buildMappingElementNamesOrder();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final Boolean isExcludeDefaultMappings() {
		return getBooleanAttribute(EXCLUDE_DEFAULT_MAPPINGS);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final Boolean isMetadataComplete() {
		return getBooleanAttribute(METADATA_COMPLETE);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final List<ExternalMapping> mappings() {

		Element element = getChild(Mapping.ATTRIBUTES);

		if (element != null) {
			return buildMappings(element);
		}

		return Collections.emptyList();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final int mappingsSize() {

		Element attributes = getChild(Mapping.ATTRIBUTES);

		if (attributes != null) {
			return getChildrenSize(attributes, getMappingElementNamesOrder());
		}

		return 0;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final List<ExternalObjectTypeConverter> objectTypeConverters() {

		int count = objectTypeConvertersSize();
		List<ExternalObjectTypeConverter> converters = new ArrayList<ExternalObjectTypeConverter>(count);

		for (int index = 0; index < count; index++) {
			converters.add(buildObjectTypeConverter(index));
		}

		return converters;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final int objectTypeConvertersSize() {
		return getChildrenSize(ObjectTypeConverter.OBJECT_TYPE_CONVERTER);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final List<ExternalProperty> properties() {

		int count = propertiesSize();
		List<ExternalProperty> properties = new ArrayList<ExternalProperty>(count);

		for (int index = 0; index < count; index++) {
			properties.add(buildProperty(index));
		}

		return properties;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final int propertiesSize() {
		return getChildrenSize(Property.PROPERTY);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final int propertiesSize(String name) {

		int count = 0;

		for (ExternalProperty property : properties()) {
			if (ObjectTools.equals(property.getName(), name)) {
				count++;
			}
		}

		return count;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void removeAccessMethods() {
		removeChild(AccessMethods.ACCESS_METHODS);
	}

	/**
	 * {@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 final void removeCloneCopyPolicy() {
		CloneCopyPolicy policy = buildCloneCopyPolicy();
		policy.removeSelf();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void removeConverter(int index) {
		ClassConverter converter = buildConverter(index);
		converter.removeSelf();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void removeCopyPolicy() {
		CopyPolicy policy = buildCopyPolicy();
		policy.removeSelf();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void removeInstantiationCopyPolicy() {
		InstantiationCopyPolicy policy = buildInstantiationCopyPolicy();
		policy.removeSelf();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void removeMapping(int index) {

		Mapping mapping = getMapping(index);

		if (mapping != null) {
			mapping.removeSelf();
		}
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void removeMapping(String name) {

		Element element = getChild(ExternalMapping.ATTRIBUTES);

		if (element != null) {

			for (Element mappingNode : getChildren(element)) {
				String mappingName = getAttribute(mappingNode, ExternalMapping.NAME);

				if (mappingName.equals(name)) {
					remove(element, mappingNode);
					break;
				}
			}
		}
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void removeNoSql() {
		NoSql noSql = buildNoSql();
		noSql.removeSelf();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void removeObjectTypeConverter(int index) {
		ObjectTypeConverter converter = buildObjectTypeConverter(index);
		converter.removeSelf();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void removeProperty(int index) {
		Property converter = buildProperty(index);
		converter.removeSelf();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void removeProperty(String name) {
		Property property = (Property) getProperty(name);
		property.removeSelf();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void removeProperty(String name, String value) {
		Property property = (Property) getProperty(name, value);
		property.removeSelf();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void removeSelf() {
		removeChild(getParent(), getElementName(), index);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void removeStructConverter(int index) {
		StructConverter converter = buildStructConverter(index);
		converter.removeSelf();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void removeTypeConverter(int index) {
		TypeConverter converter = buildTypeConverter(index);
		converter.removeSelf();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void setAccessType(AccessType type) {
		setAttribute(ACCESS, type);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void setChangeTrackingType(ChangeTrackingType type) {
		updateChildAttribute(CHANGE_TRACKING, TYPE, type);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void setClassName(String className) {
		setAttribute(CLASS, className);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void setCustomizerClassName(String name) {
		updateChildAttribute(CUSTOMIZER, CLASS, name);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void setDescription(String description) {
		updateChildTextNode(DESCRIPTION, description);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void setExcludeDefaultMappings(Boolean excludeDefaultMappings) {
		setAttribute(EXCLUDE_DEFAULT_MAPPINGS, excludeDefaultMappings);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void setMetadataComplete(Boolean metaDataComplete) {
		setAttribute(METADATA_COMPLETE, metaDataComplete);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void setParentClassName(String className) {
		setAttribute(PARENT_CLASS, className);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final List<ExternalStructConverter> structConverters() {

		int count = structConvertersSize();
		List<ExternalStructConverter> converters = new ArrayList<ExternalStructConverter>(count);

		for (int index = 0; index < count; index++) {
			converters.add(buildStructConverter(index));
		}

		return converters;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final int structConvertersSize() {
		return getChildrenSize(StructConverter.STRUCT_CONVERTER);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final List<ExternalTypeConverter> typeConverters() {

		int count = typeConvertersSize();
		List<ExternalTypeConverter> converters = new ArrayList<ExternalTypeConverter>(count);

		for (int index = 0; index < count; index++) {
			converters.add(buildTypeConverter(index));
		}

		return converters;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final int typeConvertersSize() {
		return getChildrenSize(TypeConverter.TYPE_CONVERTER);
	}
}