/*******************************************************************************
 * 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.io.ByteArrayOutputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.eclipse.persistence.tools.mapping.AbstractExternalForm;
import org.eclipse.persistence.tools.mapping.ExternalFormHelper;
import org.eclipse.persistence.tools.mapping.orm.AccessType;
import org.eclipse.persistence.tools.mapping.orm.ExternalBasicNamedQuery;
import org.eclipse.persistence.tools.mapping.orm.ExternalConverter;
import org.eclipse.persistence.tools.mapping.orm.ExternalEmbeddable;
import org.eclipse.persistence.tools.mapping.orm.ExternalEntity;
import org.eclipse.persistence.tools.mapping.orm.ExternalMappedSuperClass;
import org.eclipse.persistence.tools.mapping.orm.ExternalNamedQuery;
import org.eclipse.persistence.tools.mapping.orm.ExternalNativeQuery;
import org.eclipse.persistence.tools.mapping.orm.ExternalORMConfiguration;
import org.eclipse.persistence.tools.mapping.orm.ExternalObjectTypeConverter;
import org.eclipse.persistence.tools.mapping.orm.ExternalPersistenceUnit;
import org.eclipse.persistence.tools.mapping.orm.ExternalSQLResultSetMapping;
import org.eclipse.persistence.tools.mapping.orm.ExternalSequenceGenerator;
import org.eclipse.persistence.tools.mapping.orm.ExternalStoredProcedureQuery;
import org.eclipse.persistence.tools.mapping.orm.ExternalStructConverter;
import org.eclipse.persistence.tools.mapping.orm.ExternalTableGenerator;
import org.eclipse.persistence.tools.mapping.orm.ExternalTenantDiscriminatorColumn;
import org.eclipse.persistence.tools.mapping.orm.ExternalTypeConverter;
import org.eclipse.persistence.tools.mapping.orm.ORMDocumentType;
import org.eclipse.persistence.tools.utility.ObjectTools;
import org.eclipse.persistence.tools.utility.TextRange;
import org.w3c.dom.Element;
import static org.eclipse.persistence.tools.mapping.orm.XmlConstants.*;

/**
 * The external form interacting with the XML document for the ORM Configuration file.
 *
 * @version 2.6
 */
