/*******************************************************************************
 * Copyright (c) 2006, 2007 Oracle. All rights reserved. This
 * program and the accompanying materials are made available under the terms of
 * the Eclipse Public License v1.0 which accompanies this distribution, and is
 * available at http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors: Oracle. - initial API and implementation
 *******************************************************************************/
package org.eclipse.jpt.core.internal.content.orm;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.NotificationChain;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.emf.ecore.util.EObjectContainmentEList;
import org.eclipse.emf.ecore.util.EObjectEList;
import org.eclipse.emf.ecore.util.InternalEList;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jpt.core.internal.IJpaContentNode;
import org.eclipse.jpt.core.internal.IJpaFile;
import org.eclipse.jpt.core.internal.IPersistentAttribute;
import org.eclipse.jpt.core.internal.IPersistentType;
import org.eclipse.jpt.core.internal.ITextRange;
import org.eclipse.jpt.core.internal.JpaCorePackage;
import org.eclipse.jpt.core.internal.JptCorePlugin;
import org.eclipse.jpt.core.internal.XmlEObject;
import org.eclipse.jpt.core.internal.content.java.JavaPersistentType;
import org.eclipse.jpt.core.internal.content.java.JpaCompilationUnit;
import org.eclipse.jpt.core.internal.jdtutility.JDTTools;
import org.eclipse.jpt.core.internal.jdtutility.Type;
import org.eclipse.jpt.core.internal.platform.DefaultsContext;
import org.eclipse.jpt.utility.internal.CollectionTools;
import org.eclipse.jpt.utility.internal.StringTools;
import org.eclipse.jpt.utility.internal.iterators.ChainIterator;
import org.eclipse.jpt.utility.internal.iterators.CompositeIterator;
import org.eclipse.jpt.utility.internal.iterators.FilteringIterator;
import org.eclipse.jpt.utility.internal.iterators.ReadOnlyIterator;
import org.eclipse.jpt.utility.internal.iterators.TransformationIterator;

/**
 * <!-- begin-user-doc -->
 * A representation of the model object '<em><b>Xml Persistent Type</b></em>'.
 * <!-- end-user-doc -->
 *
 * <p>
 * The following features are supported:
 * <ul>
 *   <li>{@link org.eclipse.jpt.core.internal.content.orm.XmlPersistentType#getClass_ <em>Class</em>}</li>
 *   <li>{@link org.eclipse.jpt.core.internal.content.orm.XmlPersistentType#getAttributeMappings <em>Attribute Mappings</em>}</li>
 *   <li>{@link org.eclipse.jpt.core.internal.content.orm.XmlPersistentType#getSpecifiedAttributeMappings <em>Specified Attribute Mappings</em>}</li>
 *   <li>{@link org.eclipse.jpt.core.internal.content.orm.XmlPersistentType#getVirtualAttributeMappings <em>Virtual Attribute Mappings</em>}</li>
 *   <li>{@link org.eclipse.jpt.core.internal.content.orm.XmlPersistentType#getPersistentAttributes <em>Persistent Attributes</em>}</li>
 *   <li>{@link org.eclipse.jpt.core.internal.content.orm.XmlPersistentType#getSpecifiedPersistentAttributes <em>Specified Persistent Attributes</em>}</li>
 *   <li>{@link org.eclipse.jpt.core.internal.content.orm.XmlPersistentType#getVirtualPersistentAttributes <em>Virtual Persistent Attributes</em>}</li>
 * </ul>
 * </p>
 *
 * @see org.eclipse.jpt.core.internal.content.orm.OrmPackage#getXmlPersistentType()
 * @model kind="class"
 * @generated
 */
public class XmlPersistentType extends XmlEObject implements IPersistentType
{
	/**
	 * The default value of the '{@link #getMappingKey() <em>Mapping Key</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getMappingKey()
	 * @generated
	 * @ordered
	 */
	protected static final String MAPPING_KEY_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getMappingKey() <em>Mapping Key</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getMappingKey()
	 * @generated
	 * @ordered
	 */
	protected String mappingKey = MAPPING_KEY_EDEFAULT;

	/**
	 * The default value of the '{@link #getClass_() <em>Class</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getClass_()
	 * @generated
	 * @ordered
	 */
	protected static final String CLASS_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getClass_() <em>Class</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getClass_()
	 * @generated
	 * @ordered
	 */
	protected String class_ = CLASS_EDEFAULT;

	/**
	 * The cached value of the '{@link #getSpecifiedAttributeMappings() <em>Specified Attribute Mappings</em>}' containment reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getSpecifiedAttributeMappings()
	 * @generated
	 * @ordered
	 */
	protected EList<XmlAttributeMapping> specifiedAttributeMappings;

