/*******************************************************************************
 * 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.java;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
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.InternalEList;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jpt.core.internal.AccessType;
import org.eclipse.jpt.core.internal.IJpaContentNode;
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.content.java.mappings.JavaAssociationOverride;
import org.eclipse.jpt.core.internal.content.java.mappings.JavaAttributeOverride;
import org.eclipse.jpt.core.internal.content.java.mappings.JavaBasic;
import org.eclipse.jpt.core.internal.content.java.mappings.JavaColumn;
import org.eclipse.jpt.core.internal.content.java.mappings.JavaEmbedded;
import org.eclipse.jpt.core.internal.content.java.mappings.JavaEmbeddedId;
import org.eclipse.jpt.core.internal.content.java.mappings.JavaGeneratedValue;
import org.eclipse.jpt.core.internal.content.java.mappings.JavaId;
import org.eclipse.jpt.core.internal.content.java.mappings.JavaJoinColumn;
import org.eclipse.jpt.core.internal.content.java.mappings.JavaJoinTable;
import org.eclipse.jpt.core.internal.content.java.mappings.JavaManyToMany;
import org.eclipse.jpt.core.internal.content.java.mappings.JavaManyToOne;
import org.eclipse.jpt.core.internal.content.java.mappings.JavaMultiRelationshipMapping;
import org.eclipse.jpt.core.internal.content.java.mappings.JavaNullTypeMappingProvider;
import org.eclipse.jpt.core.internal.content.java.mappings.JavaOneToMany;
import org.eclipse.jpt.core.internal.content.java.mappings.JavaOneToOne;
import org.eclipse.jpt.core.internal.content.java.mappings.JavaPrimaryKeyJoinColumn;
import org.eclipse.jpt.core.internal.content.java.mappings.JavaSequenceGenerator;
import org.eclipse.jpt.core.internal.content.java.mappings.JavaTableGenerator;
import org.eclipse.jpt.core.internal.content.java.mappings.JavaTransient;
import org.eclipse.jpt.core.internal.content.java.mappings.JavaVersion;
import org.eclipse.jpt.core.internal.jdtutility.Attribute;
import org.eclipse.jpt.core.internal.jdtutility.AttributeAnnotationTools;
import org.eclipse.jpt.core.internal.jdtutility.DeclarationAnnotationAdapter;
import org.eclipse.jpt.core.internal.jdtutility.FieldAttribute;
import org.eclipse.jpt.core.internal.jdtutility.MethodAttribute;
import org.eclipse.jpt.core.internal.jdtutility.Type;
import org.eclipse.jpt.core.internal.platform.DefaultsContext;
import org.eclipse.jpt.utility.internal.CommandExecutorProvider;
import org.eclipse.jpt.utility.internal.Filter;
import org.eclipse.jpt.utility.internal.iterators.ChainIterator;
import org.eclipse.jpt.utility.internal.iterators.CloneIterator;
import org.eclipse.jpt.utility.internal.iterators.CompositeIterator;
import org.eclipse.jpt.utility.internal.iterators.FilteringIterator;
import org.eclipse.jpt.utility.internal.iterators.TransformationIterator;

/**
 * <!-- begin-user-doc -->
 * A representation of the model object '<em><b>Java Type</b></em>'.
 * <!-- end-user-doc -->
 *
 * <p>
 * The following features are supported:
 * <ul>
 *   <li>{@link org.eclipse.jpt.core.internal.content.java.JavaPersistentType#getMapping <em>Mapping</em>}</li>
 *   <li>{@link org.eclipse.jpt.core.internal.content.java.JavaPersistentType#getAttributes <em>Attributes</em>}</li>
 *   <li>{@link org.eclipse.jpt.core.internal.content.java.JavaPersistentType#getAccess <em>Access</em>}</li>
 * </ul>
 * </p>
 *
 * @see org.eclipse.jpt.core.internal.content.java.JpaJavaPackage#getJavaPersistentType()
 * @model kind="class"
 * @generated
 */