@SuppressWarnings("nls")
public final class ORMConfiguration extends AbstractExternalForm
                                    implements ExternalORMConfiguration {

	/**
	 * The helper is used when the document needs to be modified.
	 */
	private final ExternalFormHelper helper;

	/**
	 * Creates a new <code>ORMConfiguration</code>.
	 *
	 * @param helper The helper is used when the document needs to be modified
	 */
	public ORMConfiguration(ExternalFormHelper helper) {
		super(null);
		this.helper = helper;
	}

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

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalTenantDiscriminatorColumn addDiscriminatorColumn() {
		AbstractTenantDiscriminatorColumn column = buildDiscriminatorColumn(-1);
		column.addSelf();
		return column;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalEmbeddable addEmbeddable(String className) {
		Embeddable embeddable = buildEmbeddable(-1);
		embeddable.addSelf();
		embeddable.setClassName(className);
		return embeddable;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalEntity addEntity(String className) {
		Entity entity = buildEntity(-1);
		entity.addSelf();
		entity.setClassName(className);
		return entity;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalMappedSuperClass addMappedSuperClass(String className) {
		MappedSuperClassEntity mappedSuperclass = buildMappedSuperclass(-1);
		mappedSuperclass.addSelf();
		mappedSuperclass.setClassName(className);
		return mappedSuperclass;
	}

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

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

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

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalPersistenceUnit addPersistenceUnitMetaData() {
		PersistenceUnit persistenceUnit = buildPersistenceUnit();
		persistenceUnit.addSelf();
		return persistenceUnit;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	protected Element addSelf(String elementName) {
		return addSelf(elementName, Collections.<String>emptyList());
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public Element addSelf(String elementName, List<String> elementNamesOrder) {
		return helper.buildORMConfiguration(this);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalSequenceGenerator addSequenceGenerator(String name) {
		SequenceGenerator sequenceGenerator = buildSequenceGenerator(-1);
		sequenceGenerator.addSelf();
		sequenceGenerator.setName(name);
		return sequenceGenerator;
	}

	/**
	 * {@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 query = buildStoredProcedureQuery(-1);
		query.addSelf();
		query.setName(name);
		query.setProcedureName(procedureName);
		return query;
	}

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

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalTableGenerator addTableGenerator(String name) {
		TableGenerator generator = buildTableGenerator(-1);
		generator.addSelf();
		generator.setName(name);
		return generator;
	}

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

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

	private TenantDiscriminatorColumn buildDiscriminatorColumn(int index) {
		return new TenantDiscriminatorColumn(this, index);
	}

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

		List<String> names = new ArrayList<String>();
		names.add(DESCRIPTION);
		names.add(PersistenceUnit.PERSISTENCE_UNIT_METADATA);
		names.add(PACKAGE);
		names.add(SCHEMA);
		names.add(CATALOG);
		names.add(ACCESS);
		names.add(Converter.CONVERTER);
		names.add(TypeConverter.TYPE_CONVERTER);
		names.add(ObjectTypeConverter.OBJECT_TYPE_CONVERTER);
		names.add(StructConverter.STRUCT_CONVERTER);
		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(MappedSuperClassEntity.MAPPED_SUPERCLASS);
		names.add(Entity.ENTITY);
		names.add(Embeddable.EMBEDDABLE);
		return names;
	}

	private Embeddable buildEmbeddable(int index) {
		return new Embeddable(this, index);
	}

	private Entity buildEntity(int index) {
		return new Entity(this, index);
	}

	private MappedSuperClassEntity buildMappedSuperclass(int index) {
		return new MappedSuperClassEntity(this, index);
	}

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

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

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

	private PersistenceUnit buildPersistenceUnit() {
		return new PersistenceUnit(this);
	}

	public String buildSchemaLocation(ORMDocumentType version) {

		StringBuilder sb = new StringBuilder();
		sb.append(version.getXmlNamespace());
		sb.append(" ");
		sb.append(version.getSchemaURI());

		return sb.toString();
	}

	private SequenceGenerator buildSequenceGenerator(int index) {
		return new SequenceGenerator(this, index);
	}

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

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

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

	private TableGenerator buildTableGenerator(int index) {
		return new TableGenerator(this, index);
	}

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

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

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

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

		return converters;
	}

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

	/**
	 * {@inheritDoc}
	 */
	@Override
	public List<ExternalTenantDiscriminatorColumn> discriminatorColumns() {

		int count = discriminatorColumnSize();
		List<ExternalTenantDiscriminatorColumn> columns = new ArrayList<ExternalTenantDiscriminatorColumn>(count);

		for (int index = 0; index < count; index++) {
			columns.add(buildDiscriminatorColumn(index));
		}

		return columns;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public int discriminatorColumnSize() {
		return getChildrenSize(AbstractTenantDiscriminatorColumn.TENANT_DISCRIMINATOR_COLUMN);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public List<ExternalEmbeddable> embeddables() {

		int count = embeddablesSize();
		List<ExternalEmbeddable> embeddables = new ArrayList<ExternalEmbeddable>(count);

		for (int index = 0; index < count; index++) {
			embeddables.add(buildEmbeddable(index));
		}

		return embeddables;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public int embeddablesSize() {
		return getChildrenSize(Embeddable.EMBEDDABLE);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public List<ExternalEntity> entities() {

		int count = entitiesSize();
		List<ExternalEntity> entities = new ArrayList<ExternalEntity>(count);

		for (int index = 0; index < count; index++) {
			entities.add(buildEntity(index));
		}

		return entities;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public int entitiesSize() {
		return getChildrenSize(Entity.ENTITY);
	}

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

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

	/**
	 * {@inheritDoc}
	 */
	@Override
	public String getBuildVersion() {
		return VERSION_2_0;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public String getCatalogName() {
		return getChildTextNode(CATALOG);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public TextRange getCatalogNameTextRange() {
		return getChildTextNodeTextRange(CATALOG);
	}

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

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

		return null;
	}

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

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalTenantDiscriminatorColumn getDiscriminatorColumn(int index) {

		if (hasChild(AbstractTenantDiscriminatorColumn.TENANT_DISCRIMINATOR_COLUMN, index)) {
			return buildDiscriminatorColumn(index);
		}

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ORMDocumentType getDocumentType() {
		return ORMDocumentType.value(getNamespace(), getVersion(), getSchemaLocation());
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public Element getElement() {
		return getRootElement();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public String getElementName() {
		return ENTITY_MAPPINGS;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalEmbeddable getEmbeddable(int index) {

		if (hasChild(Embeddable.EMBEDDABLE, index)) {
			return buildEmbeddable(index);
		}

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalEmbeddable getEmbeddable(String className) {

		for (ExternalEmbeddable embeddable : embeddables()) {
			if (ObjectTools.equals(embeddable.getClassName(), className)) {
				return embeddable;
			}
		}

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalEntity getEntity(int index) {

		if (hasChild(Entity.ENTITY, index)) {
			return buildEntity(index);
		}

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public Entity getEntity(String className) {

		for (ExternalEntity entity : entities()) {
			if (ObjectTools.equals(entity.getClassName(), className)) {
				return (Entity) entity;
			}
		}

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	protected ExternalFormHelper getHelper() {
		return helper;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public URL getLocation() {
		return helper.getLocation();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalMappedSuperClass getMappedSuperClass(int index) {

		if (hasChild(MappedSuperClassEntity.MAPPED_SUPERCLASS, index)) {
			return buildMappedSuperclass(index);
		}

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalMappedSuperClass getMappedSuperClass(String className) {

		for (ExternalMappedSuperClass entity : mappedSuperClasses()) {
			if (ObjectTools.equals(entity.getClassName(), className)) {
				return entity;
			}
		}

		return null;
	}

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

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

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalNativeQuery getNamedNativeQuery(String queryName) {

		for (ExternalNativeQuery namedQuery : namedNativeQueries()) {
			if (namedQuery.getName().equals(queryName)) {
				return namedQuery;
			}
		}

		return null;
	}

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

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

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public NamedQuery getNamedQuery(String queryName) {

		for (ExternalNamedQuery namedQuery : namedQueries()) {
			if (namedQuery.getName().equals(queryName)) {
				return (NamedQuery) namedQuery;
			}
		}

		return null;
	}

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

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

		return buildObjectTypeConverter(index);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public String getPackageName() {
		return getChildTextNode(PACKAGE);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public TextRange getPackageNameTextRange() {
		return getChildTextNodeTextRange(PACKAGE);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public PersistenceUnit getPersistenceUnitMetaData() {

		if (hasChild(PersistenceUnit.PERSISTENCE_UNIT_METADATA)) {
			return buildPersistenceUnit();
		}

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public TextRange getRootElementTextRange() {
		return getElementNameTextRange(getRootElement());
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public String getSchemaName() {
		return getChildTextNode(SCHEMA);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public TextRange getSchemaNameTextRange() {
		return getChildTextNodeTextRange(SCHEMA);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalSequenceGenerator getSequenceGenerator(int index) {

		if (hasChild(SequenceGenerator.SEQUENCE_GENERATOR, index)) {
			return buildSequenceGenerator(index);
		}

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public URL getSourceRoot() {
		return getHelper().getSourceRoot();
	}

	/**
	 * {@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 ExternalStructConverter getStructConverter(int index) {

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

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalTableGenerator getTableGenerator(int index) {

		if (hasChild(TableGenerator.TABLE_GENERATOR, index)) {
			return buildTableGenerator(index);
		}

		return null;
	}

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

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

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	@SuppressWarnings("resource")
	public String getXML() {

		try {
			acquireReadLock();

			// Write the content into XML file
			TransformerFactory transformerFactory = TransformerFactory.newInstance();
			javax.xml.transform.Transformer transformer = transformerFactory.newTransformer();
			DOMSource source = new DOMSource(getDocument());

			ByteArrayOutputStream output = new ByteArrayOutputStream();
			StreamResult result = new StreamResult(output);

			transformer.transform(source, result);

			return output.toString();
		}
		catch (Exception e) {
			throw new RuntimeException(e);
		}
		finally {
			releaseReadLock();
		}
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public boolean hasPersistenceUnitMetaData() {
		return hasChild(PersistenceUnit.PERSISTENCE_UNIT_METADATA);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public List<ExternalMappedSuperClass> mappedSuperClasses() {

		int count = mappedSuperClassesSize();
		List<ExternalMappedSuperClass> mappedSuperclasses = new ArrayList<ExternalMappedSuperClass>(count);

		for (int index = 0; index < count; index++) {
			mappedSuperclasses.add(buildMappedSuperclass(index));
		}

		return mappedSuperclasses;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public int mappedSuperClassesSize() {
		return getChildrenSize(MappedSuperClassEntity.MAPPED_SUPERCLASS);
	}

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

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

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

		return nativeQueries;
	}

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

	/**
	 * {@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<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 int objectTypeConvertersSize() {
		return getChildrenSize(ObjectTypeConverter.OBJECT_TYPE_CONVERTER);
	}

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

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void removeDiscriminatorColumn(int index) {
		AbstractTenantDiscriminatorColumn column = buildDiscriminatorColumn(index);
		column.removeSelf();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void removeEmbeddable(int index) {
		Embeddable entity = buildEmbeddable(index);
		entity.removeSelf();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void removeEntity(int index) {
		Entity entity = buildEntity(index);
		entity.removeSelf();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void removeEntity(String entityClassName) {

		Entity entity = getEntity(entityClassName);

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

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void removeMappedSuperClass(int index) {
		MappedSuperClassEntity entity = buildMappedSuperclass(index);
		entity.removeSelf();
	}

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

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void removeNamedQuery(String queryName) {

		NamedQuery query = getNamedQuery(queryName);

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

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

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

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void removePersistenceUnitMetaData() {
		PersistenceUnit persistenceUnit = buildPersistenceUnit();
		persistenceUnit.removeSelf();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void removeSequenceGenerator(int index) {
		SequenceGenerator sequenceGenerator = buildSequenceGenerator(index);
		sequenceGenerator.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 void removeStructConverter(int index) {
		StructConverter converter = buildStructConverter(index);
		converter.removeSelf();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void removeTableGenerator(int index) {
		TableGenerator tableGenerator = buildTableGenerator(index);
		tableGenerator.removeSelf();
	}

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

	/**
	 * {@inheritDoc}
	 */
	@Override
	public List<ExternalSequenceGenerator> sequenceGenerators() {

		int count = sequenceGeneratorsSize();
		List<ExternalSequenceGenerator> generators = new ArrayList<ExternalSequenceGenerator>(count);

		for (int index = 0; index < count; index++) {
			generators.add(buildSequenceGenerator(index));
		}

		return generators;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public int sequenceGeneratorsSize() {
		return getChildrenSize(SequenceGenerator.SEQUENCE_GENERATOR);
	}

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

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setCatalogName(String catalog) {
		updateChildTextNode(CATALOG, catalog);
	}

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

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setDocumentType(ORMDocumentType version) {
		setVersion(version.getVersion());
		setSchemaLocation(buildSchemaLocation(version));
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setPackageName(String packageName) {
		updateChildTextNode(PACKAGE, packageName);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setSchemaName(String schema) {
		updateChildTextNode(SCHEMA, schema);
	}

	/**
	 * {@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);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public 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 int structConvertersSize() {
		return getChildrenSize(StructConverter.STRUCT_CONVERTER);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public List<ExternalTableGenerator> tableGenerators() {

		int count = tableGeneratorsSize();
		List<ExternalTableGenerator> generators = new ArrayList<ExternalTableGenerator>(count);

		for (int index = 0; index < count; index++) {
			generators.add(buildTableGenerator(index));
		}

		return generators;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public int tableGeneratorsSize() {
		return getChildrenSize(TableGenerator.TABLE_GENERATOR);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public 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 int typeConvertersSize() {
		return getChildrenSize(TypeConverter.TYPE_CONVERTER);
	}
}