	/**
	 * The cached value of the '{@link #getVirtualAttributeMappings() <em>Virtual Attribute Mappings</em>}' containment reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getVirtualAttributeMappings()
	 * @generated
	 * @ordered
	 */
	protected EList<XmlAttributeMapping> virtualAttributeMappings;

	/**
	 * The cached value of the '{@link #getSpecifiedPersistentAttributes() <em>Specified Persistent Attributes</em>}' reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getSpecifiedPersistentAttributes()
	 * @generated
	 * @ordered
	 */
	protected EList<XmlPersistentAttribute> specifiedPersistentAttributes;

	/**
	 * The cached value of the '{@link #getVirtualPersistentAttributes() <em>Virtual Persistent Attributes</em>}' reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getVirtualPersistentAttributes()
	 * @generated
	 * @ordered
	 */
	protected EList<XmlPersistentAttribute> virtualPersistentAttributes;

	private Collection<IXmlTypeMappingProvider> typeMappingProviders;

	private IPersistentType parentPersistentType;

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated NOT
	 */
	protected XmlPersistentType() {
		super();
		this.typeMappingProviders = buildTypeMappingProviders();
	}

	protected XmlPersistentType(String theMappingKey) {
		this();
		mappingKey = theMappingKey;
	}

	@Override
	protected void addInsignificantFeatureIdsTo(Set<Integer> insignificantFeatureIds) {
		super.addInsignificantFeatureIdsTo(insignificantFeatureIds);
		insignificantFeatureIds.add(OrmPackage.XML_PERSISTENT_TYPE__ATTRIBUTE_MAPPINGS);
		insignificantFeatureIds.add(OrmPackage.XML_PERSISTENT_TYPE__PERSISTENT_ATTRIBUTES);
		insignificantFeatureIds.add(OrmPackage.XML_PERSISTENT_TYPE__SPECIFIED_PERSISTENT_ATTRIBUTES);
		insignificantFeatureIds.add(OrmPackage.XML_PERSISTENT_TYPE__VIRTUAL_PERSISTENT_ATTRIBUTES);
	}

