/*******************************************************************************
 * Copyright (c) 2008, 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.jpa.eclipselink.core.internal.context.java;

import java.util.List;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jpt.common.core.resource.java.JavaResourceType;
import org.eclipse.jpt.common.core.utility.TextRange;
import org.eclipse.jpt.jpa.core.context.java.JavaTypeMapping;
import org.eclipse.jpt.jpa.core.internal.context.java.AbstractJavaJpaContextNode;
import org.eclipse.jpt.jpa.eclipselink.core.context.java.JavaEclipseLinkConverterContainer;
import org.eclipse.jpt.jpa.eclipselink.core.resource.java.EclipseLinkNamedConverterAnnotation;
import org.eclipse.wst.validation.internal.provisional.core.IMessage;
import org.eclipse.wst.validation.internal.provisional.core.IReporter;

public class JavaEclipseLinkConverterContainerImpl
	extends AbstractJavaJpaContextNode
	implements JavaEclipseLinkConverterContainer
{
	protected JavaEclipseLinkCustomConverter customConverter;
	protected JavaEclipseLinkObjectTypeConverter objectTypeConverter;
	protected JavaEclipseLinkStructConverter structConverter;
	protected JavaEclipseLinkTypeConverter typeConverter;


	public JavaEclipseLinkConverterContainerImpl(JavaTypeMapping parent) {
		super(parent);
		this.customConverter = this.buildCustomConverter();
		this.objectTypeConverter = this.buildObjectTypeConverter();
		this.structConverter = this.buildStructConverter();
		this.typeConverter = this.buildTypeConverter();
	}


	// ********** synchronize/update **********

	@Override
	public void synchronizeWithResourceModel() {
		super.synchronizeWithResourceModel();
		this.syncCustomConverter();
		this.syncObjectTypeConverter();
		this.syncStructConverter();
		this.syncTypeConverter();
	}

	@Override
	public void update() {
		super.update();
		if (this.customConverter != null) {
			this.customConverter.update();
		}
		if (this.objectTypeConverter != null) {
			this.objectTypeConverter.update();
		}
		if (this.structConverter != null) {
			this.structConverter.update();
		}
		if (this.typeConverter != null) {
			this.typeConverter.update();
		}
	}


	// ********** custom converter **********

	public JavaEclipseLinkCustomConverter getCustomConverter() {
		return this.customConverter;
	}

	public JavaEclipseLinkCustomConverter addCustomConverter() {
		if (this.customConverter != null) {
			throw new IllegalStateException("custom converter already exists: " + this.customConverter); //$NON-NLS-1$
		}
		JavaEclipseLinkCustomConverter converter = this.buildNewConverter(this.getCustomConverterAdapter());
		this.setCustomConverter_(converter);
		return converter;
	}

	public void removeCustomConverter() {
		if (this.customConverter == null) {
			throw new IllegalStateException("custom converter is null"); //$NON-NLS-1$
		}
		this.getCustomConverterAdapter().removeConverterAnnotation(this.getJavaResourceType());
		this.setCustomConverter_(null);
	}

	protected void setCustomConverter_(JavaEclipseLinkCustomConverter converter) {
		JavaEclipseLinkCustomConverter old = this.customConverter;
		this.customConverter = converter;
		this.firePropertyChanged(CUSTOM_CONVERTER_PROPERTY, old, converter);
	}

	protected JavaEclipseLinkCustomConverter buildCustomConverter() {
		return this.buildConverter(this.getCustomConverterAdapter());
	}

	protected void syncCustomConverter() {
		EclipseLinkNamedConverterAnnotation annotation = this.getCustomConverterAdapter().getConverterAnnotation(this.getJavaResourceType());
		if (annotation == null) {
			if (this.customConverter != null) {
				this.setCustomConverter_(null);
			}
		} else {
			if ((this.customConverter != null) && (this.customConverter.getConverterAnnotation() == annotation)) {
				this.customConverter.synchronizeWithResourceModel();
			} else {
				JavaEclipseLinkCustomConverter converter = this.buildConverter(this.getCustomConverterAdapter(), annotation);
				this.setCustomConverter_(converter);
			}
		}
	}

	protected JavaEclipseLinkCustomConverter.Adapter getCustomConverterAdapter() {
		return JavaEclipseLinkCustomConverter.Adapter.instance();
	}


	// ********** object type converter **********

	public JavaEclipseLinkObjectTypeConverter getObjectTypeConverter() {
		return this.objectTypeConverter;
	}

	public JavaEclipseLinkObjectTypeConverter addObjectTypeConverter() {
		if (this.objectTypeConverter != null) {
			throw new IllegalStateException("object type converter already exists: " + this.objectTypeConverter); //$NON-NLS-1$
		}
		JavaEclipseLinkObjectTypeConverter converter = this.buildNewConverter(this.getObjectTypeConverterAdapter());
		this.setObjectTypeConverter_(converter);
		return converter;
	}

	public void removeObjectTypeConverter() {
		if (this.objectTypeConverter == null) {
			throw new IllegalStateException("object type converter is null"); //$NON-NLS-1$
		}
		this.getObjectTypeConverterAdapter().removeConverterAnnotation(this.getJavaResourceType());
		this.setObjectTypeConverter_(null);
	}

	protected void setObjectTypeConverter_(JavaEclipseLinkObjectTypeConverter converter) {
		JavaEclipseLinkObjectTypeConverter old = this.objectTypeConverter;
		this.objectTypeConverter = converter;
		this.firePropertyChanged(OBJECT_TYPE_CONVERTER_PROPERTY, old, converter);
	}

	protected JavaEclipseLinkObjectTypeConverter buildObjectTypeConverter() {
		return this.buildConverter(this.getObjectTypeConverterAdapter());
	}

	protected void syncObjectTypeConverter() {
		EclipseLinkNamedConverterAnnotation annotation = this.getObjectTypeConverterAdapter().getConverterAnnotation(this.getJavaResourceType());
		if (annotation == null) {
			if (this.objectTypeConverter != null) {
				this.setObjectTypeConverter_(null);
			}
		} else {
			if ((this.objectTypeConverter != null) && (this.objectTypeConverter.getConverterAnnotation() == annotation)) {
				this.objectTypeConverter.synchronizeWithResourceModel();
			} else {
				JavaEclipseLinkObjectTypeConverter converter = this.buildConverter(this.getObjectTypeConverterAdapter(), annotation);
				this.setObjectTypeConverter_(converter);
			}
		}
	}

	protected JavaEclipseLinkObjectTypeConverter.Adapter getObjectTypeConverterAdapter() {
		return JavaEclipseLinkObjectTypeConverter.Adapter.instance();
	}


	// ********** struct converter **********

	public JavaEclipseLinkStructConverter getStructConverter() {
		return this.structConverter;
	}

	public JavaEclipseLinkStructConverter addStructConverter() {
		if (this.structConverter != null) {
			throw new IllegalStateException("struct converter already exists: " + this.structConverter); //$NON-NLS-1$
		}
		JavaEclipseLinkStructConverter converter = this.buildNewConverter(this.getStructConverterAdapter());
		this.setStructConverter_(converter);
		return converter;
	}

	public void removeStructConverter() {
		if (this.structConverter == null) {
			throw new IllegalStateException("struct converter is null"); //$NON-NLS-1$
		}
		this.getStructConverterAdapter().removeConverterAnnotation(this.getJavaResourceType());
		this.setStructConverter_(null);
	}

	protected void setStructConverter_(JavaEclipseLinkStructConverter converter) {
		JavaEclipseLinkStructConverter old = this.structConverter;
		this.structConverter = converter;
		this.firePropertyChanged(STRUCT_CONVERTER_PROPERTY, old, converter);
	}

	protected JavaEclipseLinkStructConverter buildStructConverter() {
		return this.buildConverter(this.getStructConverterAdapter());
	}

	protected void syncStructConverter() {
		EclipseLinkNamedConverterAnnotation annotation = this.getStructConverterAdapter().getConverterAnnotation(this.getJavaResourceType());
		if (annotation == null) {
			if (this.structConverter != null) {
				this.setStructConverter_(null);
			}
		} else {
			if ((this.structConverter != null) && (this.structConverter.getConverterAnnotation() == annotation)) {
				this.structConverter.synchronizeWithResourceModel();
			} else {
				JavaEclipseLinkStructConverter converter = this.buildConverter(this.getStructConverterAdapter(), annotation);
				this.setStructConverter_(converter);
			}
		}
	}

	protected JavaEclipseLinkStructConverter.Adapter getStructConverterAdapter() {
		return JavaEclipseLinkStructConverter.Adapter.instance();
	}


	// ********** object type converter **********

	public JavaEclipseLinkTypeConverter getTypeConverter() {
		return this.typeConverter;
	}

	public JavaEclipseLinkTypeConverter addTypeConverter() {
		if (this.typeConverter != null) {
			throw new IllegalStateException("type converter already exists: " + this.typeConverter); //$NON-NLS-1$
		}
		JavaEclipseLinkTypeConverter converter = this.buildNewConverter(this.getTypeConverterAdapter());
		this.setTypeConverter_(converter);
		return converter;
	}

	public void removeTypeConverter() {
		if (this.typeConverter == null) {
			throw new IllegalStateException("type converter is null"); //$NON-NLS-1$
		}
		this.getTypeConverterAdapter().removeConverterAnnotation(this.getJavaResourceType());
		this.setTypeConverter_(null);
	}

	protected void setTypeConverter_(JavaEclipseLinkTypeConverter converter) {
		JavaEclipseLinkTypeConverter old = this.typeConverter;
		this.typeConverter = converter;
		this.firePropertyChanged(TYPE_CONVERTER_PROPERTY, old, converter);
	}

	protected JavaEclipseLinkTypeConverter buildTypeConverter() {
		return this.buildConverter(this.getTypeConverterAdapter());
	}

	protected void syncTypeConverter() {
		EclipseLinkNamedConverterAnnotation annotation = this.getTypeConverterAdapter().getConverterAnnotation(this.getJavaResourceType());
		if (annotation == null) {
			if (this.typeConverter != null) {
				this.setTypeConverter_(null);
			}
		} else {
			if ((this.typeConverter != null) && (this.typeConverter.getConverterAnnotation() == annotation)) {
				this.typeConverter.synchronizeWithResourceModel();
			} else {
				JavaEclipseLinkTypeConverter converter = this.buildConverter(this.getTypeConverterAdapter(), annotation);
				this.setTypeConverter_(converter);
			}
		}
	}

	protected JavaEclipseLinkTypeConverter.Adapter getTypeConverterAdapter() {
		return JavaEclipseLinkTypeConverter.Adapter.instance();
	}


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

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

	protected JavaTypeMapping getTypeMapping() {
		return this.getParent();
	}

	protected JavaResourceType getJavaResourceType() {
		return this.getTypeMapping().getJavaResourceType();
	}

	@SuppressWarnings("unchecked")
	protected <C extends JavaEclipseLinkConverter<?>> C buildConverter(C.Adapter adapter) {
		return (C) adapter.buildConverter(this.getJavaResourceType(), this);
	}

	@SuppressWarnings("unchecked")
	protected <C extends JavaEclipseLinkConverter<?>> C buildConverter(C.Adapter adapter, EclipseLinkNamedConverterAnnotation converterAnnotation) {
		return (C) adapter.buildConverter(converterAnnotation, this);
	}

	@SuppressWarnings("unchecked")
	protected <C extends JavaEclipseLinkConverter<?>> C buildNewConverter(C.Adapter adapter) {
		return (C) adapter.buildNewConverter(this.getJavaResourceType(), this);
	}


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

	/**
	 * The converters are validated in the persistence unit.
	 * @see org.eclipse.jpt.jpa.eclipselink.core.context.persistence.EclipseLinkPersistenceUnit#validateConverters(List, IReporter)
	 */
	@Override
	public void validate(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) {
		super.validate(messages, reporter, astRoot);
		// converters are validated in the persistence unit
	}

	public TextRange getValidationTextRange(CompilationUnit astRoot) {
		TextRange textRange = this.getJavaResourceType().getTextRange(astRoot);
		return (textRange != null) ? textRange : this.getTypeMapping().getValidationTextRange(astRoot);
	}
}