public class JavaPersistentType extends JavaEObject 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 cached value of the '{@link #getMapping() <em>Mapping</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getMapping()
	 * @generated
	 * @ordered
	 */
	protected IJavaTypeMapping mapping;

	/**
	 * The cached value of the '{@link #getAttributes() <em>Attributes</em>}' containment reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getAttributes()
	 * @generated
	 * @ordered
	 */
	protected EList<JavaPersistentAttribute> attributes;

	/**
	 * The default value of the '{@link #getAccess() <em>Access</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getAccess()
	 * @generated
	 * @ordered
	 */
	protected static final AccessType ACCESS_EDEFAULT = AccessType.DEFAULT;

	/**
	 * The cached value of the '{@link #getAccess() <em>Access</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getAccess()
	 * @generated
	 * @ordered
	 */
	protected AccessType access = ACCESS_EDEFAULT;

	private Type type;

	private DeclarationAnnotationAdapter[] attributeMappingAnnotationAdapters;

	/**
	 * Store the parentPersistentType during default calculation.  This will
	 * be the first persisentType found in the hierarchy, the JPA spec allows
	 * for non-persistent types to be part of the hierarchy.
	 * Example:
	 * 
	 * @Entity public abstract class Model {}
	 * 
	 * public abstract class Animal extends Model {}
	 * 
	 * @Entity public class Cat extends Animal {}
	 * 
	 * If this is the Cat JavaPersistentType then parentPersistentType is the Model JavaPersistentType
	 * The parentPersistentType could be found in java or xml.
	 */
	private IPersistentType parentPersistentType;

	protected JavaPersistentType() {
		throw new UnsupportedOperationException();
	}

	protected JavaPersistentType(Type type) {
		super();
		this.type = type;
		this.attributeMappingAnnotationAdapters = this.buildAttributeMappingAnnotationAdapters();
		this.setMappingGen(this.nullTypeMappingProvider().buildMapping(this.type, null));
	}

	private DeclarationAnnotationAdapter[] buildAttributeMappingAnnotationAdapters() {
		ArrayList<DeclarationAnnotationAdapter> adapters = new ArrayList<DeclarationAnnotationAdapter>();
		this.addAttributeMappingAnnotationAdaptersTo(adapters);
		return adapters.toArray(new DeclarationAnnotationAdapter[adapters.size()]);
	}

	/**
	 * Override this to specify more or different attribute mapping annotation
	 * adapters. The default includes the JPA spec-defined attribute mapping
	 * annotations.
	 */
	protected void addAttributeMappingAnnotationAdaptersTo(Collection<DeclarationAnnotationAdapter> adapters) {
		adapters.add(JavaAssociationOverride.SINGLE_DECLARATION_ANNOTATION_ADAPTER);
		adapters.add(JavaAssociationOverride.MULTIPLE_DECLARATION_ANNOTATION_ADAPTER); // AssociationOverrides
		adapters.add(JavaAttributeOverride.SINGLE_DECLARATION_ANNOTATION_ADAPTER);
		adapters.add(JavaAttributeOverride.MULTIPLE_DECLARATION_ANNOTATION_ADAPTER); // AttributeOverrides
		adapters.add(JavaBasic.DECLARATION_ANNOTATION_ADAPTER);
		adapters.add(JavaColumn.MAPPING_DECLARATION_ANNOTATION_ADAPTER); // standalone Column
		adapters.add(JavaEmbedded.DECLARATION_ANNOTATION_ADAPTER);
		adapters.add(JavaEmbeddedId.DECLARATION_ANNOTATION_ADAPTER);
		adapters.add(JavaBasic.ENUMERATED_ADAPTER);
		adapters.add(JavaGeneratedValue.DECLARATION_ANNOTATION_ADAPTER);
		adapters.add(JavaId.DECLARATION_ANNOTATION_ADAPTER);
		adapters.add(JavaJoinColumn.SINGLE_DECLARATION_ANNOTATION_ADAPTER);
		adapters.add(JavaJoinColumn.MULTIPLE_DECLARATION_ANNOTATION_ADAPTER); // JoinColumns
		adapters.add(JavaJoinTable.DECLARATION_ANNOTATION_ADAPTER);
		adapters.add(JavaBasic.LOB_ADAPTER);
		adapters.add(JavaManyToMany.DECLARATION_ANNOTATION_ADAPTER);
		adapters.add(JavaManyToOne.DECLARATION_ANNOTATION_ADAPTER);
		adapters.add(JavaMultiRelationshipMapping.ORDER_BY_ADAPTER);
		adapters.add(JavaMultiRelationshipMapping.MAP_KEY_ADAPTER);
		adapters.add(JavaOneToMany.DECLARATION_ANNOTATION_ADAPTER);
		adapters.add(JavaOneToOne.DECLARATION_ANNOTATION_ADAPTER);
		adapters.add(JavaPrimaryKeyJoinColumn.MULTIPLE_DECLARATION_ANNOTATION_ADAPTER);
		adapters.add(JavaPrimaryKeyJoinColumn.SINGLE_DECLARATION_ANNOTATION_ADAPTER); // PrimaryKeyJoinColumns
		adapters.add(JavaSequenceGenerator.DECLARATION_ANNOTATION_ADAPTER);
		adapters.add(JavaTableGenerator.DECLARATION_ANNOTATION_ADAPTER);
		adapters.add(JavaBasic.TEMPORAL_ADAPTER);
		adapters.add(JavaTransient.DECLARATION_ANNOTATION_ADAPTER);
		adapters.add(JavaVersion.DECLARATION_ANNOTATION_ADAPTER);
	}

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

	/**
	 * 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.java.JpaJavaPackage#getIPersistentType_MappingKey()
	 * @model required="true"
	 * @generated
	 */
	public String getMappingKey() {
		return mappingKey;
	}

	/**
	 * Sets the value of the '{@link org.eclipse.jpt.core.internal.content.java.JavaPersistentType#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, JpaJavaPackage.JAVA_PERSISTENT_TYPE__MAPPING_KEY, oldMappingKey, mappingKey));
	}

	/**
	 * This is called by the UI, it should not be called when updating
	 * the persistence model from the java model.
	 */
	public void setMappingKey(String newMappingKey) {
		if (newMappingKey == this.mappingKey) {
			return;
		}
		setMapping(buildJavaTypeMapping(newMappingKey));
		setMappingKeyGen(newMappingKey);
	}

	/**
	 * Returns the value of the '<em><b>Mapping</b></em>' containment reference.
	 * <!-- begin-user-doc -->
	 * <p>
	 * If the meaning of the '<em>Mapping</em>' containment reference isn't clear,
	 * there really should be more of a description here...
	 * </p>
	 * <!-- end-user-doc -->
	 * @return the value of the '<em>Mapping</em>' containment reference.
	 * @see #setMapping(IJavaTypeMapping)
	 * @see org.eclipse.jpt.core.internal.content.java.JpaJavaPackage#getJavaPersistentType_Mapping()
	 * @model containment="true" required="true"
	 * @generated
	 */
	public IJavaTypeMapping getMapping() {
		return mapping;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetMapping(IJavaTypeMapping newMapping, NotificationChain msgs) {
		IJavaTypeMapping oldMapping = mapping;
		mapping = newMapping;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, JpaJavaPackage.JAVA_PERSISTENT_TYPE__MAPPING, oldMapping, newMapping);
			if (msgs == null)
				msgs = notification;
			else
				msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * Sets the value of the '{@link org.eclipse.jpt.core.internal.content.java.JavaPersistentType#getMapping <em>Mapping</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @param value the new value of the '<em>Mapping</em>' containment reference.
	 * @see #getMapping()
	 * @generated
	 */
	public void setMappingGen(IJavaTypeMapping newMapping) {
		if (newMapping != mapping) {
			NotificationChain msgs = null;
			if (mapping != null)
				msgs = ((InternalEObject) mapping).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - JpaJavaPackage.JAVA_PERSISTENT_TYPE__MAPPING, null, msgs);
			if (newMapping != null)
				msgs = ((InternalEObject) newMapping).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - JpaJavaPackage.JAVA_PERSISTENT_TYPE__MAPPING, null, msgs);
			msgs = basicSetMapping(newMapping, msgs);
			if (msgs != null)
				msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, JpaJavaPackage.JAVA_PERSISTENT_TYPE__MAPPING, newMapping, newMapping));
	}

	/**
	 * This should not be called when updating the persistence model
	 * from the java model, it should only be called when going in the 
	 * other direction.  This will update the java code appropriately
	 * to the change in mapping in the persistence model.
	 */
	public void setMapping(IJavaTypeMapping newMapping) {
		this.type.removeAnnotation(this.annotationAdapterForTypeMappingKey(this.mapping.getKey()));
		this.type.newMarkerAnnotation(this.annotationAdapterForTypeMappingKey(newMapping.getKey()));
		this.setMappingGen(newMapping);
	}

	private DeclarationAnnotationAdapter annotationAdapterForTypeMappingKey(String typeMappingKey) {
		return this.typeMappingProvider(typeMappingKey).declarationAnnotationAdapter();
	}

	protected Iterator<IJavaTypeMappingProvider> typeMappingProviders() {
		return jpaPlatform().javaTypeMappingProviders();
	}

	private IJavaTypeMappingProvider typeMappingProvider(String typeMappingKey) {
		IJavaTypeMappingProvider javaTypeMappingProvider = jpaPlatform().javaTypeMappingProvider(typeMappingKey);
		if (javaTypeMappingProvider == null) {
			javaTypeMappingProvider = nullTypeMappingProvider();
		}
		return javaTypeMappingProvider;
	}
	
	/**
	 * the "null" type mapping is used when the types is not modified
	 * by a mapping annotation
	 */
	protected IJavaTypeMappingProvider nullTypeMappingProvider() {
		return JavaNullTypeMappingProvider.instance();
	}

	/**
	 * Returns the value of the '<em><b>Attributes</b></em>' containment reference list.
	 * The list contents are of type {@link org.eclipse.jpt.core.internal.content.java.JavaPersistentAttribute}.
	 * <!-- begin-user-doc -->
	 * <p>
	 * If the meaning of the '<em>Attributes</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>Attributes</em>' containment reference list.
	 * @see org.eclipse.jpt.core.internal.content.java.JpaJavaPackage#getJavaPersistentType_Attributes()
	 * @model containment="true"
	 * @generated
	 */
	public EList<JavaPersistentAttribute> getAttributes() {
		if (attributes == null) {
			attributes = new EObjectContainmentEList<JavaPersistentAttribute>(JavaPersistentAttribute.class, this, JpaJavaPackage.JAVA_PERSISTENT_TYPE__ATTRIBUTES);
		}
		return attributes;
	}

	/**
	 * Returns the value of the '<em><b>Access</b></em>' attribute.
	 * The literals are from the enumeration {@link org.eclipse.jpt.core.internal.AccessType}.
	 * <!-- begin-user-doc -->
	 * <p>
	 * If the meaning of the '<em>Access</em>' attribute isn't clear,
	 * there really should be more of a description here...
	 * </p>
	 * <!-- end-user-doc -->
	 * @return the value of the '<em>Access</em>' attribute.
	 * @see org.eclipse.jpt.core.internal.AccessType
	 * @see org.eclipse.jpt.core.internal.content.java.JpaJavaPackage#getJavaPersistentType_Access()
	 * @model changeable="false"
	 * @generated
	 */
	public AccessType getAccess() {
		return access;
	}

	private void setAccess(AccessType newAccess) {
		AccessType oldAccess = access;
		access = newAccess == null ? ACCESS_EDEFAULT : newAccess;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, JpaJavaPackage.JAVA_PERSISTENT_TYPE__ACCESS, oldAccess, access));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case JpaJavaPackage.JAVA_PERSISTENT_TYPE__MAPPING :
				return basicSetMapping(null, msgs);
			case JpaJavaPackage.JAVA_PERSISTENT_TYPE__ATTRIBUTES :
				return ((InternalEList<?>) getAttributes()).basicRemove(otherEnd, msgs);
		}
		return super.eInverseRemove(otherEnd, featureID, msgs);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case JpaJavaPackage.JAVA_PERSISTENT_TYPE__MAPPING_KEY :
				return getMappingKey();
			case JpaJavaPackage.JAVA_PERSISTENT_TYPE__MAPPING :
				return getMapping();
			case JpaJavaPackage.JAVA_PERSISTENT_TYPE__ATTRIBUTES :
				return getAttributes();
			case JpaJavaPackage.JAVA_PERSISTENT_TYPE__ACCESS :
				return getAccess();
		}
		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 JpaJavaPackage.JAVA_PERSISTENT_TYPE__MAPPING_KEY :
				setMappingKey((String) newValue);
				return;
			case JpaJavaPackage.JAVA_PERSISTENT_TYPE__MAPPING :
				setMapping((IJavaTypeMapping) newValue);
				return;
			case JpaJavaPackage.JAVA_PERSISTENT_TYPE__ATTRIBUTES :
				getAttributes().clear();
				getAttributes().addAll((Collection<? extends JavaPersistentAttribute>) newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case JpaJavaPackage.JAVA_PERSISTENT_TYPE__MAPPING_KEY :
				setMappingKey(MAPPING_KEY_EDEFAULT);
				return;
			case JpaJavaPackage.JAVA_PERSISTENT_TYPE__MAPPING :
				setMapping((IJavaTypeMapping) null);
				return;
			case JpaJavaPackage.JAVA_PERSISTENT_TYPE__ATTRIBUTES :
				getAttributes().clear();
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case JpaJavaPackage.JAVA_PERSISTENT_TYPE__MAPPING_KEY :
				return MAPPING_KEY_EDEFAULT == null ? mappingKey != null : !MAPPING_KEY_EDEFAULT.equals(mappingKey);
			case JpaJavaPackage.JAVA_PERSISTENT_TYPE__MAPPING :
				return mapping != null;
			case JpaJavaPackage.JAVA_PERSISTENT_TYPE__ATTRIBUTES :
				return attributes != null && !attributes.isEmpty();
			case JpaJavaPackage.JAVA_PERSISTENT_TYPE__ACCESS :
				return access != ACCESS_EDEFAULT;
		}
		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 JpaJavaPackage.JAVA_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 JpaJavaPackage.JAVA_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(", access: ");
		result.append(access);
		result.append(')');
		return result.toString();
	}

	/**
	 * delegate to the type's project (there is one provider per project)
	 */
	private CommandExecutorProvider modifySharedDocumentCommandExecutorProvider() {
		return this.getJpaProject().modifySharedDocumentCommandExecutorProvider();
	}

	public JavaPersistentAttribute addJavaPersistentAttribute(IMember jdtMember) {
		JavaPersistentAttribute persistentAttribute = createJavaPersistentAttribute(jdtMember);
		getAttributes().add(persistentAttribute);
		return persistentAttribute;
	}

	public JavaPersistentAttribute createJavaPersistentAttribute(IMember member) {
		Attribute attribute = null;
		if (member instanceof IField) {
			attribute = new FieldAttribute((IField) member, this.modifySharedDocumentCommandExecutorProvider());
		}
		else if (member instanceof IMethod) {
			attribute = new MethodAttribute((IMethod) member, this.modifySharedDocumentCommandExecutorProvider());
		}
		else {
			throw new IllegalArgumentException();
		}
		return JpaJavaFactory.eINSTANCE.createJavaPersistentAttribute(attribute);
	}

	private void createAndSetPersistentTypeMappingFromJava(String key) {
		setMappingGen(buildJavaTypeMapping(key));
		setMappingKeyGen(key);
	}

	private IJavaTypeMapping buildJavaTypeMapping(String key) {
		return this.typeMappingProvider(key).buildMapping(this.type, this.jpaFactory());
	}

	public Type getType() {
		return this.type;
	}

	public String fullyQualifiedTypeName() {
		return jdtType().getFullyQualifiedName();
	}

	public IType jdtType() {
		return getType().getJdtMember();
	}

	/**
	 * This implementation of IPersistentType#findJdtType() will
	 * *always* find its type
	 */
	public IType findJdtType() {
		return jdtType();
	}

	public boolean isFor(IType member) {
		return this.type.wraps(member);
	}

	protected void updateFromJava(CompilationUnit astRoot) {
		this.setAccess(this.javaAccessType(astRoot));
		String jpaKey = this.getMapping().getKey();
		String javaKey = this.javaTypeMappingKey(astRoot);
		if (jpaKey != javaKey) {
			this.createAndSetPersistentTypeMappingFromJava(javaKey);
		}
		this.getMapping().updateFromJava(astRoot);
		this.updatePersistentAttributes(astRoot);
	}

	private void updatePersistentAttributes(CompilationUnit astRoot) {
		List<JavaPersistentAttribute> persistentAttributesToRemove = new ArrayList<JavaPersistentAttribute>(getAttributes());
		if (getAccess() == AccessType.FIELD) {
			updatePersistentFields(astRoot, persistentAttributesToRemove);
		}
		else if (getAccess() == AccessType.PROPERTY) {
			updatePersistentProperties(astRoot, persistentAttributesToRemove);
		}
		getAttributes().removeAll(persistentAttributesToRemove);
	}

	private void updatePersistentFields(CompilationUnit astRoot, List<JavaPersistentAttribute> persistentAttributesToRemove) {
		updatePersistentAttributes(astRoot, persistentAttributesToRemove, this.jdtPersistableFields());
	}

	private void updatePersistentProperties(CompilationUnit astRoot, List<JavaPersistentAttribute> persistentAttributesToRemove) {
		updatePersistentAttributes(astRoot, persistentAttributesToRemove, this.jdtPersistableProperties());
	}

	private void updatePersistentAttributes(CompilationUnit astRoot, List<JavaPersistentAttribute> persistentAttributesToRemove, IMember[] members) {
		for (IMember member : members) {
			JavaPersistentAttribute persistentAttribute = persistentAttributeFor(member);
			if (persistentAttribute == null) {
				persistentAttribute = addJavaPersistentAttribute(member);
			}
			else {
				persistentAttributesToRemove.remove(persistentAttribute);
			}
			persistentAttribute.updateFromJava(astRoot);
		}
	}

	private IField[] jdtPersistableFields() {
		return AttributeAnnotationTools.persistableFields(jdtType());
	}

	private IMethod[] jdtPersistableProperties() {
		return AttributeAnnotationTools.persistablePropertyGetters(jdtType());
	}

	private String javaTypeMappingKey(CompilationUnit astRoot) {
		for (Iterator<IJavaTypeMappingProvider> i = this.typeMappingProviders(); i.hasNext();) {
			IJavaTypeMappingProvider provider = i.next();
			if (this.type.containsAnnotation(provider.declarationAnnotationAdapter(), astRoot)) {
				return provider.key();
			}
		}
		return null;
	}

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

	public JavaPersistentAttribute attributeNamed(String attributeName) {
		Iterator<JavaPersistentAttribute> stream = attributesNamed(attributeName);
		return (stream.hasNext()) ? stream.next() : null;
	}

	public IPersistentAttribute resolveAttribute(String attributeName) {
		Iterator<JavaPersistentAttribute> stream = attributesNamed(attributeName);
		if (stream.hasNext()) {
			JavaPersistentAttribute attribute = stream.next();
			return (stream.hasNext()) ? null /*more than one*/: attribute;
		}
		return (parentPersistentType() == null) ? null : parentPersistentType().resolveAttribute(attributeName);
	}

	@Override
	public Iterator<String> candidateValuesFor(int pos, Filter<String> filter, CompilationUnit astRoot) {
		Iterator<String> result = super.candidateValuesFor(pos, filter, astRoot);
		if (result != null) {
			return result;
		}
		Iterator<String> values = this.mapping.candidateValuesFor(pos, filter, astRoot);
		if (values != null) {
			return values;
		}
		for (Iterator<JavaPersistentAttribute> stream = attributes(); stream.hasNext();) {
			values = stream.next().candidateValuesFor(pos, filter, astRoot);
			if (values != null) {
				return values;
			}
		}
		return null;
	}

	public IJpaContentNode contentNodeAt(int offset) {
		for (Iterator<JavaPersistentAttribute> i = attributes(); i.hasNext();) {
			JavaPersistentAttribute persistentAttribute = i.next();
			if (persistentAttribute.includes(offset)) {
				return persistentAttribute;
			}
		}
		return null;
	}

	public boolean includes(int offset) {
		ITextRange fullTextRange = this.fullTextRange();
		if (fullTextRange == null) {
			//This happens if the type no longer exists in the java (rename in editor).
			//The text selection event is fired before the update from java so our
			//model has not yet had a chance to update appropriately.  For now, avoid the NPE, 
			//not sure of the ultimate solution to these 2 threads accessing our model
			return false;
		}
		return fullTextRange.includes(offset);
	}

	public ITextRange fullTextRange() {
		return this.type.textRange();
	}

	public ITextRange validationTextRange() {
		return this.selectionTextRange();
	}

	public ITextRange selectionTextRange() {
		return this.type.nameTextRange();
	}

	public ITextRange getTextRange() {
		return type.textRange();
	}

	private JavaPersistentAttribute persistentAttributeFor(IMember member) {
		for (Iterator<JavaPersistentAttribute> i = attributes(); i.hasNext();) {
			JavaPersistentAttribute attribute = i.next();
			if (attribute.isFor(member)) {
				return attribute;
			}
		}
		return null;
	}

	public Iterator<JavaPersistentAttribute> attributes() {
		return new CloneIterator<JavaPersistentAttribute>(getAttributes());
	}

	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<IPersistentType>(this) {
			@Override
			protected IPersistentType nextLink(IPersistentType pt) {
				return pt.parentPersistentType();
			}
		};
	}

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

	/**
	 * Return the AccessType currently implied by the Java source code:
	 *     - if only Fields are annotated => FIELD
	 *     - if only Properties are annotated => PROPERTY
	 *     - if both Fields and Properties are annotated => FIELD
	 *     - if nothing is annotated
	 *     		- and fields exist => FIELD
	 *     		- and properties exist, but no fields exist => PROPERTY
	 *     		- and neither fields nor properties exist => FIELD
	 */
	private AccessType javaAccessType(CompilationUnit astRoot) {
		IType jdtType = this.jdtType();
		boolean hasPersistableFields = false;
		boolean hasPersistableProperties = false;
		for (IField field : AttributeAnnotationTools.persistableFields(jdtType)) {
			hasPersistableFields = true;
			FieldAttribute fa = new FieldAttribute(field, null); // a bit hacky...
			if (fa.containsAnyAnnotation(this.attributeMappingAnnotationAdapters, astRoot)) {
				// any field is annotated => FIELD
				return AccessType.FIELD;
			}
		}
		for (IMethod method : AttributeAnnotationTools.persistablePropertyGetters(jdtType)) {
			hasPersistableProperties = true;
			MethodAttribute ma = new MethodAttribute(method, null); // a bit hacky...
			if (ma.containsAnyAnnotation(this.attributeMappingAnnotationAdapters, astRoot)) {
				// none of the fields are annotated and a getter is annotated => PROPERTY
				return AccessType.PROPERTY;
			}
		}
		// no annotations exist - default to fields, unless it's *obvious* to use properties
		if (hasPersistableProperties && !hasPersistableFields) {
			return AccessType.PROPERTY;
		}
		return AccessType.FIELD;
	}

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

	private void refreshParentPersistentType(DefaultsContext context) {
		ITypeBinding typeBinding = getType().typeBinding(context.astRoot());
		this.parentPersistentType = parentPersistentType(context, typeBinding);
	}

	public static IPersistentType parentPersistentType(DefaultsContext context, ITypeBinding typeBinding) {
		if (typeBinding == null) {
			return null;
		}
		ITypeBinding superClassTypeBinding = typeBinding.getSuperclass();
		if (superClassTypeBinding == null) {
			return null;
		}
		String fullyQualifiedTypeName = superClassTypeBinding.getQualifiedName();
		IPersistentType possibleParent = context.persistentType(fullyQualifiedTypeName);
		if (possibleParent == null) {
			//TODO look to superclass
			return null;
		}
		if (possibleParent.getMappingKey() != null) {
			return possibleParent;
		}
		return possibleParent.parentPersistentType();
	}
}