	protected Collection<IXmlTypeMappingProvider> buildTypeMappingProviders() {
		Collection<IXmlTypeMappingProvider> collection = new ArrayList<IXmlTypeMappingProvider>();
		collection.add(new XmlEntityProvider());
		collection.add(new XmlMappedSuperclassProvider());
		collection.add(new XmlEmbeddableProvider());
		return collection;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	protected EClass eStaticClass() {
		return OrmPackage.Literals.XML_PERSISTENT_TYPE;
	}

	public XmlTypeMapping getMapping() {
		return (XmlTypeMapping) eContainer();
	}

	/* @see IJpaContentNode#getId() */
	public Object getId() {
		return IXmlContentNodes.PERSISTENT_TYPE_ID;
	}

	/**
	 * Returns the value of the '<em><b>Mapping Key</b></em>' attribute.
	 * <!-- begin-user-doc -->
	 * <p>
	 * If the meaning of the '<em>Mapping Key</em>' attribute isn't clear,
	 * there really should be more of a description here...
	 * </p>
	 * <!-- end-user-doc -->
	 * @return the value of the '<em>Mapping Key</em>' attribute.
	 * @see #setMappingKey(String)
	 * @see org.eclipse.jpt.core.internal.content.orm.OrmPackage#getIPersistentType_MappingKey()
	 * @model required="true"
	 * @generated
	 */
	public String getMappingKey() {
		return mappingKey;
	}

	/**
	 * Sets the value of the '{@link org.eclipse.jpt.core.internal.content.orm.XmlPersistentType#getMappingKey <em>Mapping Key</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @param value the new value of the '<em>Mapping Key</em>' attribute.
	 * @see #getMappingKey()
	 * @generated
	 */
	public void setMappingKeyGen(String newMappingKey) {
		String oldMappingKey = mappingKey;
		mappingKey = newMappingKey;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, OrmPackage.XML_PERSISTENT_TYPE__MAPPING_KEY, oldMappingKey, mappingKey));
	}

	public void setMappingKey(String newMappingKey) {
		if (mappingKey.equals(newMappingKey)) {
			return;
		}
		XmlTypeMapping oldMapping = getMapping();
		EntityMappings entityMappings = oldMapping.getEntityMappings();
		entityMappings.changeMapping(oldMapping, newMappingKey);
		setMappingKeyGen(newMappingKey);
	}

	/**
	 * Returns the value of the '<em><b>Class</b></em>' attribute.
	 * <!-- begin-user-doc -->
	 * <p>
	 * If the meaning of the '<em>Class</em>' attribute isn't clear,
	 * there really should be more of a description here...
	 * </p>
	 * <!-- end-user-doc -->
	 * @return the value of the '<em>Class</em>' attribute.
	 * @see #setClass(String)
	 * @see org.eclipse.jpt.core.internal.content.orm.OrmPackage#getXmlPersistentType_Class()
	 * @model
	 * @generated
	 */
	public String getClass_() {
		return class_;
	}

	/**
	 * Sets the value of the '{@link org.eclipse.jpt.core.internal.content.orm.XmlPersistentType#getClass_ <em>Class</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @param value the new value of the '<em>Class</em>' attribute.
	 * @see #getClass_()
	 * @generated
	 */
	public void setClass(String newClass) {
		String oldClass = class_;
		class_ = newClass;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, OrmPackage.XML_PERSISTENT_TYPE__CLASS, oldClass, class_));
	}

	/**
	 * Returns the value of the '<em><b>Attribute Mappings</b></em>' containment reference list.
	 * The list contents are of type {@link org.eclipse.jpt.core.internal.content.orm.XmlAttributeMapping}.
	 * <!-- begin-user-doc -->
	 * <p>
	 * If the meaning of the '<em>Attribute Mappings</em>' containment reference list isn't clear,
	 * there really should be more of a description here...
	 * </p>
	 * <!-- end-user-doc -->
	 * @return the value of the '<em>Attribute Mappings</em>' containment reference list.
	 * @see org.eclipse.jpt.core.internal.content.orm.OrmPackage#getXmlPersistentType_AttributeMappings()
	 * @model type="org.eclipse.jpt.core.internal.content.orm.XmlAttributeMapping" containment="true" transient="true" changeable="false" volatile="true"
	 * @generated NOT
	 */
	public EList<XmlAttributeMapping> getAttributeMappings() {
		EList<XmlAttributeMapping> list = new EObjectEList<XmlAttributeMapping>(XmlAttributeMapping.class, this, OrmPackage.XML_PERSISTENT_TYPE__ATTRIBUTE_MAPPINGS);
		list.addAll(getSpecifiedAttributeMappings());
		list.addAll(getVirtualAttributeMappings());
		return list;
	}

	/**
	 * Returns the value of the '<em><b>Specified Attribute Mappings</b></em>' containment reference list.
	 * The list contents are of type {@link org.eclipse.jpt.core.internal.content.orm.XmlAttributeMapping}.
	 * <!-- begin-user-doc -->
	 * <p>
	 * If the meaning of the '<em>Specified Attribute Mappings</em>' containment reference list isn't clear,
	 * there really should be more of a description here...
	 * </p>
	 * <!-- end-user-doc -->
	 * @return the value of the '<em>Specified Attribute Mappings</em>' containment reference list.
	 * @see org.eclipse.jpt.core.internal.content.orm.OrmPackage#getXmlPersistentType_SpecifiedAttributeMappings()
	 * @model containment="true"
	 * @generated
	 */
	public EList<XmlAttributeMapping> getSpecifiedAttributeMappingsGen() {
		if (specifiedAttributeMappings == null) {
			specifiedAttributeMappings = new EObjectContainmentEList<XmlAttributeMapping>(XmlAttributeMapping.class, this, OrmPackage.XML_PERSISTENT_TYPE__SPECIFIED_ATTRIBUTE_MAPPINGS);
		}
		return specifiedAttributeMappings;
	}

	public EList<XmlAttributeMapping> getSpecifiedAttributeMappings() {
		if (specifiedAttributeMappings == null) {
			specifiedAttributeMappings = new SpecifiedAttributeMappingsList<XmlAttributeMapping>();
		}
		return getSpecifiedAttributeMappingsGen();
	}

	/**
	 * Returns the value of the '<em><b>Virtual Attribute Mappings</b></em>' containment reference list.
	 * The list contents are of type {@link org.eclipse.jpt.core.internal.content.orm.XmlAttributeMapping}.
	 * <!-- begin-user-doc -->
	 * <p>
	 * If the meaning of the '<em>Virtual Attribute Mappings</em>' containment reference list isn't clear,
	 * there really should be more of a description here...
	 * </p>
	 * <!-- end-user-doc -->
	 * @return the value of the '<em>Virtual Attribute Mappings</em>' containment reference list.
	 * @see org.eclipse.jpt.core.internal.content.orm.OrmPackage#getXmlPersistentType_VirtualAttributeMappings()
	 * @model containment="true"
	 * @generated
	 */
	public EList<XmlAttributeMapping> getVirtualAttributeMappingsGen() {
		if (virtualAttributeMappings == null) {
			virtualAttributeMappings = new EObjectContainmentEList<XmlAttributeMapping>(XmlAttributeMapping.class, this, OrmPackage.XML_PERSISTENT_TYPE__VIRTUAL_ATTRIBUTE_MAPPINGS);
		}
		return virtualAttributeMappings;
	}

	public EList<XmlAttributeMapping> getVirtualAttributeMappings() {
		if (virtualAttributeMappings == null) {
			virtualAttributeMappings = new VirtualAttributeMappingsList<XmlAttributeMapping>();
		}
		return getVirtualAttributeMappingsGen();
	}

	/**
	 * Returns the value of the '<em><b>Persistent Attributes</b></em>' reference list.
	 * The list contents are of type {@link org.eclipse.jpt.core.internal.content.orm.XmlPersistentAttribute}.
	 * <!-- begin-user-doc -->
	 * <p>
	 * If the meaning of the '<em>Persistent Attributes</em>' reference list isn't clear,
	 * there really should be more of a description here...
	 * </p>
	 * <!-- end-user-doc -->
	 * @return the value of the '<em>Persistent Attributes</em>' reference list.
	 * @see org.eclipse.jpt.core.internal.content.orm.OrmPackage#getXmlPersistentType_PersistentAttributes()
	 * @model type="org.eclipse.jpt.core.internal.content.orm.XmlPersistentAttribute" resolveProxies="false" transient="true" changeable="false" volatile="true"
	 * @generated NOT
	 */
	public EList<XmlPersistentAttribute> getPersistentAttributes() {
		EList<XmlPersistentAttribute> list = new EObjectEList<XmlPersistentAttribute>(XmlPersistentAttribute.class, this, OrmPackage.XML_PERSISTENT_TYPE__PERSISTENT_ATTRIBUTES);
		list.addAll(getSpecifiedPersistentAttributes());
		list.addAll(getVirtualPersistentAttributes());
		return list;
	}

	/**
	 * Returns the value of the '<em><b>Specified Persistent Attributes</b></em>' reference list.
	 * The list contents are of type {@link org.eclipse.jpt.core.internal.content.orm.XmlPersistentAttribute}.
	 * <!-- begin-user-doc -->
	 * <p>
	 * If the meaning of the '<em>Specified Persistent Attributes</em>' reference list isn't clear,
	 * there really should be more of a description here...
	 * </p>
	 * <!-- end-user-doc -->
	 * @return the value of the '<em>Specified Persistent Attributes</em>' reference list.
	 * @see org.eclipse.jpt.core.internal.content.orm.OrmPackage#getXmlPersistentType_SpecifiedPersistentAttributes()
	 * @model resolveProxies="false"
	 * @generated
	 */
	public EList<XmlPersistentAttribute> getSpecifiedPersistentAttributes() {
		if (specifiedPersistentAttributes == null) {
			specifiedPersistentAttributes = new EObjectEList<XmlPersistentAttribute>(XmlPersistentAttribute.class, this, OrmPackage.XML_PERSISTENT_TYPE__SPECIFIED_PERSISTENT_ATTRIBUTES);
		}
		return specifiedPersistentAttributes;
	}

	/**
	 * Returns the value of the '<em><b>Virtual Persistent Attributes</b></em>' reference list.
	 * The list contents are of type {@link org.eclipse.jpt.core.internal.content.orm.XmlPersistentAttribute}.
	 * <!-- begin-user-doc -->
	 * <p>
	 * If the meaning of the '<em>Default Persistent Attributes</em>' reference list isn't clear,
	 * there really should be more of a description here...
	 * </p>
	 * <!-- end-user-doc -->
	 * @return the value of the '<em>Virtual Persistent Attributes</em>' reference list.
	 * @see org.eclipse.jpt.core.internal.content.orm.OrmPackage#getXmlPersistentType_VirtualPersistentAttributes()
	 * @model resolveProxies="false"
	 * @generated
	 */
	public EList<XmlPersistentAttribute> getVirtualPersistentAttributes() {
		if (virtualPersistentAttributes == null) {
			virtualPersistentAttributes = new EObjectEList<XmlPersistentAttribute>(XmlPersistentAttribute.class, this, OrmPackage.XML_PERSISTENT_TYPE__VIRTUAL_PERSISTENT_ATTRIBUTES);
		}
		return virtualPersistentAttributes;
	}

	protected void changeMapping(XmlAttributeMapping oldMapping, String newMappingKey) {
		boolean virtual = oldMapping.isVirtual();
		XmlAttributeMapping newAttributeMapping = buildAttributeMapping(oldMapping.getPersistentAttribute().attributeMappingProviders(), newMappingKey);
		// we can't set the attribute to null, but we can set it to a dummy placeholder one
		// we do this to get the translators to *wake up* and remove adapters from the attribute
		XmlPersistentAttribute nullAttribute = OrmFactory.eINSTANCE.createXmlPersistentAttribute();
		XmlPersistentAttribute attribute = oldMapping.getPersistentAttribute();
		oldMapping.setPersistentAttribute(nullAttribute);
		if (virtual) {
			getVirtualPersistentAttributes().remove(attribute);
			getVirtualAttributeMappings().remove(oldMapping);
		}
		else {
			getSpecifiedPersistentAttributes().remove(attribute);
			getSpecifiedAttributeMappings().remove(oldMapping);
		}
		newAttributeMapping.setPersistentAttribute(attribute);
		oldMapping.initializeOn(newAttributeMapping);
		if (virtual) {
			insertAttributeMapping(newAttributeMapping, getVirtualAttributeMappings());
		}
		else {
			insertAttributeMapping(newAttributeMapping, getSpecifiedAttributeMappings());
		}
	}

	private XmlAttributeMapping buildAttributeMapping(Collection<IXmlAttributeMappingProvider> providers, String key) {
		for (IXmlAttributeMappingProvider provider : providers) {
			if (provider.key().equals(key)) {
				return provider.buildAttributeMapping();
			}
		}
		return OrmFactory.eINSTANCE.createXmlNullAttributeMapping();
	}

	public Collection<IXmlTypeMappingProvider> typeMappingProviders() {
		return this.typeMappingProviders;
	}

	protected void setMappingVirtual(XmlAttributeMapping attributeMapping, boolean virtual) {
		boolean oldVirtual = attributeMapping.isVirtual();
		if (oldVirtual == virtual) {
			return;
		}
		if (virtual) {
			getSpecifiedAttributeMappings().remove(attributeMapping);
			insertAttributeMapping(attributeMapping, getVirtualAttributeMappings());
		}
		else {
			getVirtualAttributeMappings().remove(attributeMapping);
			insertAttributeMapping(attributeMapping, getSpecifiedAttributeMappings());
		}
	}

	private void insertAttributeMapping(XmlAttributeMapping newMapping, List<XmlAttributeMapping> attributeMappings) {
		int newIndex = CollectionTools.insertionIndexOf(attributeMappings, newMapping, buildMappingComparator());
		attributeMappings.add(newIndex, newMapping);
	}

	private Comparator<XmlAttributeMapping> buildMappingComparator() {
		return new Comparator<XmlAttributeMapping>() {
			public int compare(XmlAttributeMapping o1, XmlAttributeMapping o2) {
				int o1Sequence = o1.xmlSequence();
				int o2Sequence = o2.xmlSequence();
				if (o1Sequence < o2Sequence) {
					return -1;
				}
				if (o1Sequence == o2Sequence) {
					return 0;
				}
				return 1;
			}
		};
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case OrmPackage.XML_PERSISTENT_TYPE__ATTRIBUTE_MAPPINGS :
				return ((InternalEList<?>) getAttributeMappings()).basicRemove(otherEnd, msgs);
			case OrmPackage.XML_PERSISTENT_TYPE__SPECIFIED_ATTRIBUTE_MAPPINGS :
				return ((InternalEList<?>) getSpecifiedAttributeMappings()).basicRemove(otherEnd, msgs);
			case OrmPackage.XML_PERSISTENT_TYPE__VIRTUAL_ATTRIBUTE_MAPPINGS :
				return ((InternalEList<?>) getVirtualAttributeMappings()).basicRemove(otherEnd, msgs);
		}
		return super.eInverseRemove(otherEnd, featureID, msgs);
	}

	public Iterator candidateMappingKeys() {
		Collection mappingKeys = new ArrayList();
		for (IXmlTypeMappingProvider provider : typeMappingProviders()) {
			mappingKeys.add(provider.key());
		}
		return mappingKeys.iterator();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case OrmPackage.XML_PERSISTENT_TYPE__MAPPING_KEY :
				return getMappingKey();
			case OrmPackage.XML_PERSISTENT_TYPE__CLASS :
				return getClass_();
			case OrmPackage.XML_PERSISTENT_TYPE__ATTRIBUTE_MAPPINGS :
				return getAttributeMappings();
			case OrmPackage.XML_PERSISTENT_TYPE__SPECIFIED_ATTRIBUTE_MAPPINGS :
				return getSpecifiedAttributeMappings();
			case OrmPackage.XML_PERSISTENT_TYPE__VIRTUAL_ATTRIBUTE_MAPPINGS :
				return getVirtualAttributeMappings();
			case OrmPackage.XML_PERSISTENT_TYPE__PERSISTENT_ATTRIBUTES :
				return getPersistentAttributes();
			case OrmPackage.XML_PERSISTENT_TYPE__SPECIFIED_PERSISTENT_ATTRIBUTES :
				return getSpecifiedPersistentAttributes();
			case OrmPackage.XML_PERSISTENT_TYPE__VIRTUAL_PERSISTENT_ATTRIBUTES :
				return getVirtualPersistentAttributes();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@SuppressWarnings("unchecked")
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case OrmPackage.XML_PERSISTENT_TYPE__MAPPING_KEY :
				setMappingKey((String) newValue);
				return;
			case OrmPackage.XML_PERSISTENT_TYPE__CLASS :
				setClass((String) newValue);
				return;
			case OrmPackage.XML_PERSISTENT_TYPE__SPECIFIED_ATTRIBUTE_MAPPINGS :
				getSpecifiedAttributeMappings().clear();
				getSpecifiedAttributeMappings().addAll((Collection<? extends XmlAttributeMapping>) newValue);
				return;
			case OrmPackage.XML_PERSISTENT_TYPE__VIRTUAL_ATTRIBUTE_MAPPINGS :
				getVirtualAttributeMappings().clear();
				getVirtualAttributeMappings().addAll((Collection<? extends XmlAttributeMapping>) newValue);
				return;
			case OrmPackage.XML_PERSISTENT_TYPE__SPECIFIED_PERSISTENT_ATTRIBUTES :
				getSpecifiedPersistentAttributes().clear();
				getSpecifiedPersistentAttributes().addAll((Collection<? extends XmlPersistentAttribute>) newValue);
				return;
			case OrmPackage.XML_PERSISTENT_TYPE__VIRTUAL_PERSISTENT_ATTRIBUTES :
				getVirtualPersistentAttributes().clear();
				getVirtualPersistentAttributes().addAll((Collection<? extends XmlPersistentAttribute>) newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case OrmPackage.XML_PERSISTENT_TYPE__MAPPING_KEY :
				setMappingKey(MAPPING_KEY_EDEFAULT);
				return;
			case OrmPackage.XML_PERSISTENT_TYPE__CLASS :
				setClass(CLASS_EDEFAULT);
				return;
			case OrmPackage.XML_PERSISTENT_TYPE__SPECIFIED_ATTRIBUTE_MAPPINGS :
				getSpecifiedAttributeMappings().clear();
				return;
			case OrmPackage.XML_PERSISTENT_TYPE__VIRTUAL_ATTRIBUTE_MAPPINGS :
				getVirtualAttributeMappings().clear();
				return;
			case OrmPackage.XML_PERSISTENT_TYPE__SPECIFIED_PERSISTENT_ATTRIBUTES :
				getSpecifiedPersistentAttributes().clear();
				return;
			case OrmPackage.XML_PERSISTENT_TYPE__VIRTUAL_PERSISTENT_ATTRIBUTES :
				getVirtualPersistentAttributes().clear();
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case OrmPackage.XML_PERSISTENT_TYPE__MAPPING_KEY :
				return MAPPING_KEY_EDEFAULT == null ? mappingKey != null : !MAPPING_KEY_EDEFAULT.equals(mappingKey);
			case OrmPackage.XML_PERSISTENT_TYPE__CLASS :
				return CLASS_EDEFAULT == null ? class_ != null : !CLASS_EDEFAULT.equals(class_);
			case OrmPackage.XML_PERSISTENT_TYPE__ATTRIBUTE_MAPPINGS :
				return !getAttributeMappings().isEmpty();
			case OrmPackage.XML_PERSISTENT_TYPE__SPECIFIED_ATTRIBUTE_MAPPINGS :
				return specifiedAttributeMappings != null && !specifiedAttributeMappings.isEmpty();
			case OrmPackage.XML_PERSISTENT_TYPE__VIRTUAL_ATTRIBUTE_MAPPINGS :
				return virtualAttributeMappings != null && !virtualAttributeMappings.isEmpty();
			case OrmPackage.XML_PERSISTENT_TYPE__PERSISTENT_ATTRIBUTES :
				return !getPersistentAttributes().isEmpty();
			case OrmPackage.XML_PERSISTENT_TYPE__SPECIFIED_PERSISTENT_ATTRIBUTES :
				return specifiedPersistentAttributes != null && !specifiedPersistentAttributes.isEmpty();
			case OrmPackage.XML_PERSISTENT_TYPE__VIRTUAL_PERSISTENT_ATTRIBUTES :
				return virtualPersistentAttributes != null && !virtualPersistentAttributes.isEmpty();
		}
		return super.eIsSet(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public int eBaseStructuralFeatureID(int derivedFeatureID, Class<?> baseClass) {
		if (baseClass == IJpaContentNode.class) {
			switch (derivedFeatureID) {
				default :
					return -1;
			}
		}
		if (baseClass == IPersistentType.class) {
			switch (derivedFeatureID) {
				case OrmPackage.XML_PERSISTENT_TYPE__MAPPING_KEY :
					return JpaCorePackage.IPERSISTENT_TYPE__MAPPING_KEY;
				default :
					return -1;
			}
		}
		return super.eBaseStructuralFeatureID(derivedFeatureID, baseClass);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public int eDerivedStructuralFeatureID(int baseFeatureID, Class<?> baseClass) {
		if (baseClass == IJpaContentNode.class) {
			switch (baseFeatureID) {
				default :
					return -1;
			}
		}
		if (baseClass == IPersistentType.class) {
			switch (baseFeatureID) {
				case JpaCorePackage.IPERSISTENT_TYPE__MAPPING_KEY :
					return OrmPackage.XML_PERSISTENT_TYPE__MAPPING_KEY;
				default :
					return -1;
			}
		}
		return super.eDerivedStructuralFeatureID(baseFeatureID, baseClass);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public String toString() {
		if (eIsProxy())
			return super.toString();
		StringBuffer result = new StringBuffer(super.toString());
		result.append(" (mappingKey: ");
		result.append(mappingKey);
		result.append(", class: ");
		result.append(class_);
		result.append(')');
		return result.toString();
	}

	public IType findJdtType() {
		String fqName = getClass_();
		if (StringTools.stringIsEmpty(fqName)) {
			return null;
		}
		// try to resolve by only the locally specified name
		IType type = resolveJdtType(fqName);
		if (type == null) {
			// try to resolve by prepending the global package name
			fqName = getMapping().getEntityMappings().getPackage() + "." + getClass_();
			type = resolveJdtType(fqName);
		}
		return type;
	}

	private IType resolveJdtType(String fullyQualifiedName) {
		// this name could be of the form "package.name.ClassName"
		// or the form "package.name.ClassName.MemberClassName"
		// so we must try multiple package and class names here
		String[] name = new String[] {
			fullyQualifiedName, ""
		};
		while (name[0].length() != 0) {
			name = moveDot(name);
			IType type = JDTTools.findType(name[0], name[1], getJpaProject().getJavaProject());
			if (type != null)
				return type;
		}
		return null;
	}

	/**
	 * Returns a String array based on the given string array by 
	 * moving a package segment from the end of the first to the
	 * beginning of the second
	 * 
	 * e.g. ["foo.bar", "Baz"] -> ["foo", "bar.Baz"]
	 */
	private String[] moveDot(String[] packageAndClassName) {
		if (packageAndClassName[0].length() == 0) {
			throw new IllegalArgumentException();
		}
		String segmentToMove;
		String packageName = packageAndClassName[0];
		String className = packageAndClassName[1];
		if (packageName.indexOf('.') == -1) {
			segmentToMove = packageName;
			packageAndClassName[0] = "";
		}
		else {
			int dotIndex = packageName.lastIndexOf('.');
			segmentToMove = packageName.substring(dotIndex + 1, packageName.length());
			packageAndClassName[0] = packageName.substring(0, dotIndex);
		}
		if (className.length() == 0) {
			packageAndClassName[1] = segmentToMove;
		}
		else {
			packageAndClassName[1] = segmentToMove + '.' + className;
		}
		return packageAndClassName;
	}

	public JavaPersistentType findJavaPersistentType() {
		IType iType = findJdtType();
		if (iType != null) {
			for (IJpaFile jpaFile : getJpaProject().jpaFiles(JptCorePlugin.JAVA_CONTENT_TYPE)) {
				for (JavaPersistentType javaPersistentType : ((JpaCompilationUnit) jpaFile.getContent()).getTypes()) {
					if (javaPersistentType.jdtType().equals(iType)) {
						return javaPersistentType;
					}
				}
			}
		}
		return null;
	}

	public Type findType() {
		JavaPersistentType javaPersistentType = findJavaPersistentType();
		return (javaPersistentType == null) ? null : javaPersistentType.getType();
	}

	public Iterator<XmlPersistentAttribute> attributes() {
		return new ReadOnlyIterator<XmlPersistentAttribute>(getPersistentAttributes());
	}

	public Iterator<String> attributeNames() {
		return this.attributeNames(this.attributes());
	}

	private Iterator<String> attributeNames(Iterator<? extends IPersistentAttribute> attrs) {
		return new TransformationIterator<IPersistentAttribute, String>(attrs) {
			@Override
			protected String transform(IPersistentAttribute attribute) {
				return attribute.getName();
			}
		};
	}

	public Iterator<IPersistentAttribute> allAttributes() {
		return new CompositeIterator<IPersistentAttribute>(new TransformationIterator<IPersistentType, Iterator<IPersistentAttribute>>(this.inheritanceHierarchy()) {
			@Override
			protected Iterator<IPersistentAttribute> transform(IPersistentType pt) {
				//TODO how to remove this warning?
				return (Iterator<IPersistentAttribute>) pt.attributes();
			}
		});
	}

	public Iterator<String> allAttributeNames() {
		return this.attributeNames(this.allAttributes());
	}

	public Iterator<IPersistentType> inheritanceHierarchy() {
		// using a chain iterator to traverse up the inheritance tree
		return new ChainIterator(this) {
			protected Object nextLink(Object currentLink) {
				return ((IPersistentType) currentLink).parentPersistentType();
			}
		};
	}

	public IPersistentType parentPersistentType() {
		return this.parentPersistentType;
	}

	public IJpaContentNode getContentNode(int offset) {
		for (Iterator i = getSpecifiedAttributeMappings().iterator(); i.hasNext();) {
			XmlAttributeMapping mapping = (XmlAttributeMapping) i.next();
			if (mapping.getNode().contains(offset)) {
				return mapping.getContentNode(offset);
			}
		}
		return this;
	}

	public void refreshDefaults(DefaultsContext context) {
		refreshParentPersistentType(context);
	}

	private void refreshParentPersistentType(DefaultsContext context) {
		JavaPersistentType javaPersistentType = findJavaPersistentType();
		if (javaPersistentType == null) {
			this.parentPersistentType = null;
			return;
		}
		//TODO need to fix the performance issue that results here
		//setting this back for now because of bug 200957 in the M1 release
		ITypeBinding typeBinding = javaPersistentType.getType().typeBinding(javaPersistentType.getType().astRoot());
		IPersistentType parentPersistentType = JavaPersistentType.parentPersistentType(context, typeBinding);
		this.parentPersistentType = parentPersistentType;
		return;
	}

	protected Iterator<XmlPersistentAttribute> attributesNamed(final String attributeName) {
		return new FilteringIterator<XmlPersistentAttribute>(getPersistentAttributes().iterator()) {
			@Override
			protected boolean accept(Object o) {
				return attributeName.equals(((XmlPersistentAttribute) o).getName());
			}
		};
	}

	public XmlPersistentAttribute attributeNamed(String attributeName) {
		Iterator<XmlPersistentAttribute> attributes = attributesNamed(attributeName);
		if (attributes.hasNext()) {
			return attributes.next();
		}
		else {
			return null;
		}
	}

	public IPersistentAttribute resolveAttribute(String attributeName) {
		Iterator<XmlPersistentAttribute> attributes = attributesNamed(attributeName);
		if (attributes.hasNext()) {
			XmlPersistentAttribute attribute = attributes.next();
			if (attributes.hasNext()) {
				// more than one
				return null;
			}
			else {
				return attribute;
			}
		}
		else if (parentPersistentType() != null) {
			return parentPersistentType().resolveAttribute(attributeName);
		}
		else {
			return null;
		}
	}

	@Override
	public ITextRange validationTextRange() {
		return selectionTextRange();
	}

	@Override
	public ITextRange selectionTextRange() {
		return getMapping().selectionTextRange();
	}

	public ITextRange classTextRange() {
		return getMapping().classTextRange();
	}

	public ITextRange attributesTextRange() {
		return getMapping().attributesTextRange();
	}


	private abstract class AttributeMappingsList<E>
		extends EObjectContainmentEList<XmlAttributeMapping>
	{
		private AttributeMappingsList(int feature) {
			super(XmlAttributeMapping.class, XmlPersistentType.this, feature);
		}

		protected abstract EList<XmlPersistentAttribute> persistentAttributes();

		@Override
		protected void didAdd(int index, XmlAttributeMapping newObject) {
			if (newObject.getPersistentAttribute() == null) {
				throw new IllegalStateException("Must set the PersistentAttribute during creation");
			}
			persistentAttributes().add(index, newObject.getPersistentAttribute());
		}

		@Override
		protected void didChange() {
			// TODO Auto-generated method stub
			super.didChange();
		}

		@Override
		protected void didClear(int size, Object[] oldObjects) {
			persistentAttributes().clear();
		}

		@Override
		protected void didMove(int index, XmlAttributeMapping movedObject, int oldIndex) {
			persistentAttributes().move(index, movedObject.getPersistentAttribute());
		}

		@Override
		protected void didRemove(int index, XmlAttributeMapping oldObject) {
			persistentAttributes().remove(oldObject.getPersistentAttribute());
		}

		@Override
		protected void didSet(int index, XmlAttributeMapping newObject, XmlAttributeMapping oldObject) {
			persistentAttributes().set(index, newObject.getPersistentAttribute());
		}
	}


	private class SpecifiedAttributeMappingsList<E>
		extends AttributeMappingsList<XmlAttributeMapping>
	{
		private SpecifiedAttributeMappingsList() {
			super(OrmPackage.XML_PERSISTENT_TYPE__SPECIFIED_ATTRIBUTE_MAPPINGS);
		}

		@Override
		protected EList<XmlPersistentAttribute> persistentAttributes() {
			return getSpecifiedPersistentAttributes();
		}
	}


	private class VirtualAttributeMappingsList<E>
		extends AttributeMappingsList<XmlAttributeMapping>
	{
		private VirtualAttributeMappingsList() {
			super(OrmPackage.XML_PERSISTENT_TYPE__VIRTUAL_ATTRIBUTE_MAPPINGS);
		}

		@Override
		protected EList<XmlPersistentAttribute> persistentAttributes() {
			return getVirtualPersistentAttributes();
		}
	}
}
