/*******************************************************************************
 * Copyright (c) 2006, 2010 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.jpa1.context.orm;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Vector;

import org.eclipse.core.resources.IFile;
import org.eclipse.jpt.core.JpaStructureNode;
import org.eclipse.jpt.core.JptCorePlugin;
import org.eclipse.jpt.core.MappingKeys;
import org.eclipse.jpt.core.context.AccessType;
import org.eclipse.jpt.core.context.PersistentAttribute;
import org.eclipse.jpt.core.context.PersistentType;
import org.eclipse.jpt.core.context.java.JavaAttributeMapping;
import org.eclipse.jpt.core.context.java.JavaPersistentAttribute;
import org.eclipse.jpt.core.context.java.JavaPersistentType;
import org.eclipse.jpt.core.context.orm.EntityMappings;
import org.eclipse.jpt.core.context.orm.OrmAttributeMapping;
import org.eclipse.jpt.core.context.orm.OrmAttributeMappingDefinition;
import org.eclipse.jpt.core.context.orm.OrmPersistentAttribute;
import org.eclipse.jpt.core.context.orm.OrmPersistentType;
import org.eclipse.jpt.core.context.orm.OrmStructureNodes;
import org.eclipse.jpt.core.context.orm.OrmTypeMapping;
import org.eclipse.jpt.core.context.orm.OrmTypeMappingDefinition;
import org.eclipse.jpt.core.internal.context.orm.AbstractOrmXmlContextNode;
import org.eclipse.jpt.core.internal.validation.DefaultJpaValidationMessages;
import org.eclipse.jpt.core.internal.validation.JpaValidationMessages;
import org.eclipse.jpt.core.jpa2.JpaFactory2_0;
import org.eclipse.jpt.core.jpa2.context.PersistentType2_0;
import org.eclipse.jpt.core.jpa2.context.orm.OrmPersistentType2_0;
import org.eclipse.jpt.core.resource.java.JavaResourcePersistentAttribute;
import org.eclipse.jpt.core.resource.java.JavaResourcePersistentType;
import org.eclipse.jpt.core.resource.orm.Attributes;
import org.eclipse.jpt.core.resource.orm.OrmPackage;
import org.eclipse.jpt.core.resource.orm.XmlAttributeMapping;
import org.eclipse.jpt.core.resource.orm.XmlTypeMapping;
import org.eclipse.jpt.core.resource.xml.EmfTools;
import org.eclipse.jpt.core.utility.TextRange;
import org.eclipse.jpt.utility.internal.ClassName;
import org.eclipse.jpt.utility.internal.CollectionTools;
import org.eclipse.jpt.utility.internal.StringTools;
import org.eclipse.jpt.utility.internal.Tools;
import org.eclipse.jpt.utility.internal.iterables.CompositeIterable;
import org.eclipse.jpt.utility.internal.iterables.LiveCloneIterable;
import org.eclipse.jpt.utility.internal.iterators.ChainIterator;
import org.eclipse.jpt.utility.internal.iterators.CloneListIterator;
import org.eclipse.jpt.utility.internal.iterators.CompositeIterator;
import org.eclipse.jpt.utility.internal.iterators.CompositeListIterator;
import org.eclipse.jpt.utility.internal.iterators.EmptyListIterator;
import org.eclipse.jpt.utility.internal.iterators.FilteringIterator;
import org.eclipse.jpt.utility.internal.iterators.TransformationIterator;
import org.eclipse.wst.validation.internal.provisional.core.IMessage;
import org.eclipse.wst.validation.internal.provisional.core.IReporter;

/**
 * ORM persistent type:<ul>
 * <li>mapping
 * <li>access
 * <li>attributes
 * <li>super persistent type
 * <li>Java persistent type
 * </ul>
 */
