/*******************************************************************************
 *  Copyright (c) 2011  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.jaxb.core.internal.context.java;

import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jpt.common.core.internal.utility.JDTTools;
import org.eclipse.jpt.common.core.resource.java.JavaResourceType;
import org.eclipse.jpt.common.core.utility.TextRange;
import org.eclipse.jpt.common.utility.Filter;
import org.eclipse.jpt.common.utility.internal.Bag;
import org.eclipse.jpt.common.utility.internal.CollectionTools;
import org.eclipse.jpt.common.utility.internal.StringTools;
import org.eclipse.jpt.common.utility.internal.iterables.ChainIterable;
import org.eclipse.jpt.common.utility.internal.iterables.CompositeIterable;
import org.eclipse.jpt.common.utility.internal.iterables.EmptyIterable;
import org.eclipse.jpt.common.utility.internal.iterables.EmptyListIterable;
import org.eclipse.jpt.common.utility.internal.iterables.FilteringIterable;
import org.eclipse.jpt.common.utility.internal.iterables.ListIterable;
import org.eclipse.jpt.common.utility.internal.iterables.LiveCloneIterable;
import org.eclipse.jpt.common.utility.internal.iterables.SingleElementIterable;
import org.eclipse.jpt.common.utility.internal.iterables.SubIterableWrapper;
import org.eclipse.jpt.common.utility.internal.iterables.TransformationIterable;
import org.eclipse.jpt.jaxb.core.MappingKeys;
import org.eclipse.jpt.jaxb.core.context.JaxbAttributeMapping;
import org.eclipse.jpt.jaxb.core.context.JaxbAttributesContainer;
import org.eclipse.jpt.jaxb.core.context.JaxbClass;
import org.eclipse.jpt.jaxb.core.context.JaxbClassMapping;
import org.eclipse.jpt.jaxb.core.context.JaxbPackage;
import org.eclipse.jpt.jaxb.core.context.JaxbPackageInfo;
import org.eclipse.jpt.jaxb.core.context.JaxbPersistentAttribute;
import org.eclipse.jpt.jaxb.core.context.JaxbType;
import org.eclipse.jpt.jaxb.core.context.XmlAccessOrder;
import org.eclipse.jpt.jaxb.core.context.XmlAccessType;
import org.eclipse.jpt.jaxb.core.context.XmlNamedNodeMapping;
import org.eclipse.jpt.jaxb.core.internal.validation.DefaultValidationMessages;
import org.eclipse.jpt.jaxb.core.internal.validation.JaxbValidationMessages;
import org.eclipse.jpt.jaxb.core.resource.java.JAXB;
import org.eclipse.jpt.jaxb.core.resource.java.XmlAccessorOrderAnnotation;
import org.eclipse.jpt.jaxb.core.resource.java.XmlAccessorTypeAnnotation;
import org.eclipse.wst.validation.internal.provisional.core.IMessage;
import org.eclipse.wst.validation.internal.provisional.core.IReporter;
import org.omg.CORBA.PUBLIC_MEMBER;


public class GenericJavaClassMapping
		extends AbstractJavaTypeMapping
		implements JaxbClassMapping {
	
	protected String specifiedFactoryClass;
	
	protected String factoryMethod;
	
	protected final PropOrderContainer propOrderContainer;
	
	protected JaxbClassMapping superclass;
	
	protected XmlAccessType defaultAccessType;
	protected XmlAccessType specifiedAccessType;
	
	protected XmlAccessOrder defaultAccessOrder;
	protected XmlAccessOrder specifiedAccessOrder;
	
	protected boolean hasRootElementInHierarchy_loaded = false;
	protected boolean hasRootElementInHierarchy = false;
	
	protected final JaxbAttributesContainer attributesContainer;
	
	protected final Map<JaxbClassMapping, JaxbAttributesContainer> includedAttributesContainers;
	
	public GenericJavaClassMapping(JaxbClass parent) {
		super(parent);
		this.includedAttributesContainers = new Hashtable<JaxbClassMapping, JaxbAttributesContainer>();
		this.propOrderContainer = new PropOrderContainer();
		
		initFactoryClass();
		initFactoryMethod();
		initPropOrder();
		initSpecifiedAccessType();
		initDefaultAccessType();
		initSpecifiedAccessOrder();
		initDefaultAccessOrder();
		this.attributesContainer = new GenericJavaAttributesContainer(this, buildAttributesContainerOwner(), getJavaResourceType());
		initIncludedAttributes();
	}
	
	
	@Override
	public JavaResourceType getJavaResourceType() {
		return (JavaResourceType) super.getJavaResourceType();
	}
	
	@Override
	public JaxbClass getJaxbType() {
		return (JaxbClass) super.getJaxbType();
	}
	
	public JaxbPackageInfo getPackageInfo() {
		JaxbPackage jaxbPackage = getJaxbPackage();
		// jaxb package may be null during initialization/update
		return (jaxbPackage == null) ? null : jaxbPackage.getPackageInfo();
	}
	
	
	// ***** sync/update *****
	
	@Override
	public void synchronizeWithResourceModel() {
		super.synchronizeWithResourceModel();
		syncFactoryClass();
		syncFactoryMethod();
		syncPropOrder();
		syncSpecifiedAccessType();
		syncSpecifiedAccessOrder();
		this.attributesContainer.synchronizeWithResourceModel();
		syncIncludedAttributes();
	}
	
	@Override
	public void update() {
		super.update();
		updateSuperclass();
		updateDefaultAccessType();
		updateDefaultAccessOrder();
		this.hasRootElementInHierarchy_loaded = false; // triggers that the value must be recalculated on next request
		this.attributesContainer.update();
		updateIncludedAttributes();
	}
	
	
	// ***** factory class *****
	
	public String getFactoryClass() {
		return (this.specifiedFactoryClass != null) ? this.specifiedFactoryClass : JAXB.XML_TYPE__DEFAULT_FACTORY_CLASS;
	}
	
	public String getSpecifiedFactoryClass() {
		return this.specifiedFactoryClass;
	}
	
	public void setSpecifiedFactoryClass(String factoryClass) {
		getXmlTypeAnnotation().setFactoryClass(factoryClass);
		setSpecifiedFactoryClass_(factoryClass);	
	}
	
	protected void setSpecifiedFactoryClass_(String factoryClass) {
		String old = this.specifiedFactoryClass;
		this.specifiedFactoryClass = factoryClass;
		firePropertyChanged(SPECIFIED_FACTORY_CLASS_PROPERTY, old, factoryClass);
	}
	
	protected String getResourceFactoryClass() {
		return getXmlTypeAnnotation().getFactoryClass();
	}
	
	protected void initFactoryClass() {
		this.specifiedFactoryClass = getResourceFactoryClass();
	}
	
	protected void syncFactoryClass() {
		setSpecifiedFactoryClass_(getResourceFactoryClass());
	}
	
	
	// ***** factory method *****
	
	public String getFactoryMethod() {
		return this.factoryMethod;
	}
	
	public void setFactoryMethod(String factoryMethod) {
		getXmlTypeAnnotation().setFactoryMethod(factoryMethod);
		setFactoryMethod_(factoryMethod);	
	}
	
	protected void setFactoryMethod_(String factoryMethod) {
		String old = this.factoryMethod;
		this.factoryMethod = factoryMethod;
		firePropertyChanged(FACTORY_METHOD_PROPERTY, old, factoryMethod);
	}
	
	protected String getResourceFactoryMethod() {
		return getXmlTypeAnnotation().getFactoryMethod();
	}
	
	protected void initFactoryMethod() {
		this.factoryMethod = getResourceFactoryMethod();
	}
	
	protected void syncFactoryMethod() {
		setFactoryMethod_(getResourceFactoryMethod());
	}
	
	
	// ***** prop order *****
	
	public ListIterable<String> getPropOrder() {
		return this.propOrderContainer.getContextElements();
	}
	
	public String getProp(int index) {
		return this.propOrderContainer.getContextElement(index);
	}
	
	public int getPropOrderSize() {
		return this.propOrderContainer.getContextElementsSize();
	}
	
	public void addProp(int index, String prop) {
		getXmlTypeAnnotation().addProp(index, prop);
		this.propOrderContainer.addContextElement(index, prop);
	}
	
	public void removeProp(String prop) {
		this.removeProp(this.propOrderContainer.indexOfContextElement(prop));
	}
	
	public void removeProp(int index) {
		this.getXmlTypeAnnotation().removeProp(index);
		this.propOrderContainer.removeContextElement(index);
	}
	
	public void moveProp(int targetIndex, int sourceIndex) {
		this.getXmlTypeAnnotation().moveProp(targetIndex, sourceIndex);
		this.propOrderContainer.moveContextElement(targetIndex, sourceIndex);
	}
	
	protected void initPropOrder() {
		this.propOrderContainer.initialize();
	}
	
	protected void syncPropOrder() {
		this.propOrderContainer.synchronizeWithResourceModel();
	}
	
	protected ListIterable<String> getResourcePropOrder() {
		ListIterable<String> result = getXmlTypeAnnotation().getPropOrder();
		if (CollectionTools.size(result) == 1 && StringTools.EMPTY_STRING.equals(CollectionTools.get(result, 0))) {
			return EmptyListIterable.instance();
		}
		return result;
	}
	
	
	// ***** XmlAccessorType *****
	
	public XmlAccessType getAccessType() {
		return (this.specifiedAccessType != null) ? this.specifiedAccessType : this.defaultAccessType;
	}
	
	public XmlAccessType getDefaultAccessType() {
		return this.defaultAccessType;
	}
	
	protected void setDefaultAccessType_(XmlAccessType access) {
		XmlAccessType old = this.defaultAccessType;
		this.defaultAccessType = access;
		firePropertyChanged(DEFAULT_ACCESS_TYPE_PROPERTY, old, access);
	}
	
	public XmlAccessType getSpecifiedAccessType() {
		return this.specifiedAccessType;
	}
	
	public void setSpecifiedAccessType(XmlAccessType access) {
		getXmlAccessorTypeAnnotation().setValue(XmlAccessType.toJavaResourceModel(access));
		setSpecifiedAccessType_(access);
	}
	
	protected void setSpecifiedAccessType_(XmlAccessType access) {
		XmlAccessType old = this.specifiedAccessType;
		this.specifiedAccessType = access;
		firePropertyChanged(SPECIFIED_ACCESS_TYPE_PROPERTY, old, access);
	}
	
	protected void initDefaultAccessType() {
		this.defaultAccessType = buildDefaultAccessType();
	}
	
	protected void updateDefaultAccessType() {
		setDefaultAccessType_(buildDefaultAccessType());
	}
	
	/**
	 * Default access type is determined by the following, in order of precedence:
	 * - @XmlAccessorType annotation on a mapped super class
	 * - @XmlAccessorType annotation on the package
	 * - default access type of {@link PUBLIC_MEMBER}
	 */
	protected XmlAccessType buildDefaultAccessType() {
		XmlAccessType accessType = getSuperclassAccessType();
		if (accessType != null) {
			return accessType;
		}
		accessType = getPackageAccessType();
		if (accessType != null) {
			return accessType;
		}
		return XmlAccessType.PUBLIC_MEMBER;
	}
	
	protected XmlAccessType getSuperclassAccessType() {
		return this.superclass == null ? null : this.superclass.getSpecifiedAccessType();
	}
	
	protected XmlAccessType getPackageAccessType() {
		JaxbPackageInfo packageInfo = getPackageInfo();
		return (packageInfo == null) ? null : packageInfo.getAccessType();
	}
	
	protected XmlAccessorTypeAnnotation getXmlAccessorTypeAnnotation() {
		return (XmlAccessorTypeAnnotation) getJavaResourceType().getNonNullAnnotation(JAXB.XML_ACCESSOR_TYPE);
	}
	
	protected XmlAccessType getResourceAccessType() {
		return XmlAccessType.fromJavaResourceModel(getXmlAccessorTypeAnnotation().getValue());
	}
	
	protected void initSpecifiedAccessType() {
		this.specifiedAccessType = getResourceAccessType();
	}
	
	protected void syncSpecifiedAccessType() {
		setSpecifiedAccessType_(getResourceAccessType());
	}
	
	
	// ***** XmlAccessorOrder *****
	
	public XmlAccessOrder getAccessOrder() {
		return (this.specifiedAccessOrder != null) ? this.specifiedAccessOrder : this.defaultAccessOrder;
	}
	
	public XmlAccessOrder getDefaultAccessOrder() {
		return this.defaultAccessOrder;
	}
	
	protected void setDefaultAccessOrder_(XmlAccessOrder accessOrder) {
		XmlAccessOrder old = this.defaultAccessOrder;
		this.defaultAccessOrder = accessOrder;
		firePropertyChanged(DEFAULT_ACCESS_ORDER_PROPERTY, old, accessOrder);
	}
	
	public XmlAccessOrder getSpecifiedAccessOrder() {
		return this.specifiedAccessOrder;
	}
	
	public void setSpecifiedAccessOrder(XmlAccessOrder accessOrder) {
		getXmlAccessorOrderAnnotation().setValue(XmlAccessOrder.toJavaResourceModel(accessOrder));
		setSpecifiedAccessOrder_(accessOrder);
	}
	
	protected void setSpecifiedAccessOrder_(XmlAccessOrder accessOrder) {
		XmlAccessOrder old = this.specifiedAccessOrder;
		this.specifiedAccessOrder = accessOrder;
		firePropertyChanged(SPECIFIED_ACCESS_ORDER_PROPERTY, old, accessOrder);
	}
	
	protected void initDefaultAccessOrder() {
		this.defaultAccessOrder = buildDefaultAccessOrder();
	}
	
	protected void updateDefaultAccessOrder() {
		setDefaultAccessOrder_(buildDefaultAccessOrder());
	}
	
	/**
	 * Default access order is determined by the following, in order of precedence:
	 * - @XmlAccessorOrder annotation on a mapped super class
	 * - @XmlAccessorOrder annotation on the package
	 * - default access order of {@link UNDEFINED}
	 */
	protected XmlAccessOrder buildDefaultAccessOrder() {
		XmlAccessOrder accessOrder = getSuperclassAccessOrder();
		if (accessOrder != null) {
			return accessOrder;
		}
		accessOrder = getPackageAccessOrder();
		if (accessOrder != null) {
			return accessOrder;
		}
		return XmlAccessOrder.UNDEFINED;
	}
	
	protected XmlAccessOrder getSuperclassAccessOrder() {
		JaxbClassMapping superclass = this.superclass;
		while (superclass != null) {
			XmlAccessOrder accessOrder = superclass.getSpecifiedAccessOrder();
			if (accessOrder != null) {
				return accessOrder;
			}
			superclass = superclass.getSuperclass();
		}
		return null;
	}
	
	protected XmlAccessOrder getPackageAccessOrder() {
		JaxbPackageInfo packageInfo = getPackageInfo();
		return packageInfo == null ? null : packageInfo.getAccessOrder();
	}
	
	protected XmlAccessorOrderAnnotation getXmlAccessorOrderAnnotation() {
		return (XmlAccessorOrderAnnotation) getJavaResourceType().getNonNullAnnotation(JAXB.XML_ACCESSOR_ORDER);
	}
	
	protected XmlAccessOrder getResourceAccessOrder() {
		return XmlAccessOrder.fromJavaResourceModel(getXmlAccessorOrderAnnotation().getValue());
	}
	
	protected void initSpecifiedAccessOrder() {
		this.specifiedAccessOrder = getResourceAccessOrder();
	}
	
	protected void syncSpecifiedAccessOrder() {
		setSpecifiedAccessOrder_(getResourceAccessOrder());
	}
	
	
	// ********** super class **********
	
	public JaxbClassMapping getSuperclass() {
		return this.superclass;
	}
	
	protected void setSuperclass_(JaxbClassMapping superclass) {
		JaxbClassMapping old = this.superclass;
		this.superclass = superclass;
		this.firePropertyChanged(SUPERCLASS_PROPERTY, old, superclass);
	}
	
	protected void updateSuperclass() {
		setSuperclass_(findSuperclass());
	}
	
	protected JaxbClassMapping findSuperclass() {
		JavaResourceType resourceType = getSuperclass(getJavaResourceType());
		while (resourceType != null && resourceType != this) {
			JaxbType jaxbType = getJaxbProject().getContextRoot().getType(resourceType.getQualifiedName());
			
			// if the superclass is not a class, return null
			if (jaxbType == null || jaxbType.getKind() != JaxbType.Kind.CLASS) {
				return null;
			}
			
			JaxbClassMapping jaxbClassMapping = ((JaxbClass) jaxbType).getMapping();
			// rare for a non-null superclass to not be mapped, but potentially possible mid-update
			if (jaxbClassMapping != null) {  
				return jaxbClassMapping;
			}
			else {
				resourceType = getSuperclass(resourceType);
			}
		}
		return null;
	}
	
	protected JavaResourceType getSuperclass(JavaResourceType resourceType) {
		String superclassName = resourceType.getSuperclassQualifiedName();
		if (superclassName == null) {
			return null;
		}
		
		return (JavaResourceType) getJaxbProject().getJavaResourceType(
				superclassName, JavaResourceType.Kind.TYPE);
	}
	
	
	// ***** attributes *****
	
	public Iterable<JaxbPersistentAttribute> getAttributes() {
		return this.attributesContainer.getAttributes();
	}
	
	public int getAttributesSize() {
		return this.attributesContainer.getAttributesSize();
	}
	
	protected GenericJavaAttributesContainer.Owner buildAttributesContainerOwner() {
		return new GenericJavaAttributesContainer.Owner() {
			public XmlAccessType getAccessType() {
				return GenericJavaClassMapping.this.getAccessType();
			}
			
			public void fireAttributeAdded(JaxbPersistentAttribute attribute) {
				GenericJavaClassMapping.this.fireItemAdded(ATTRIBUTES_COLLECTION, attribute);
			}
			
			public void fireAttributeRemoved(JaxbPersistentAttribute attribute) {
				GenericJavaClassMapping.this.fireItemRemoved(ATTRIBUTES_COLLECTION, attribute);
			}
		};
	}
	
	
	// ***** included attributes *****
	
	public Iterable<JaxbPersistentAttribute> getIncludedAttributes() {
		return new CompositeIterable<JaxbPersistentAttribute>(getIncludedAttributeSets());
	}
	
	protected Iterable<Iterable<JaxbPersistentAttribute>> getIncludedAttributeSets() {
		return new TransformationIterable<JaxbAttributesContainer, Iterable<JaxbPersistentAttribute>>(
				getIncludedAttributesContainers()) {
			@Override
			protected Iterable<JaxbPersistentAttribute> transform(JaxbAttributesContainer attributesContainer) {
				return attributesContainer.getAttributes();
			}
		};
	}
	
	protected Iterable<JaxbAttributesContainer> getIncludedAttributesContainers() {
		return new LiveCloneIterable<JaxbAttributesContainer>(this.includedAttributesContainers.values());  // read-only
	}
	
	public int getIncludedAttributesSize() {
		int size = 0;
		for (JaxbAttributesContainer attributesContainer : getIncludedAttributesContainers()) {
			size += attributesContainer.getAttributesSize();
		}
		return size;
	}
	
	protected void initIncludedAttributes() {
		// xml transient classes have no included attributes
		if (isXmlTransient()) {
			return;
		}
		JaxbClassMapping superclass = this.superclass;
		// only add inherited attributes for superclasses up until a mapped class is encountered
		while (superclass != null && superclass.isXmlTransient()) {
			this.includedAttributesContainers.put(superclass, buildIncludedAttributesContainer(superclass));
			superclass = superclass.getSuperclass();
		}
	}
	
	protected void syncIncludedAttributes() {
		for (JaxbAttributesContainer attributesContainer : this.includedAttributesContainers.values()) {
			attributesContainer.synchronizeWithResourceModel();
		}
	}
	
	protected void updateIncludedAttributes() {
		HashSet<JaxbClassMapping> oldSuperclasses 
				= CollectionTools.set(this.includedAttributesContainers.keySet());
		Set<JaxbPersistentAttribute> oldAttributes = CollectionTools.set(getIncludedAttributes());
		
		if (! isXmlTransient()) {
			JaxbClassMapping superclass = this.superclass;
			// only add inherited attributes for superclasses up until a mapped class is encountered
			while (superclass != null && superclass.isXmlTransient()) {
				if (this.includedAttributesContainers.containsKey(superclass)) {
					this.includedAttributesContainers.get(superclass).update();
					oldSuperclasses.remove(superclass);
				}
				else {
					this.includedAttributesContainers.put(superclass, buildIncludedAttributesContainer(superclass));
				}
				superclass = superclass.getSuperclass();
			}
		}
		
		for (JaxbClassMapping oldSuperclass : oldSuperclasses) {
			this.includedAttributesContainers.remove(oldSuperclass);
		}
		
		Set<JaxbPersistentAttribute> newAttributes = CollectionTools.set(getIncludedAttributes());
		if (CollectionTools.elementsAreDifferent(oldAttributes, newAttributes)) {
			fireCollectionChanged(INCLUDED_ATTRIBUTES_COLLECTION, newAttributes);
		}
	}
	
	protected JaxbAttributesContainer buildIncludedAttributesContainer(JaxbClassMapping jaxbClassMapping) {
		return new GenericJavaAttributesContainer(this, buildIncludedAttributesContainerOwner(), jaxbClassMapping.getJaxbType().getJavaResourceType());
	}
	
	protected GenericJavaAttributesContainer.Owner buildIncludedAttributesContainerOwner() {
		return new GenericJavaAttributesContainer.Owner() {
			public XmlAccessType getAccessType() {
				return GenericJavaClassMapping.this.getAccessType();
			}
			
			public void fireAttributeAdded(JaxbPersistentAttribute attribute) {
				GenericJavaClassMapping.this.fireItemAdded(INCLUDED_ATTRIBUTES_COLLECTION, attribute);
			}
			
			public void fireAttributeRemoved(JaxbPersistentAttribute attribute) {
				GenericJavaClassMapping.this.fireItemRemoved(INCLUDED_ATTRIBUTES_COLLECTION, attribute);
			}
		};
	}
	
	
	// ***** misc attributes *****
	
	public Iterable<JaxbPersistentAttribute> getAllLocallyDefinedAttributes() {
		return new CompositeIterable<JaxbPersistentAttribute>(
				getAttributes(),
				getIncludedAttributes());
	}
	
	public Iterable<JaxbPersistentAttribute> getInheritedAttributes() {
		return new CompositeIterable<JaxbPersistentAttribute>(
				getIncludedAttributes(),
				getOtherInheritedAttributes());
	}
	
	public Iterable<JaxbPersistentAttribute> getAllAttributes() {
		return new CompositeIterable<JaxbPersistentAttribute>(
				getAttributes(),
				getIncludedAttributes(),
				getOtherInheritedAttributes());
	}
	
	/**
	 * return those inherited attributes that are not included
	 */
	protected Iterable<JaxbPersistentAttribute> getOtherInheritedAttributes() {
		return new CompositeIterable<JaxbPersistentAttribute>(
				new TransformationIterable<JaxbClassMapping, Iterable<JaxbPersistentAttribute>>(
						new ChainIterable<JaxbClassMapping>(getSuperclass()) {
							@Override
							protected JaxbClassMapping nextLink(JaxbClassMapping currentLink) {
								return currentLink.getSuperclass();
							}
						}) {
					@Override
					protected Iterable<JaxbPersistentAttribute> transform(JaxbClassMapping o) {
						return o.getAttributes();
					}
				});
	}
	
	
	// ***** subClasses *****
	
	@Override
	public boolean hasRootElementInHierarchy() {
		if (! this.hasRootElementInHierarchy_loaded) {
			this.hasRootElementInHierarchy = calculateHasRootElementInHierarchy();
			this.hasRootElementInHierarchy_loaded = true;
		}
		return this.hasRootElementInHierarchy;
	}
	
	protected boolean calculateHasRootElementInHierarchy() {
		if (this.getXmlRootElement() != null) {
			return true;
		}
		
		for (JaxbType jaxbType : getJaxbProject().getContextRoot().getTypes()) {
			if (jaxbType.getMapping() != null 
					&& ! jaxbType.getMapping().isXmlTransient() 
					&& jaxbType.getMapping().getXmlRootElement() != null
					&& JDTTools.typeIsSubType(
							getJaxbProject().getJavaProject(),
							jaxbType.getFullyQualifiedName(), getJaxbType().getFullyQualifiedName())) {
				return true;
			}
		}
		
		return false;
	}
	
	
	// ***** misc *****
	
	@Override
	protected Iterable<String> getTransientReferencedXmlTypeNames() {
		return new CompositeIterable<String>(
				super.getTransientReferencedXmlTypeNames(),
				new SingleElementIterable(getJavaResourceType().getSuperclassQualifiedName()));
	}
	
	@Override
	protected Iterable<String> getNonTransientReferencedXmlTypeNames() {
		return new CompositeIterable<String>(
				super.getNonTransientReferencedXmlTypeNames(),
				new SingleElementIterable(getJavaResourceType().getSuperclassQualifiedName()),
				new CompositeIterable<String>(
						new TransformationIterable<JaxbPersistentAttribute, Iterable<String>>(getAttributes()) {
							@Override
							protected Iterable<String> transform(JaxbPersistentAttribute o) {
								return o.getMapping().getReferencedXmlTypeNames();
							}
						}));
	}
	
	public JaxbAttributeMapping getXmlIdMapping() {
		Iterator<XmlNamedNodeMapping> allXmlIdMappings = 
				new FilteringIterable<XmlNamedNodeMapping>(
						new SubIterableWrapper<JaxbAttributeMapping, XmlNamedNodeMapping>(
								new FilteringIterable<JaxbAttributeMapping>(
										new TransformationIterable<JaxbPersistentAttribute, JaxbAttributeMapping>(getAllAttributes()) {
											@Override
											protected JaxbAttributeMapping transform(JaxbPersistentAttribute o) {
												return o.getMapping();
											}
										}) {
									@Override
									protected boolean accept(JaxbAttributeMapping o) {
										return (o.getKey() == MappingKeys.XML_ELEMENT_ATTRIBUTE_MAPPING_KEY
												|| o.getKey() == MappingKeys.XML_ATTRIBUTE_ATTRIBUTE_MAPPING_KEY);
									}
								})) {
					@Override
					protected boolean accept(XmlNamedNodeMapping o) {
						return o.getXmlID() != null;
					}
				}.iterator();
		return (allXmlIdMappings.hasNext()) ? allXmlIdMappings.next() : null;
	}
	
	protected Iterable<? extends JaxbAttributeMapping> getAttributeMappings() {
		return new TransformationIterable<JaxbPersistentAttribute, JaxbAttributeMapping>(getAttributes()) {
			@Override
			protected JaxbAttributeMapping transform(JaxbPersistentAttribute attribute) {
				return attribute.getMapping();
			}
		};
	}
	
	
	// ***** content assist *****
	
	@Override
	public Iterable<String> getJavaCompletionProposals(
			int pos, Filter<String> filter, CompilationUnit astRoot) {
		
		Iterable<String> result = super.getJavaCompletionProposals(pos, filter, astRoot);
		if (! CollectionTools.isEmpty(result)) {
			return result;
		}
		
		if (propTouches(pos, astRoot)) {
			return getPropProposals(filter);
		}
		
		// TODO - factory methods?
		
		for (JaxbPersistentAttribute attribute : this.getAttributes()) {
			result = attribute.getJavaCompletionProposals(pos, filter, astRoot);
			if (!CollectionTools.isEmpty(result)) {
				return result;
			}
		}
		
		return EmptyIterable.instance();
	}
	
	protected Iterable<String> getPropProposals(Filter<String> filter) {
		return StringTools.convertToJavaStringLiterals(
				new FilteringIterable<String>(
					new TransformationIterable<JaxbPersistentAttribute, String>(getAllLocallyDefinedAttributes()) {
						@Override
						protected String transform(JaxbPersistentAttribute o) {
							return o.getName();
						}
					},
					filter));
	}
	
	
	// ***** validation *****
	
	@Override
	public void validate(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) {
		super.validate(messages, reporter, astRoot);
		
		validateConstructor(messages, reporter, astRoot);
		validatePropOrder(messages, reporter, astRoot);
		validateXmlAnyAttributeMapping(messages, astRoot);
		validateXmlAnyElementMapping(messages, astRoot);
		validateXmlValueMapping(messages, astRoot);
		validateXmlIDs(messages, astRoot);
		
		for (JaxbPersistentAttribute attribute : getAttributes()) {
			attribute.validate(messages, reporter, astRoot);
		}
	}
	
	protected void validateConstructor(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) {
		// TODO - factory class/method
		
		if (! JAXB.XML_TYPE__DEFAULT_FACTORY_CLASS.equals(getFactoryClass())) {
			if (StringTools.stringIsEmpty(getFactoryMethod())) {
				messages.add(
						DefaultValidationMessages.buildMessage(
								IMessage.HIGH_SEVERITY,
								JaxbValidationMessages.XML_TYPE__UNSPECIFIED_FACTORY_METHOD,
								this,
								getFactoryClassTextRange(astRoot)));
			}
		}
		else {
			if (getFactoryMethod() == null
					&& getJaxbType().getXmlJavaTypeAdapter() == null
					&& ! getJavaResourceType().hasPublicOrProtectedNoArgConstructor()) {
				messages.add(
						DefaultValidationMessages.buildMessage(
								IMessage.HIGH_SEVERITY,
								JaxbValidationMessages.XML_TYPE__NO_PUBLIC_OR_PROTECTED_CONSTRUCTOR,
								this,
								getValidationTextRange(astRoot)));
			}
		}
		
	}
	
	protected void validatePropOrder(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) {
		if (CollectionTools.isEmpty(getPropOrder())) {
			return;
		}
		
		// no duplicates
		// all attributes/included attributes with XmlElement/s/Ref/s must be listed
		// no nonexistent attributes (attributes mapped otherwise allowed) ...
		// *except* no transient attributes allowed
		
		Bag<String> props = CollectionTools.bag(getPropOrder());
		Set<String> allAttributes = new HashSet<String>();
		Set<String> requiredAttributes = new HashSet<String>();
		Set<String> transientAttributes = new HashSet<String>();
		
		for (JaxbPersistentAttribute attribute : getAllLocallyDefinedAttributes()) {
			allAttributes.add(attribute.getName());
			transientAttributes.add(attribute.getName());
		}
		
		for (JaxbPersistentAttribute attribute : getAllLocallyDefinedAttributes()) {
			if (attribute.getMapping().isParticleMapping()) {
				requiredAttributes.add(attribute.getName());
			}
			
			if (! attribute.getMapping().isTransient()) {
				// remove transients (rather than previous algorithm of adding them)
				// there may be two attributes of the same name (one field, one property) in 
				// a class, which is a correct configuration.  we want to know if *every* attribute 
				// of a given name is transient (or if there's a single non-transient attribute)
				transientAttributes.remove(attribute.getName());
			}
		}
		
		Set<Integer> duplicateProps = new HashSet<Integer>();
		Set<String> missingProps = new HashSet<String>(requiredAttributes);
		Set<Integer> nonexistentProps = new HashSet<Integer>();
		Set<Integer> transientProps = new HashSet<Integer>();
		
		for (int i = 0; i < getPropOrderSize(); i ++ ) {
			String prop = getProp(i);
			
			if (props.count(prop) > 1) {
				duplicateProps.add(i);
			}
			
			if (missingProps.contains(prop)) {
				missingProps.remove(prop);
			}
			
			if (! allAttributes.contains(prop)) {
				nonexistentProps.add(i);
			}
			
			if (transientAttributes.contains(prop)) {
				transientProps.add(i);
			}
		}
		
		for (int i : duplicateProps) {
			messages.add(
					DefaultValidationMessages.buildMessage(
							IMessage.HIGH_SEVERITY,
							JaxbValidationMessages.XML_TYPE__DUPLICATE_PROP,
							new String[] { getProp(i) },
							this,
							getPropTextRange(i, astRoot)));
		}
		
		for (String missingProp : missingProps) {
			messages.add(
					DefaultValidationMessages.buildMessage(
							IMessage.HIGH_SEVERITY,
							JaxbValidationMessages.XML_TYPE__MISSING_PROP,
							new String[] { missingProp },
							this,
							getPropOrderTextRange(astRoot)));
		}
		
		for (int i : nonexistentProps) {
			messages.add(
					DefaultValidationMessages.buildMessage(
							IMessage.HIGH_SEVERITY,
							JaxbValidationMessages.XML_TYPE__NONEXISTENT_PROP,
							new String[] { getProp(i) },
							this,
							getPropTextRange(i, astRoot)));
		}
		
		for (int i : transientProps) {
			messages.add(
					DefaultValidationMessages.buildMessage(
							IMessage.HIGH_SEVERITY,
							JaxbValidationMessages.XML_TYPE__TRANSIENT_PROP,
							new String [] { getProp(i) },
							this,
							getPropTextRange(i, astRoot)));
		}
	}
	
	protected void validateXmlAnyAttributeMapping(List<IMessage> messages, CompilationUnit astRoot) {
		Set<JaxbPersistentAttribute> localAttributes = new HashSet<JaxbPersistentAttribute>();
		Set<JaxbPersistentAttribute> allAttributes = new HashSet<JaxbPersistentAttribute>();
			
		for (JaxbPersistentAttribute attribute : getAttributes()) {
			if (attribute.getMappingKey() == MappingKeys.XML_ANY_ATTRIBUTE_ATTRIBUTE_MAPPING_KEY) {
				localAttributes.add(attribute);
				allAttributes.add(attribute);
			}
		}
		
		for (JaxbPersistentAttribute attribute : getInheritedAttributes()) {
			if (attribute.getMappingKey() == MappingKeys.XML_ANY_ATTRIBUTE_ATTRIBUTE_MAPPING_KEY) {
				allAttributes.add(attribute);
			}
		}
		
		if (allAttributes.size() > 1) {
			messages.add(
					DefaultValidationMessages.buildMessage(
							IMessage.HIGH_SEVERITY,
							JaxbValidationMessages.XML_ANY_ATTRIBUTE__MULTIPLE_MAPPINGS_DEFINED,
							this,
							getValidationTextRange(astRoot)));
				
			for (JaxbPersistentAttribute anyAttribute : localAttributes) {
				messages.add(
					DefaultValidationMessages.buildMessage(
						IMessage.HIGH_SEVERITY,
						JaxbValidationMessages.XML_ANY_ATTRIBUTE__MULTIPLE_MAPPINGS_DEFINED,
						anyAttribute.getMapping(),
						anyAttribute.getMapping().getValidationTextRange(astRoot)));
			}
		}
	}
	
	protected void validateXmlAnyElementMapping(List<IMessage> messages, CompilationUnit astRoot) {
		Set<JaxbPersistentAttribute> localAttributes = new HashSet<JaxbPersistentAttribute>();
		Set<JaxbPersistentAttribute> allAttributes = new HashSet<JaxbPersistentAttribute>();
			
		for (JaxbPersistentAttribute attribute : getAttributes()) {
			if (attribute.getMappingKey() == MappingKeys.XML_ANY_ELEMENT_ATTRIBUTE_MAPPING_KEY) {
				localAttributes.add(attribute);
				allAttributes.add(attribute);
			}
		}
		
		for (JaxbPersistentAttribute attribute : getInheritedAttributes()) {
			if (attribute.getMappingKey() == MappingKeys.XML_ANY_ELEMENT_ATTRIBUTE_MAPPING_KEY) {
				allAttributes.add(attribute);
			}
		}
		
		if (allAttributes.size() > 1) {
			messages.add(
					DefaultValidationMessages.buildMessage(
							IMessage.HIGH_SEVERITY,
							JaxbValidationMessages.XML_ANY_ELEMENT__MULTIPLE_MAPPINGS_DEFINED,
							this,
							getValidationTextRange(astRoot)));
				
			for (JaxbPersistentAttribute anyAttribute : localAttributes) {
				messages.add(
					DefaultValidationMessages.buildMessage(
						IMessage.HIGH_SEVERITY,
						JaxbValidationMessages.XML_ANY_ELEMENT__MULTIPLE_MAPPINGS_DEFINED,
						anyAttribute.getMapping(),
						anyAttribute.getMapping().getValidationTextRange(astRoot)));
			}
		}
	}
	
	protected void validateXmlValueMapping(List<IMessage> messages, CompilationUnit astRoot) {
		Set<JaxbPersistentAttribute> localAttributes = new HashSet<JaxbPersistentAttribute>();
		Set<JaxbPersistentAttribute> allAttributes = new HashSet<JaxbPersistentAttribute>();
			
		for (JaxbPersistentAttribute attribute : getAttributes()) {
			if (attribute.getMappingKey() == MappingKeys.XML_VALUE_ATTRIBUTE_MAPPING_KEY) {
				localAttributes.add(attribute);
				allAttributes.add(attribute);
			}
		}
		
		for (JaxbPersistentAttribute attribute : getInheritedAttributes()) {
			if (attribute.getMappingKey() == MappingKeys.XML_VALUE_ATTRIBUTE_MAPPING_KEY) {
				allAttributes.add(attribute);
			}
		}
		
		if (allAttributes.size() > 1) {
			messages.add(
					DefaultValidationMessages.buildMessage(
							IMessage.HIGH_SEVERITY,
							JaxbValidationMessages.XML_VALUE__MULTIPLE_MAPPINGS_DEFINED,
							this,
							getValidationTextRange(astRoot)));
				
			for (JaxbPersistentAttribute anyAttribute : localAttributes) {
				messages.add(
					DefaultValidationMessages.buildMessage(
						IMessage.HIGH_SEVERITY,
						JaxbValidationMessages.XML_VALUE__MULTIPLE_MAPPINGS_DEFINED,
						anyAttribute.getMapping(),
						anyAttribute.getMapping().getValidationTextRange(astRoot)));
			}
		}
	}
	
	protected void validateXmlIDs(List<IMessage> messages, CompilationUnit astRoot) {
		
		Set<JaxbPersistentAttribute> localAttributes = new HashSet<JaxbPersistentAttribute>();
		Set<JaxbPersistentAttribute> allAttributes = new HashSet<JaxbPersistentAttribute>();
			
		for (JaxbPersistentAttribute attribute : getAttributes()) {
			if ((attribute.getMappingKey() == MappingKeys.XML_ATTRIBUTE_ATTRIBUTE_MAPPING_KEY
					|| attribute.getMappingKey() == MappingKeys.XML_ELEMENT_ATTRIBUTE_MAPPING_KEY)
					&& ((XmlNamedNodeMapping) attribute.getMapping()).getXmlID() != null) {
				localAttributes.add(attribute);
				allAttributes.add(attribute);
			}
		}
		
		for (JaxbPersistentAttribute attribute : getInheritedAttributes()) {
			if ((attribute.getMappingKey() == MappingKeys.XML_ATTRIBUTE_ATTRIBUTE_MAPPING_KEY
					|| attribute.getMappingKey() == MappingKeys.XML_ELEMENT_ATTRIBUTE_MAPPING_KEY)
					&& ((XmlNamedNodeMapping) attribute.getMapping()).getXmlID() != null) {
				allAttributes.add(attribute);
			}
		}
		
		if (allAttributes.size() > 1) {
			messages.add(
					DefaultValidationMessages.buildMessage(
							IMessage.HIGH_SEVERITY,
							JaxbValidationMessages.XML_ID__MULTIPLE_MAPPINGS_DEFINED,
							this,
							getValidationTextRange(astRoot)));
				
			for (JaxbPersistentAttribute anyAttribute : localAttributes) {
				messages.add(
					DefaultValidationMessages.buildMessage(
						IMessage.HIGH_SEVERITY,
						JaxbValidationMessages.XML_ID__MULTIPLE_MAPPINGS_DEFINED,
						anyAttribute.getMapping(),
						anyAttribute.getMapping().getValidationTextRange(astRoot)));
			}
		}
	}
	
	protected TextRange getFactoryClassTextRange(CompilationUnit astRoot) {
		TextRange result = getXmlTypeAnnotation().getFactoryClassTextRange(astRoot);
		return (result != null) ? result : getValidationTextRange(astRoot);
	}
	
	protected TextRange getFactoryMethodTextRange(CompilationUnit astRoot) {
		TextRange result = getXmlTypeAnnotation().getFactoryMethodTextRange(astRoot);
		return (result != null) ? result : getValidationTextRange(astRoot);
	}
	
	protected TextRange getPropOrderTextRange(CompilationUnit astRoot) {
		TextRange result = getXmlTypeAnnotation().getPropOrderTextRange(astRoot);
		return (result != null) ? result : getValidationTextRange(astRoot);
	}
	
	protected TextRange getPropTextRange(int index, CompilationUnit astRoot) {
		return getXmlTypeAnnotation().getPropTextRange(index, astRoot);
	}
	
	protected boolean propTouches(int pos, CompilationUnit astRoot) {
		if (getXmlTypeAnnotation().propOrderTouches(pos, astRoot)) {
			for (int i = 0; i < getXmlTypeAnnotation().getPropOrderSize(); i ++ ) {
				if (getXmlTypeAnnotation().propTouches(i, pos, astRoot)) {
					return true;
				}
			}
		}
		return false;
	}
	
	
	/**
	 * xml prop order container
	 */
	protected class PropOrderContainer
			extends ListContainer<String, String> {
		
		@Override
		protected String getContextElementsPropertyName() {
			return PROP_ORDER_LIST;
		}
		
		@Override
		protected String buildContextElement(String resourceElement) {
			return resourceElement;
		}
		
		@Override
		protected ListIterable<String> getResourceElements() {
			return GenericJavaClassMapping.this.getResourcePropOrder();
		}
		
		@Override
		protected String getResourceElement(String contextElement) {
			return contextElement;
		}
	}
}