public class GenericOrmPersistentType
	extends AbstractOrmXmlContextNode
	implements OrmPersistentType2_0
{
	protected OrmTypeMapping mapping;

	protected AccessType defaultAccess;

	protected AccessType specifiedAccess;

	protected final Vector<OrmPersistentAttribute> specifiedAttributes = new Vector<OrmPersistentAttribute>();

	protected final Vector<OrmPersistentAttribute> virtualAttributes = new Vector<OrmPersistentAttribute>();

	protected PersistentType superPersistentType;

	protected JavaPersistentType javaPersistentType;

	protected final PersistentType2_0.MetamodelSynchronizer metamodelSynchronizer;


	public GenericOrmPersistentType(EntityMappings parent, XmlTypeMapping resourceMapping) {
		super(parent);
		this.mapping = this.buildMapping(resourceMapping);
		this.specifiedAccess = this.buildSpecifiedAccess();
		this.defaultAccess = this.buildDefaultAccess();
		this.javaPersistentType = this.buildJavaPersistentType();
		this.superPersistentType = this.buildSuperPersistentType();
		this.initializeAttributes();
		this.metamodelSynchronizer = this.buildMetamodelSynchronizer();
	}

	protected PersistentType2_0.MetamodelSynchronizer buildMetamodelSynchronizer() {
		return ((JpaFactory2_0) this.getJpaFactory()).buildPersistentTypeMetamodelSynchronizer(this);
	}


	// ********** update **********

	public void update() {
		this.setSpecifiedAccess(this.buildSpecifiedAccess());
		this.setDefaultAccess(this.buildDefaultAccess());
		this.mapping.update();
		this.updateJavaPersistentType();
		this.updateSuperPersistentType();
		this.updateAttributes();
	}

	@Override
	public void postUpdate() {
		super.postUpdate();
		if (this.javaPersistentType != null) {
			this.javaPersistentType.postUpdate();
		}
		this.mapping.postUpdate();
		for (PersistentAttribute attribute : this.getAttributes()) {
			attribute.postUpdate();
		}
	}


	// ********** name **********

	public String getName() {
		return this.mapping.getClass_();
	}

	public String getShortName(){
		String className = this.getName();
		return StringTools.stringIsEmpty(className) ? null : ClassName.getSimpleName(className);
	}


	// ********** mapping **********

	public OrmTypeMapping getMapping() {
		return this.mapping;
	}

	public void setMappingKey(String newMappingKey) {
		if (this.valuesAreEqual(this.getMappingKey(), newMappingKey)) {
			return;
		}
		OrmTypeMapping oldMapping = this.mapping;
		OrmTypeMappingDefinition mappingDefinition = this.getMappingFileDefinition().getOrmTypeMappingDefinition(newMappingKey);
		XmlTypeMapping resourceTypeMapping = mappingDefinition.buildResourceMapping(this.getResourceNodeFactory());
		this.mapping = this.buildMapping(resourceTypeMapping);
		this.getEntityMappings().changeMapping(this, oldMapping, this.mapping);
		this.firePropertyChanged(MAPPING_PROPERTY, oldMapping, this.mapping);
	}

	protected OrmTypeMapping buildMapping(XmlTypeMapping resourceMapping) {
		OrmTypeMappingDefinition mappingDefintion = this.getMappingFileDefinition().getOrmTypeMappingDefinition(resourceMapping.getMappingKey());
		return mappingDefintion.buildContextMapping(this, resourceMapping, this.getXmlContextNodeFactory());
	}


	// ********** access **********

	public AccessType getAccess() {
		return (this.specifiedAccess != null) ? this.specifiedAccess : this.defaultAccess;
	}

	public AccessType getDefaultAccess() {
		return this.defaultAccess;
	}

	protected void setDefaultAccess(AccessType defaultAccess) {
		AccessType old = this.defaultAccess;
		this.defaultAccess = defaultAccess;
		this.firePropertyChanged(DEFAULT_ACCESS_PROPERTY, old, defaultAccess);
	}

	public AccessType getSpecifiedAccess() {
		return this.specifiedAccess;
	}

	public void setSpecifiedAccess(AccessType specifiedAccess) {
		AccessType old = this.specifiedAccess;
		this.specifiedAccess = specifiedAccess;
		this.getResourceTypeMapping().setAccess(AccessType.toOrmResourceModel(specifiedAccess));
		this.firePropertyChanged(SPECIFIED_ACCESS_PROPERTY, old, specifiedAccess);
	}

	protected AccessType buildDefaultAccess() {
		if ( ! this.mapping.isMetadataComplete()) {
			if (this.javaPersistentType != null) {
				if (this.javaPersistentTypeHasSpecifiedAccess()) {
					return this.javaPersistentType.getAccess();
				}
				if (this.superPersistentType != null) {
					return this.superPersistentType.getAccess();
				}
			}
		}
		AccessType access = this.getMappingFileRoot().getAccess();
		return (access != null) ? access : AccessType.FIELD; //default to FIELD if no specified access found
	}

	protected boolean javaPersistentTypeHasSpecifiedAccess() {
		return (this.javaPersistentType.getSpecifiedAccess() != null) || 
				this.javaPersistentType.hasAnyAnnotatedAttributes();
	}

	public AccessType getOwnerOverrideAccess() {
		return this.getEntityMappings().getOverridePersistentTypeAccess();
	}

	public AccessType getOwnerDefaultAccess() {
		return this.getEntityMappings().getDefaultPersistentTypeAccess();
	}

	protected AccessType buildSpecifiedAccess() {
		return AccessType.fromOrmResourceModel(this.getResourceTypeMapping().getAccess());
	}


	// ********** attributes **********

	@SuppressWarnings("unchecked")
	public ListIterator<OrmPersistentAttribute> attributes() {
		return new CompositeListIterator<OrmPersistentAttribute>(this.specifiedAttributes(), this.virtualAttributes());
	}

	@SuppressWarnings("unchecked")
	protected Iterable<OrmPersistentAttribute> getAttributes() {
		return new CompositeIterable<OrmPersistentAttribute>(this.getSpecifiedAttributes(), this.getVirtualAttributes());
	}

	public int attributesSize() {
		return this.specifiedAttributesSize() + this.virtualAttributesSize();
	}

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

	public Iterator<PersistentAttribute> allAttributes() {
		return new CompositeIterator<PersistentAttribute>(
				new TransformationIterator<PersistentType, Iterator<PersistentAttribute>>(this.inheritanceHierarchy()) {
					@Override
					protected Iterator<PersistentAttribute> transform(PersistentType pt) {
						return pt.attributes();
					}
				}
			);
	}

	protected Iterator<OrmPersistentAttribute> attributesNamed(final String attributeName) {
		return new FilteringIterator<OrmPersistentAttribute>(this.attributes()) {
			@Override
			protected boolean accept(OrmPersistentAttribute o) {
				return Tools.valuesAreEqual(attributeName, o.getName());
			}
		};
	}

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

	public PersistentAttribute resolveAttribute(String attributeName) {
		Iterator<OrmPersistentAttribute> attributes = this.attributesNamed(attributeName);
		if (attributes.hasNext()) {
			OrmPersistentAttribute attribute = attributes.next();
			return attributes.hasNext() ? null /* more than one */: attribute;
		}
		return (this.superPersistentType == null) ? null : this.superPersistentType.resolveAttribute(attributeName);
	}

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

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

	protected void initializeAttributes() {
		this.initializeSpecifiedAttributes();
		this.initializeVirtualAttributes();
	}

	protected void updateAttributes() {
		this.updateSpecifiedAttributes();
		this.updateVirtualAttributes();
	}

	protected Iterator<JavaResourcePersistentAttribute> javaPersistentAttributes() {
		return (this.javaPersistentType == null) ?
				EmptyListIterator.<JavaResourcePersistentAttribute>instance() :
				this.javaPersistentAttributes(this.javaPersistentType.getResourcePersistentType());
	}

	protected Iterator<JavaResourcePersistentAttribute> javaPersistentAttributes(JavaResourcePersistentType resourcePersistentType) {
		AccessType access = this.specifiedAccess;
		if (access == null && ! this.mapping.isMetadataComplete()) {
			access = this.getJavaPersistentType().getSpecifiedAccess();
		}
		if (access == null) {
			access = this.defaultAccess;
		}
		return resourcePersistentType.persistableAttributes(AccessType.toJavaResourceModel(access));
	}


	// ********** specified attributes **********

	public ListIterator<OrmPersistentAttribute> specifiedAttributes() {
		return new CloneListIterator<OrmPersistentAttribute>(this.specifiedAttributes);
	}

	protected Iterable<OrmPersistentAttribute> getSpecifiedAttributes() {
		return new LiveCloneIterable<OrmPersistentAttribute>(this.specifiedAttributes);
	}

	public int specifiedAttributesSize() {
		return this.specifiedAttributes.size();
	}

	protected OrmPersistentAttribute getSpecifiedAttributeFor(final JavaResourcePersistentAttribute jrpa) {
		for (OrmPersistentAttribute attribute : this.getSpecifiedAttributes()) {
			JavaPersistentAttribute javaAttribute = attribute.getJavaPersistentAttribute();
			if ((javaAttribute != null) && (javaAttribute.getResourcePersistentAttribute() == jrpa)) {
				return attribute;
			}
		}
		return null;
	}

	public OrmPersistentAttribute addSpecifiedAttribute(String mappingKey, String attributeName) {
		Attributes resourceAttributes = this.getResourceAttributes();
		if (resourceAttributes == null) {
			resourceAttributes = this.createResourceAttributes();
			this.mapping.getResourceTypeMapping().setAttributes(resourceAttributes);
		}

		OrmAttributeMappingDefinition mappingDefintion = this.getMappingFileDefinition().getOrmAttributeMappingDefinition(mappingKey);
		XmlAttributeMapping resourceMapping = mappingDefintion.buildResourceMapping(getResourceNodeFactory());
		OrmPersistentAttribute persistentAttribute = this.buildSpecifiedAttribute(resourceMapping);
		int index = this.getSpecifiedAttributeInsertionIndex(persistentAttribute);
		this.specifiedAttributes.add(index, persistentAttribute);
		persistentAttribute.getMapping().addToResourceModel(resourceAttributes);

		persistentAttribute.getSpecifiedMapping().setName(attributeName);
		this.fireItemAdded(ATTRIBUTES_LIST, index, persistentAttribute);
		return persistentAttribute;
	}

	public void changeMapping(OrmPersistentAttribute ormPersistentAttribute, OrmAttributeMapping oldMapping, OrmAttributeMapping newMapping) {
		int sourceIndex = this.specifiedAttributes.indexOf(ormPersistentAttribute);
		this.specifiedAttributes.remove(sourceIndex);
		oldMapping.removeFromResourceModel(this.getResourceAttributes());
		int targetIndex = getSpecifiedAttributeInsertionIndex(ormPersistentAttribute);
		this.specifiedAttributes.add(targetIndex, ormPersistentAttribute);
		newMapping.addToResourceModel(this.getResourceAttributes());
		oldMapping.initializeOn(newMapping);
		this.fireItemMoved(ATTRIBUTES_LIST, targetIndex, sourceIndex);
	}

	public void makeAttributeSpecified(OrmPersistentAttribute ormPersistentAttribute) {
		this.makeAttributeSpecified(ormPersistentAttribute, ormPersistentAttribute.getMappingKey());
	}

	public void makeAttributeSpecified(OrmPersistentAttribute ormPersistentAttribute, String mappingKey) {
		if ( ! ormPersistentAttribute.isVirtual()) {
			throw new IllegalStateException("Attribute is already specified"); //$NON-NLS-1$
		}
		if (this.valuesAreEqual(mappingKey, MappingKeys.NULL_ATTRIBUTE_MAPPING_KEY)) {
			throw new IllegalStateException("Use makePersistentAttributeSpecified(OrmPersistentAttribute, String) instead and specify a mapping type"); //$NON-NLS-1$
		}

		Attributes resourceAttributes = this.getResourceAttributes();
		if (resourceAttributes == null) {
			resourceAttributes = this.createResourceAttributes();
			this.mapping.getResourceTypeMapping().setAttributes(resourceAttributes);
		}

		OrmAttributeMappingDefinition mappingDefintion = this.getMappingFileDefinition().getOrmAttributeMappingDefinition(mappingKey);
		XmlAttributeMapping resourceMapping = mappingDefintion.buildResourceMapping(getResourceNodeFactory());

		OrmPersistentAttribute newAttribute = this.buildSpecifiedAttribute(resourceMapping);
		int insertionIndex = this.getSpecifiedAttributeInsertionIndex(newAttribute);
		this.specifiedAttributes.add(insertionIndex, newAttribute);
		newAttribute.getMapping().addToResourceModel(resourceAttributes);

		int removalIndex = this.virtualAttributes.indexOf(ormPersistentAttribute);
		this.virtualAttributes.remove(ormPersistentAttribute);
		newAttribute.getSpecifiedMapping().setName(ormPersistentAttribute.getName());
		if (ormPersistentAttribute.getJavaPersistentAttribute().getSpecifiedAccess() != null) {
			newAttribute.setSpecifiedAccess(ormPersistentAttribute.getJavaPersistentAttribute().getSpecifiedAccess());
		}

		this.fireItemAdded(ATTRIBUTES_LIST, insertionIndex, newAttribute);
		this.fireItemRemoved(VIRTUAL_ATTRIBUTES_LIST, removalIndex, ormPersistentAttribute);
	}

	protected int getSpecifiedAttributeInsertionIndex(OrmPersistentAttribute specifiedAttribute) {
		return CollectionTools.insertionIndexOf(this.specifiedAttributes, specifiedAttribute, this.getAttributeComparator());
	}

	protected Comparator<OrmPersistentAttribute> getAttributeComparator() {
		return ATTRIBUTE_COMPARATOR;
	}

	protected static final Comparator<OrmPersistentAttribute> ATTRIBUTE_COMPARATOR = 
		new Comparator<OrmPersistentAttribute>() {
			public int compare(OrmPersistentAttribute o1, OrmPersistentAttribute o2) {
				int o1Sequence = o1.getMapping().getXmlSequence();
				int o2Sequence = o2.getMapping().getXmlSequence();
				return (o1Sequence == o2Sequence) ? 0 : (o1Sequence < o2Sequence) ? -1 : 1;
			}
		};

	protected Attributes getResourceAttributes() {
		return this.getResourceTypeMapping().getAttributes();
	}

	protected Attributes createResourceAttributes() {
		return EmfTools.create(this.getResourceNodeFactory(), OrmPackage.eINSTANCE.getAttributes(), Attributes.class);
	}

	protected void initializeSpecifiedAttributes() {
		Attributes attributes = this.getResourceAttributes();
		if (attributes == null) {
			return;
		}
		for (XmlAttributeMapping resourceMapping : attributes.getAttributeMappings()) {
			this.addSpecifiedAttribute(resourceMapping);
		}
	}

	protected void updateSpecifiedAttributes() {
		Attributes attributes = this.getResourceAttributes();
		Collection<OrmPersistentAttribute> contextAttributesToRemove = CollectionTools.collection(this.specifiedAttributes());
		Collection<OrmPersistentAttribute> contextAttributesToUpdate = new ArrayList<OrmPersistentAttribute>();
		int resourceIndex = 0;

		if (attributes != null) {
			for (XmlAttributeMapping resourceMapping : attributes.getAttributeMappings()) {
				boolean contextAttributeFound = false;
				for (OrmPersistentAttribute contextAttribute : contextAttributesToRemove) {
					if (contextAttribute.getMapping().getResourceAttributeMapping() == resourceMapping) {
						this.moveSpecifiedAttribute_(resourceIndex, contextAttribute);
						contextAttributesToRemove.remove(contextAttribute);
						contextAttributesToUpdate.add(contextAttribute);
						contextAttributeFound = true;
						break;
					}
				}
				if ( ! contextAttributeFound) {
					OrmPersistentAttribute ormPersistentAttribute = this.addSpecifiedAttribute(resourceMapping);
					this.fireItemAdded(ATTRIBUTES_LIST, specifiedAttributesSize(), ormPersistentAttribute);
				}
				resourceIndex++;
			}
		}
		for (OrmPersistentAttribute contextAttribute : contextAttributesToRemove) {
			this.removeSpecifiedAttribute_(contextAttribute);
		}
		//first handle adding/removing of the persistent attributes, then update the others last, 
		//this causes less churn in the update process
		for (OrmPersistentAttribute contextAttribute : contextAttributesToUpdate) {
			contextAttribute.update();
		}
	}

	protected void removeSpecifiedAttribute_(OrmPersistentAttribute ormPersistentAttribute) {
		this.removeItemFromList(ormPersistentAttribute, this.specifiedAttributes, ATTRIBUTES_LIST);
	}

	//not firing change notification so this can be reused in initialize and update
	protected OrmPersistentAttribute addSpecifiedAttribute(XmlAttributeMapping resourceMapping) {
		OrmPersistentAttribute ormPersistentAttribute = this.buildSpecifiedAttribute(resourceMapping);
		this.specifiedAttributes.add(ormPersistentAttribute);
		return ormPersistentAttribute;
	}

	protected void moveSpecifiedAttribute_(int index, OrmPersistentAttribute attribute) {
		this.moveItemInList(index, this.specifiedAttributes.indexOf(attribute), this.specifiedAttributes, ATTRIBUTES_LIST);
	}

	public void removeSpecifiedAttribute(OrmPersistentAttribute ormPersistentAttribute) {
		int index = this.specifiedAttributes.indexOf(ormPersistentAttribute);
		this.specifiedAttributes.remove(ormPersistentAttribute);
		ormPersistentAttribute.getMapping().removeFromResourceModel(this.getResourceAttributes());
		if (this.getResourceAttributes().isUnset()) {
			this.mapping.getResourceTypeMapping().setAttributes(null);
		}
		this.fireItemRemoved(ATTRIBUTES_LIST, index, ormPersistentAttribute);
	}

	protected OrmPersistentAttribute buildSpecifiedAttribute(XmlAttributeMapping resourceMapping) {
		return this.buildOrmPersistentAttribute(this.buildSpecifiedAttributeOwner(), resourceMapping);
	}

	protected OrmPersistentAttribute.Owner buildSpecifiedAttributeOwner() {
		return new SpecifiedAttributeOwner();
	}

	protected JavaPersistentAttribute buildJavaPersistentAttribute(JavaResourcePersistentAttribute jrpa) {
		return this.getJpaFactory().buildJavaPersistentAttribute(this, jrpa);
	}


	// ********** virtual attributes **********

	public ListIterator<OrmPersistentAttribute> virtualAttributes() {
		return new CloneListIterator<OrmPersistentAttribute>(this.virtualAttributes);
	}

	protected Iterable<OrmPersistentAttribute> getVirtualAttributes() {
		return new LiveCloneIterable<OrmPersistentAttribute>(this.virtualAttributes);
	}

	public int virtualAttributesSize() {
		return this.virtualAttributes.size();
	}

	protected void addVirtualAttribute(OrmPersistentAttribute virtualAttribute) {
		this.addItemToList(virtualAttribute, this.virtualAttributes, VIRTUAL_ATTRIBUTES_LIST);
	}

	protected void removeVirtualAttribute(OrmPersistentAttribute virtualAttribute) {
		this.removeItemFromList(virtualAttribute, this.virtualAttributes, VIRTUAL_ATTRIBUTES_LIST);
	}

	protected void moveVirtualAttribute_(int index, OrmPersistentAttribute virtualAttribute) {
		this.moveItemInList(index, this.virtualAttributes.indexOf(virtualAttribute), this.virtualAttributes, VIRTUAL_ATTRIBUTES_LIST);
	}

	public boolean containsVirtualAttribute(OrmPersistentAttribute ormPersistentAttribute) {
		return this.virtualAttributes.contains(ormPersistentAttribute);
	}

	public void makeAttributeVirtual(OrmPersistentAttribute ormPersistentAttribute) {
		if (ormPersistentAttribute.isVirtual()) {
			throw new IllegalStateException("Attribute is already virtual"); //$NON-NLS-1$
		}
		JavaPersistentAttribute javaPersistentAttribute = ormPersistentAttribute.getJavaPersistentAttribute();
		OrmPersistentAttribute virtualAttribute = null;
		if (javaPersistentAttribute != null) {
			virtualAttribute = this.addVirtualAttribute(javaPersistentAttribute.getResourcePersistentAttribute());
		}
		this.removeSpecifiedAttribute(ormPersistentAttribute);
		if (virtualAttribute != null) {
			this.fireItemAdded(VIRTUAL_ATTRIBUTES_LIST, virtualAttributesSize() - 1, virtualAttribute);
		}
	}

	protected void initializeVirtualAttributes() {
		for (Iterator<JavaResourcePersistentAttribute> stream = this.javaPersistentAttributes(); stream.hasNext(); ) {
			JavaResourcePersistentAttribute javaResourceAttribute = stream.next();
			if (this.getSpecifiedAttributeFor(javaResourceAttribute) == null) {
				this.addVirtualAttribute(javaResourceAttribute);
			}
		}
	}

	protected void updateVirtualAttributes() {
		Collection<OrmPersistentAttribute> contextAttributesToRemove = CollectionTools.collection(this.virtualAttributes());
		Collection<OrmPersistentAttribute> contextAttributesToUpdate = new ArrayList<OrmPersistentAttribute>();
		int resourceIndex = 0;

		for (Iterator<JavaResourcePersistentAttribute> stream = this.javaPersistentAttributes(); stream.hasNext(); ) {
			JavaResourcePersistentAttribute javaResourceAttribute = stream.next();
			OrmPersistentAttribute specifiedAttribute = this.getSpecifiedAttributeFor(javaResourceAttribute);
			if (specifiedAttribute == null) {
				JavaPersistentAttribute javaAttribute = this.getJpaFactory().buildJavaPersistentAttribute(this, javaResourceAttribute);
				JavaAttributeMapping javaAttributeMapping = javaAttribute.getMapping();
				if (this.mapping.isMetadataComplete()) {
					javaAttributeMapping = javaAttribute.getDefaultMapping();
				}
				boolean contextAttributeFound = false;
				for (OrmPersistentAttribute contextAttribute : contextAttributesToRemove) {
					JavaPersistentAttribute javaPersistentAttribute = contextAttribute.getJavaPersistentAttribute();
					if (javaPersistentAttribute.getResourcePersistentAttribute() == javaResourceAttribute) {
						if (this.valuesAreEqual(contextAttribute.getMappingKey(), javaAttributeMapping.getKey())) { 
							//the mapping key would change if metaDataComplete flag changes, rebuild the orm attribute
							this.moveVirtualAttribute_(resourceIndex, contextAttribute);
							contextAttributesToRemove.remove(contextAttribute);
							contextAttributesToUpdate.add(contextAttribute);
							contextAttributeFound = true;
							break;
						}
					}
				}
				if ( ! contextAttributeFound) {
					OrmPersistentAttribute virtualAttribute = this.addVirtualAttribute(javaAttributeMapping);
					this.fireItemAdded(VIRTUAL_ATTRIBUTES_LIST, virtualAttributesSize() - 1, virtualAttribute);
				}
				resourceIndex++;
			}
		}

		for (OrmPersistentAttribute contextAttribute : contextAttributesToRemove) {
			this.removeVirtualAttribute(contextAttribute);
		}
		//first handle adding/removing of the persistent attributes, then update the others last, 
		//this causes less churn in the update process
		for (OrmPersistentAttribute contextAttribute : contextAttributesToUpdate) {
			contextAttribute.update();
		}
	}

	protected OrmPersistentAttribute addVirtualAttribute(JavaResourcePersistentAttribute resourceAttribute) {
		JavaPersistentAttribute javaAttribute = this.getJpaFactory().buildJavaPersistentAttribute(this, resourceAttribute);
		JavaAttributeMapping javaAttributeMapping = javaAttribute.getMapping();
		if (this.mapping.isMetadataComplete()) {
			javaAttributeMapping = javaAttribute.getDefaultMapping();
		}
		return this.addVirtualAttribute(javaAttributeMapping);
	}

	//not firing change notification so this can be reused in initialize and update
	protected OrmPersistentAttribute addVirtualAttribute(JavaAttributeMapping javaAttributeMapping) {
		OrmAttributeMappingDefinition mappingDefintion = this.getMappingFileDefinition().getOrmAttributeMappingDefinition(javaAttributeMapping.getKey());
		XmlAttributeMapping resourceMapping = mappingDefintion.buildVirtualResourceMapping(this.mapping, javaAttributeMapping, this.getXmlContextNodeFactory());
		OrmPersistentAttribute virtualAttribute = this.buildVirtualOrmPersistentAttribute(javaAttributeMapping, resourceMapping);
		this.virtualAttributes.add(virtualAttribute);
		return virtualAttribute;
	}

	protected OrmPersistentAttribute buildVirtualOrmPersistentAttribute(JavaAttributeMapping javaAttributeMapping, XmlAttributeMapping resourceMapping) {
		return this.buildOrmPersistentAttribute(this.buildVirtualAttributeOwner(javaAttributeMapping.getPersistentAttribute()), resourceMapping);
	}

	protected OrmPersistentAttribute buildOrmPersistentAttribute(OrmPersistentAttribute.Owner owner, XmlAttributeMapping resourceMapping) {
		return this.getXmlContextNodeFactory().buildOrmPersistentAttribute(this, owner, resourceMapping);
	}

	protected OrmPersistentAttribute.Owner buildVirtualAttributeOwner(final JavaPersistentAttribute javaPersistentAttribute) {
		return new OrmPersistentAttribute.Owner() {
			public JavaPersistentAttribute findJavaPersistentAttribute(OrmPersistentAttribute ormPersistentAttribute) {
				return javaPersistentAttribute;
			}

			public void updateJavaPersistentAttribute() {
				//update the attribute, since we own it and it will not get updated otherwise
				javaPersistentAttribute.update();
			}
		};
	}


	// ********** Java persistent type **********

	public JavaPersistentType getJavaPersistentType() {
		return this.javaPersistentType;
	}

	protected void setJavaPersistentType(JavaPersistentType javaPersistentType) {
		JavaPersistentType old = this.javaPersistentType;
		this.javaPersistentType = javaPersistentType;
		this.firePropertyChanged(JAVA_PERSISTENT_TYPE_PROPERTY, old, javaPersistentType);
	}

	protected JavaPersistentType buildJavaPersistentType() {
		JavaResourcePersistentType jrpt = this.getJavaResourcePersistentType();
		return (jrpt == null) ? null : this.buildJavaPersistentType(jrpt);
	}

	protected JavaResourcePersistentType getJavaResourcePersistentType() {
		String className = this.getName();
		if (className == null) {
			return null;
		}
		className = className.replace('$', '.');

		// first try to resolve using only the locally specified name...
		JavaResourcePersistentType jrpt = this.getJavaResourcePersistentType(className);
		if (jrpt != null) {
			return jrpt;
		}

		// ...then try to resolve by prepending the global package name
		String defaultPackage = this.getDefaultPackage();
		if (defaultPackage == null) {
			return null;
		}
		return this.getJavaResourcePersistentType(defaultPackage + '.' +  className);
	}

	protected JavaResourcePersistentType getJavaResourcePersistentType(String className) {
		return this.getJpaProject().getJavaResourcePersistentType(className);
	}

	protected JavaPersistentType buildJavaPersistentType(JavaResourcePersistentType jrpt) {
		return getJpaFactory().buildJavaPersistentType(this, jrpt);
	}

	protected void updateJavaPersistentType() {
		JavaResourcePersistentType jrpt = this.getJavaResourcePersistentType();
		if (jrpt == null) {
			this.setJavaPersistentType(null);
		} else { 
			if (this.javaPersistentType == null) {
				this.setJavaPersistentType(this.buildJavaPersistentType(jrpt));
			} else {
				this.javaPersistentType.update(jrpt);
			}
		}
	}


	// ********** super persistent type **********

	public PersistentType getSuperPersistentType() {
		return this.superPersistentType;
	}

	protected void setSuperPersistentType(PersistentType superPersistentType) {
		PersistentType old = this.superPersistentType;
		this.superPersistentType = superPersistentType;
		this.firePropertyChanged(SUPER_PERSISTENT_TYPE_PROPERTY, old, superPersistentType);
	}

	protected void updateSuperPersistentType() {
		PersistentType spt = this.buildSuperPersistentType();
		// check for circular inheritance
		if ((spt == null) || CollectionTools.contains(spt.inheritanceHierarchy(), this)) {
			this.setSuperPersistentType(null);
		} else {
			this.setSuperPersistentType(spt);
		}
	}

	protected PersistentType buildSuperPersistentType() {
		return (this.javaPersistentType == null) ? null : this.javaPersistentType.getSuperPersistentType();
	}


	// ********** inheritance **********

	public Iterator<PersistentType> inheritanceHierarchy() {
		return this.inheritanceHierarchyOf(this);
	}

	public Iterator<PersistentType> ancestors() {
		return this.inheritanceHierarchyOf(this.superPersistentType);
	}

	protected Iterator<PersistentType> inheritanceHierarchyOf(PersistentType start) {
		// using a chain iterator to traverse up the inheritance tree
		return new ChainIterator<PersistentType>(start) {
			@Override
			protected PersistentType nextLink(PersistentType persistentType) {
				return persistentType.getSuperPersistentType();
			}
		};
	}


	// ********** metamodel **********

	public IFile getMetamodelFile() {
		return (this.javaPersistentType == null) ? null : this.metamodelSynchronizer.getFile();
	}

	public void initializeMetamodel() {
		// do nothing - probably shouldn't be called...
	}

	/**
	 * All orm.xml persistent types must be able to generate a static metamodel
	 * because 1.0 orm.xml files can be referenced from 2.0 persistence.xml files.
	 */
	public void synchronizeMetamodel() {
		if (this.javaPersistentType != null) {
			this.metamodelSynchronizer.synchronize();
		}
	}

	public void disposeMetamodel() {
		// do nothing - probably shouldn't be called...
	}


	// ********** JpaStructureNode implementation **********

	public String getId() {
		return OrmStructureNodes.PERSISTENT_TYPE_ID;
	}

	public JpaStructureNode getStructureNode(int textOffset) {
		for (OrmPersistentAttribute attribute : this.getSpecifiedAttributes()) {
			if (attribute.contains(textOffset)) {
				return attribute;
			}
		}
		return this;
	}

	public TextRange getSelectionTextRange() {
		return this.mapping.getSelectionTextRange();
	}

	public void dispose() {
		if (this.javaPersistentType != null) {
			this.javaPersistentType.dispose();
		}
	}


	// ********** PersistentType.Owner implementation **********

	public AccessType getOverridePersistentTypeAccess() {
		if (this.specifiedAccess != null) {
			return this.specifiedAccess;
		}

		if (this.superPersistentType instanceof OrmPersistentType) {
			AccessType accessType = ((OrmPersistentType) this.superPersistentType).getSpecifiedAccess();
			if (accessType != null) {
				return accessType;
			}
		}

		if (this.mapping.isMetadataComplete()) {
			AccessType accessType = this.getOwnerDefaultAccess();
			if (accessType != null) {
				return accessType;
			}
		}

		// no override access type
		return null;
	}

	public AccessType getDefaultPersistentTypeAccess() {
		if (this.superPersistentType instanceof OrmPersistentType) {
			AccessType accessType = ((OrmPersistentType) this.superPersistentType).getDefaultAccess();
			if (accessType != null) {
				return accessType;
			}
		}

		return this.getOwnerDefaultAccess();
	}


	// ********** validation **********

	@Override
	public void validate(List<IMessage> messages, IReporter reporter) {
		super.validate(messages, reporter);
		this.validateClass(messages);
		this.validateMapping(messages, reporter);
		this.validateAttributes(messages, reporter);
	}

	protected void validateClass(List<IMessage> messages) {
		if (this.javaPersistentType == null) {
			messages.add(
				DefaultJpaValidationMessages.buildMessage(
					IMessage.HIGH_SEVERITY,
					JpaValidationMessages.PERSISTENT_TYPE_UNRESOLVED_CLASS,
					new String[] {this.getName()},
					this, 
					this.mapping.getClassTextRange()
				)
			);
		}
	}

	protected void validateMapping(List<IMessage> messages, IReporter reporter) {
		try {
			this.mapping.validate(messages, reporter);
		} catch(Throwable t) {
			JptCorePlugin.log(t);
		}
	}

	protected void validateAttributes(List<IMessage> messages, IReporter reporter) {
		for (Iterator<OrmPersistentAttribute> stream = this.attributes(); stream.hasNext(); ) {
			this.validateAttribute(stream.next(), messages, reporter);
		}
	}

	protected void validateAttribute(OrmPersistentAttribute attribute, List<IMessage> messages, IReporter reporter) {
		try {
			attribute.validate(messages, reporter);
		} catch(Throwable t) {
			JptCorePlugin.log(t);
		}
	}

	public TextRange getValidationTextRange() {
		return this.mapping.getValidationTextRange();
	}


	// ********** misc **********

	@Override
	public EntityMappings getParent() {
		return (EntityMappings) super.getParent();
	}

	public String getDefaultPackage() {
		return this.getEntityMappings().getDefaultPersistentTypePackage();
	}

	public boolean isDefaultMetadataComplete() {
		return this.getEntityMappings().isDefaultPersistentTypeMetadataComplete();
	}

	public boolean isFor(String typeName) {
		String className = this.getName();
		if (className == null) {
			return false;
		}
		if (className.equals(typeName)) {
			return true;
		}
		String defaultPackage = this.getDefaultPackage();
		if (defaultPackage == null) {
			return false;
		}
		return (defaultPackage + '.' +  className).equals(typeName);
	}

	public boolean contains(int textOffset) {
		return this.mapping.containsOffset(textOffset);
	}

	public void classChanged(String oldClass, String newClass) {
		this.firePropertyChanged(NAME_PROPERTY, oldClass, newClass);
	}

	public boolean isMapped() {
		return true;
	}

	public String getMappingKey() {
		return this.mapping.getKey();
	}

	protected EntityMappings getEntityMappings() {
		return this.getParent();
	}

	protected XmlTypeMapping getResourceTypeMapping() {
		return this.mapping.getResourceTypeMapping();
	}

	@Override
	public void toString(StringBuilder sb) {
		sb.append(this.getName());
	}


	// ********** specified persistent attribute owner **********

	protected class SpecifiedAttributeOwner
		implements OrmPersistentAttribute.Owner
	{
		private JavaPersistentAttribute cachedJavaPersistentAttribute;

		public SpecifiedAttributeOwner() {
			super();
		}

		public JavaPersistentAttribute findJavaPersistentAttribute(OrmPersistentAttribute ormPersistentAttribute) {
			if (GenericOrmPersistentType.this.javaPersistentType == null) {
				return null;
			}
			String ormName = ormPersistentAttribute.getName();
			if (ormName == null) {
				return null;
			}
			AccessType ormAccess = ormPersistentAttribute.getAccess();

			JavaPersistentAttribute javaPersistentAttribute = this.findExistingJavaPersistentAttribute(ormName);
			if ((javaPersistentAttribute != null) && (javaPersistentAttribute.getAccess() == ormAccess)) {
				this.cachedJavaPersistentAttribute = null;  // we only want to cache the persistent attribute if we build it
				return javaPersistentAttribute;
			}

			// if 'javaPersistentAttribute' is null, it might exist in a superclass that is not persistent, we need to build it ourselves.
			// if access is different, we won't be able to find the corresponding java persistent attribute, it won't exist so we build it ourselves
			return this.buildJavaPersistentAttribute(ormName, ormAccess);
		}

		protected JavaPersistentAttribute findExistingJavaPersistentAttribute(String attributeName) {
			return GenericOrmPersistentType.this.javaPersistentType.getAttributeNamed(attributeName);
		}

		protected JavaPersistentAttribute buildJavaPersistentAttribute(String ormName, AccessType ormAccess) {
			JavaResourcePersistentAttribute jrpa = this.getJavaResourcePersistentAttribute(this.getJavaResourcePersistentType(), ormName, ormAccess);
			if (this.cachedJavaPersistentAttribute != null &&
					this.cachedJavaPersistentAttribute.getResourcePersistentAttribute() == jrpa) {
				return this.cachedJavaPersistentAttribute;
			}
			return this.cachedJavaPersistentAttribute = (jrpa == null) ? null : GenericOrmPersistentType.this.buildJavaPersistentAttribute(jrpa);
		}

		protected JavaResourcePersistentType getJavaResourcePersistentType() {
			return GenericOrmPersistentType.this.javaPersistentType.getResourcePersistentType();
		}

		protected JavaResourcePersistentAttribute getJavaResourcePersistentAttribute(JavaResourcePersistentType javaResourcePersistentType, String ormName, AccessType ormAccess) {
			for (Iterator<JavaResourcePersistentAttribute> stream = this.attributes(javaResourcePersistentType, ormAccess); stream.hasNext(); ) {
				JavaResourcePersistentAttribute jrpa = stream.next();
				if (jrpa.getName().equals(ormName)) {
					return jrpa;
				}
			}
			// climb up inheritance hierarchy
			String superclassName = javaResourcePersistentType.getSuperclassQualifiedName();
			if (superclassName == null) {
				return null;
			}
			JavaResourcePersistentType superclass = GenericOrmPersistentType.this.getJavaResourcePersistentType(superclassName);
			if (superclass == null) {
				return null;
			}
			// recurse
			return this.getJavaResourcePersistentAttribute(superclass, ormName, ormAccess);
		}

		protected Iterator<JavaResourcePersistentAttribute> attributes(JavaResourcePersistentType javaResourcePersistentType, AccessType ormAccess) {
			return (ormAccess == AccessType.PROPERTY) ? javaResourcePersistentType.persistableProperties() : javaResourcePersistentType.persistableFields();
		}

		public void updateJavaPersistentAttribute() {
			if (this.cachedJavaPersistentAttribute != null) {
				this.cachedJavaPersistentAttribute.update();
			}
			//else {
				//don't update, we don't own the java persistent attribute, 
				//it will be updated through the java context model
			//}
		}
	}

}
