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

import java.util.List;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jpt.core.context.java.JavaTypeMapping;
import org.eclipse.jpt.core.internal.context.java.AbstractJavaJpaContextNode;
import org.eclipse.jpt.core.resource.java.JavaResourcePersistentType;
import org.eclipse.jpt.core.utility.TextRange;
import org.eclipse.jpt.eclipselink.core.context.CacheCoordinationType;
import org.eclipse.jpt.eclipselink.core.context.CacheType;
import org.eclipse.jpt.eclipselink.core.context.Caching;
import org.eclipse.jpt.eclipselink.core.context.ExistenceType;
import org.eclipse.jpt.eclipselink.core.context.ExpiryTimeOfDay;
import org.eclipse.jpt.eclipselink.core.context.java.JavaCaching;
import org.eclipse.jpt.eclipselink.core.internal.DefaultEclipseLinkJpaValidationMessages;
import org.eclipse.jpt.eclipselink.core.internal.EclipseLinkJpaValidationMessages;
import org.eclipse.jpt.eclipselink.core.resource.java.CacheAnnotation;
import org.eclipse.jpt.eclipselink.core.resource.java.ExistenceCheckingAnnotation;
import org.eclipse.jpt.eclipselink.core.resource.java.TimeOfDayAnnotation;
import org.eclipse.wst.validation.internal.provisional.core.IMessage;
import org.eclipse.wst.validation.internal.provisional.core.IReporter;

public class EclipseLinkJavaCaching extends AbstractJavaJpaContextNode implements JavaCaching
{
	
	protected CacheType specifiedType;
	protected Integer specifiedSize;
	protected Boolean specifiedShared;
	protected Boolean specifiedAlwaysRefresh;
	protected Boolean specifiedRefreshOnlyIfNewer;
	protected Boolean specifiedDisableHits;
	
	protected boolean existenceChecking;
	protected ExistenceType specifiedExistenceType;
	protected ExistenceType defaultExistenceType;

	protected CacheCoordinationType specifiedCoordinationType;
	
	protected Integer expiry;
	protected EclipseLinkJavaExpiryTimeOfDay expiryTimeOfDay;
	
	
	protected JavaResourcePersistentType resourcePersistentType;
	
	public EclipseLinkJavaCaching(JavaTypeMapping parent) {
		super(parent);
	}
	
	@Override
	public JavaTypeMapping getParent() {
		return (JavaTypeMapping) super.getParent();
	}
	

	//query for the cache annotation every time on setters.
	//call one setter and the CacheAnnotation could change. 
	//You could call more than one setter before this object has received any notification
	//from the java resource model
	protected CacheAnnotation getCacheAnnotation() {
		return (CacheAnnotation) this.resourcePersistentType.getNonNullSupportingAnnotation(getCacheAnnotationName());
	}
	
	protected ExistenceCheckingAnnotation getExistenceCheckingAnnotation() {
		return (ExistenceCheckingAnnotation) this.resourcePersistentType.getSupportingAnnotation(getExistenceCheckingAnnotationName());
	}

	protected String getCacheAnnotationName() {
		return CacheAnnotation.ANNOTATION_NAME;
	}
	
	protected String getExistenceCheckingAnnotationName() {
		return ExistenceCheckingAnnotation.ANNOTATION_NAME;
	}
	
	public CacheType getType() {
		return (this.getSpecifiedType() == null) ? this.getDefaultType() : this.getSpecifiedType();
	}

	public CacheType getDefaultType() {
		return DEFAULT_TYPE;
	}
		
	public CacheType getSpecifiedType() {
		return this.specifiedType;
	}
	
	public void setSpecifiedType(CacheType newSpecifiedType) {
		CacheType oldSpecifiedType = this.specifiedType;
		this.specifiedType = newSpecifiedType;
		this.getCacheAnnotation().setType(CacheType.toJavaResourceModel(newSpecifiedType));
		firePropertyChanged(SPECIFIED_TYPE_PROPERTY, oldSpecifiedType, newSpecifiedType);
	}
	
	/**
	 * internal setter used only for updating from the resource model.
	 * There were problems with InvalidThreadAccess exceptions in the UI
	 * when you set a value from the UI and the annotation doesn't exist yet.
	 * Adding the annotation causes an update to occur and then the exception.
	 */
	protected void setSpecifiedType_(CacheType newSpecifiedType) {
		CacheType oldSpecifiedType = this.specifiedType;
		this.specifiedType = newSpecifiedType;
		firePropertyChanged(SPECIFIED_TYPE_PROPERTY, oldSpecifiedType, newSpecifiedType);
	}

	public int getSize() {
		return (this.getSpecifiedSize() == null) ? getDefaultSize() : this.getSpecifiedSize().intValue();
	}

	public int getDefaultSize() {
		return Caching.DEFAULT_SIZE;
	}
	
	public Integer getSpecifiedSize() {
		return this.specifiedSize;
	}

	public void setSpecifiedSize(Integer newSpecifiedSize) {
		Integer oldSpecifiedSize = this.specifiedSize;
		this.specifiedSize = newSpecifiedSize;
		getCacheAnnotation().setSize(newSpecifiedSize);
		firePropertyChanged(SPECIFIED_SIZE_PROPERTY, oldSpecifiedSize, newSpecifiedSize);
	}
	
	protected void setSpecifiedSize_(Integer newSpecifiedSize) {
		Integer oldSpecifiedSize = this.specifiedSize;
		this.specifiedSize = newSpecifiedSize;
		firePropertyChanged(SPECIFIED_SIZE_PROPERTY, oldSpecifiedSize, newSpecifiedSize);
	}


	public boolean isShared() {
		return (this.specifiedShared == null) ? this.isDefaultShared() : this.specifiedShared.booleanValue();
	}
	
	public boolean isDefaultShared() {
		return Caching.DEFAULT_SHARED;
	}
	
	public Boolean getSpecifiedShared() {
		return this.specifiedShared;
	}
	
	public void setSpecifiedShared(Boolean newSpecifiedShared) {
		Boolean oldShared = this.specifiedShared;
		this.specifiedShared = newSpecifiedShared;
		this.getCacheAnnotation().setShared(newSpecifiedShared);
		firePropertyChanged(Caching.SPECIFIED_SHARED_PROPERTY, oldShared, newSpecifiedShared);
		
		if (newSpecifiedShared == Boolean.FALSE) {
			setSpecifiedType(null);
			setSpecifiedSize(null);
			setSpecifiedAlwaysRefresh(null);
			setSpecifiedRefreshOnlyIfNewer(null);
			setSpecifiedDisableHits(null);
			setSpecifiedCoordinationType(null);
			setExpiry(null);
			if (this.expiryTimeOfDay != null) {
				removeExpiryTimeOfDay();
			}
		}
	}

	protected void setSpecifiedShared_(Boolean newSpecifiedShared) {
		Boolean oldSpecifiedShared = this.specifiedShared;
		this.specifiedShared = newSpecifiedShared;
		firePropertyChanged(Caching.SPECIFIED_SHARED_PROPERTY, oldSpecifiedShared, newSpecifiedShared);
	}

	public boolean isAlwaysRefresh() {
		return (this.specifiedAlwaysRefresh == null) ? this.isDefaultAlwaysRefresh() : this.specifiedAlwaysRefresh.booleanValue();
	}
	
	public boolean isDefaultAlwaysRefresh() {
		return Caching.DEFAULT_ALWAYS_REFRESH;
	}
	
	public Boolean getSpecifiedAlwaysRefresh() {
		return this.specifiedAlwaysRefresh;
	}
	
	public void setSpecifiedAlwaysRefresh(Boolean newSpecifiedAlwaysRefresh) {
		Boolean oldAlwaysRefresh = this.specifiedAlwaysRefresh;
		this.specifiedAlwaysRefresh = newSpecifiedAlwaysRefresh;
		this.getCacheAnnotation().setAlwaysRefresh(newSpecifiedAlwaysRefresh);
		firePropertyChanged(Caching.SPECIFIED_ALWAYS_REFRESH_PROPERTY, oldAlwaysRefresh, newSpecifiedAlwaysRefresh);
	}

	protected void setSpecifiedAlwaysRefresh_(Boolean newSpecifiedAlwaysRefresh) {
		Boolean oldAlwaysRefresh = this.specifiedAlwaysRefresh;
		this.specifiedAlwaysRefresh = newSpecifiedAlwaysRefresh;
		firePropertyChanged(Caching.SPECIFIED_ALWAYS_REFRESH_PROPERTY, oldAlwaysRefresh, newSpecifiedAlwaysRefresh);
	}

	public boolean isRefreshOnlyIfNewer() {
		return (this.specifiedRefreshOnlyIfNewer == null) ? this.isDefaultRefreshOnlyIfNewer() : this.specifiedRefreshOnlyIfNewer.booleanValue();
	}
	
	public boolean isDefaultRefreshOnlyIfNewer() {
		return Caching.DEFAULT_REFRESH_ONLY_IF_NEWER;
	}
	
	public Boolean getSpecifiedRefreshOnlyIfNewer() {
		return this.specifiedRefreshOnlyIfNewer;
	}
	
	public void setSpecifiedRefreshOnlyIfNewer(Boolean newSpecifiedRefreshOnlyIfNewer) {
		Boolean oldRefreshOnlyIfNewer = this.specifiedRefreshOnlyIfNewer;
		this.specifiedRefreshOnlyIfNewer = newSpecifiedRefreshOnlyIfNewer;
		this.getCacheAnnotation().setRefreshOnlyIfNewer(newSpecifiedRefreshOnlyIfNewer);
		firePropertyChanged(Caching.SPECIFIED_REFRESH_ONLY_IF_NEWER_PROPERTY, oldRefreshOnlyIfNewer, newSpecifiedRefreshOnlyIfNewer);
	}

	protected void setSpecifiedRefreshOnlyIfNewer_(Boolean newSpecifiedRefreshOnlyIfNewer) {
		Boolean oldRefreshOnlyIfNewer = this.specifiedRefreshOnlyIfNewer;
		this.specifiedRefreshOnlyIfNewer = newSpecifiedRefreshOnlyIfNewer;
		firePropertyChanged(Caching.SPECIFIED_REFRESH_ONLY_IF_NEWER_PROPERTY, oldRefreshOnlyIfNewer, newSpecifiedRefreshOnlyIfNewer);
	}

	public boolean isDisableHits() {
		return (this.specifiedDisableHits == null) ? this.isDefaultDisableHits() : this.specifiedDisableHits.booleanValue();
	}
	
	public boolean isDefaultDisableHits() {
		return Caching.DEFAULT_DISABLE_HITS;
	}
	
	public Boolean getSpecifiedDisableHits() {
		return this.specifiedDisableHits;
	}
	
	public void setSpecifiedDisableHits(Boolean newSpecifiedDisableHits) {
		Boolean oldDisableHits = this.specifiedDisableHits;
		this.specifiedDisableHits = newSpecifiedDisableHits;
		this.getCacheAnnotation().setDisableHits(newSpecifiedDisableHits);
		firePropertyChanged(Caching.SPECIFIED_DISABLE_HITS_PROPERTY, oldDisableHits, newSpecifiedDisableHits);
	}

	protected void setSpecifiedDisableHits_(Boolean newSpecifiedDisableHits) {
		Boolean oldDisableHits = this.specifiedDisableHits;
		this.specifiedDisableHits = newSpecifiedDisableHits;
		firePropertyChanged(Caching.SPECIFIED_DISABLE_HITS_PROPERTY, oldDisableHits, newSpecifiedDisableHits);
	}
	
	public CacheCoordinationType getCoordinationType() {
		return (this.getSpecifiedCoordinationType() == null) ? this.getDefaultCoordinationType() : this.getSpecifiedCoordinationType();
	}

	public CacheCoordinationType getDefaultCoordinationType() {
		return DEFAULT_COORDINATION_TYPE;
	}
		
	public CacheCoordinationType getSpecifiedCoordinationType() {
		return this.specifiedCoordinationType;
	}
	
	public void setSpecifiedCoordinationType(CacheCoordinationType newSpecifiedCoordinationType) {
		CacheCoordinationType oldSpecifiedCoordinationType = this.specifiedCoordinationType;
		this.specifiedCoordinationType = newSpecifiedCoordinationType;
		this.getCacheAnnotation().setCoordinationType(CacheCoordinationType.toJavaResourceModel(newSpecifiedCoordinationType));
		firePropertyChanged(SPECIFIED_COORDINATION_TYPE_PROPERTY, oldSpecifiedCoordinationType, newSpecifiedCoordinationType);
	}
	
	/**
	 * internal setter used only for updating from the resource model.
	 * There were problems with InvalidThreadAccess exceptions in the UI
	 * when you set a value from the UI and the annotation doesn't exist yet.
	 * Adding the annotation causes an update to occur and then the exception.
	 */
	protected void setSpecifiedCoordinationType_(CacheCoordinationType newSpecifiedCoordinationType) {
		CacheCoordinationType oldSpecifiedCoordinationType = this.specifiedCoordinationType;
		this.specifiedCoordinationType = newSpecifiedCoordinationType;
		firePropertyChanged(SPECIFIED_COORDINATION_TYPE_PROPERTY, oldSpecifiedCoordinationType, newSpecifiedCoordinationType);
	}
	
	public boolean hasExistenceChecking() {
		return this.existenceChecking;
	}
	
	public void setExistenceChecking(boolean newExistenceChecking) {
		boolean oldExistenceChecking = this.existenceChecking;
		this.existenceChecking = newExistenceChecking;
		if (newExistenceChecking) {
			this.resourcePersistentType.addSupportingAnnotation(getExistenceCheckingAnnotationName());
		}
		else {
			this.resourcePersistentType.removeSupportingAnnotation(getExistenceCheckingAnnotationName());
		}
		firePropertyChanged(EXISTENCE_CHECKING_PROPERTY, oldExistenceChecking, newExistenceChecking);
		setDefaultExistenceType(caclulateDefaultExistenceType());
	}
	
	protected void setExistenceChecking_(boolean newExistenceChecking) {
		boolean oldExistenceChecking = this.existenceChecking;
		this.existenceChecking = newExistenceChecking;
		firePropertyChanged(EXISTENCE_CHECKING_PROPERTY, oldExistenceChecking, newExistenceChecking);
	}
	
	protected ExistenceType caclulateDefaultExistenceType() {
		if (hasExistenceChecking()) {
			return ExistenceType.CHECK_CACHE;
		}
		return DEFAULT_EXISTENCE_TYPE;
	}
	
	public ExistenceType getExistenceType() {
		return (this.getSpecifiedExistenceType() == null) ? this.getDefaultExistenceType() : this.getSpecifiedExistenceType();
	}

	public ExistenceType getDefaultExistenceType() {
		return this.defaultExistenceType;
	}
	
	protected void setDefaultExistenceType(ExistenceType newDefaultExistenceType) {
		ExistenceType oldDefaultExistenceType = this.defaultExistenceType;
		this.defaultExistenceType = newDefaultExistenceType;
		firePropertyChanged(DEFAULT_EXISTENCE_TYPE_PROPERTY, oldDefaultExistenceType, newDefaultExistenceType);
	}
	
	public ExistenceType getSpecifiedExistenceType() {
		return this.specifiedExistenceType;
	}
	
	public void setSpecifiedExistenceType(ExistenceType newSpecifiedExistenceType) {
		if (!hasExistenceChecking()) {
			if (newSpecifiedExistenceType != null) {
				setExistenceChecking(true);
			}
			else {
				return;
			}
		}
		ExistenceType oldSpecifiedExistenceType = this.specifiedExistenceType;
		this.specifiedExistenceType = newSpecifiedExistenceType;
		this.getExistenceCheckingAnnotation().setValue(ExistenceType.toJavaResourceModel(newSpecifiedExistenceType));
		firePropertyChanged(SPECIFIED_EXISTENCE_TYPE_PROPERTY, oldSpecifiedExistenceType, newSpecifiedExistenceType);
	}
	
	/**
	 * internal setter used only for updating from the resource model.
	 * There were problems with InvalidThreadAccess exceptions in the UI
	 * when you set a value from the UI and the annotation doesn't exist yet.
	 * Adding the annotation causes an update to occur and then the exception.
	 */
	protected void setSpecifiedExistenceType_(ExistenceType newSpecifiedExistenceType) {
		ExistenceType oldSpecifiedExistenceType = this.specifiedExistenceType;
		this.specifiedExistenceType = newSpecifiedExistenceType;
		firePropertyChanged(SPECIFIED_EXISTENCE_TYPE_PROPERTY, oldSpecifiedExistenceType, newSpecifiedExistenceType);
	}

	public Integer getExpiry() {
		return this.expiry;
	}
	
	public void setExpiry(Integer newExpiry) {
		Integer oldExpiry = this.expiry;
		this.expiry = newExpiry;
		getCacheAnnotation().setExpiry(newExpiry);
		firePropertyChanged(EXPIRY_PROPERTY, oldExpiry, newExpiry);
		if (newExpiry != null && this.expiryTimeOfDay != null) {
			removeExpiryTimeOfDay();
		}
	}
	
	protected void setExpiry_(Integer newExpiry) {
		Integer oldExpiry = this.expiry;
		this.expiry = newExpiry;
		firePropertyChanged(EXPIRY_PROPERTY, oldExpiry, newExpiry);
	}
	
	public ExpiryTimeOfDay getExpiryTimeOfDay() {
		return this.expiryTimeOfDay;
	}
	
	public ExpiryTimeOfDay addExpiryTimeOfDay() {
		if (this.expiryTimeOfDay != null) {
			throw new IllegalStateException("expiryTimeOfDay already exists, use getExpiryTimeOfDay()"); //$NON-NLS-1$
		}
		if (this.resourcePersistentType.getSupportingAnnotation(getCacheAnnotationName()) == null) {
			this.resourcePersistentType.addSupportingAnnotation(getCacheAnnotationName());
		}
		EclipseLinkJavaExpiryTimeOfDay newExpiryTimeOfDay = new EclipseLinkJavaExpiryTimeOfDay(this);
		this.expiryTimeOfDay = newExpiryTimeOfDay;
		TimeOfDayAnnotation timeOfDayAnnotation = getCacheAnnotation().addExpiryTimeOfDay();
		newExpiryTimeOfDay.initialize(timeOfDayAnnotation);
		firePropertyChanged(EXPIRY_TIME_OF_DAY_PROPERTY, null, newExpiryTimeOfDay);
		setExpiry(null);
		return newExpiryTimeOfDay;
	}
	
	public void removeExpiryTimeOfDay() {
		if (this.expiryTimeOfDay == null) {
			throw new IllegalStateException("timeOfDayExpiry does not exist"); //$NON-NLS-1$
		}
		ExpiryTimeOfDay oldExpiryTimeOfDay = this.expiryTimeOfDay;
		this.expiryTimeOfDay = null;
		getCacheAnnotation().removeExpiryTimeOfDay();
		firePropertyChanged(EXPIRY_TIME_OF_DAY_PROPERTY, oldExpiryTimeOfDay, null);
	}
	
	protected void setExpiryTimeOfDay(EclipseLinkJavaExpiryTimeOfDay newExpiryTimeOfDay) {
		EclipseLinkJavaExpiryTimeOfDay oldExpiryTimeOfDay = this.expiryTimeOfDay;
		this.expiryTimeOfDay = newExpiryTimeOfDay;
		firePropertyChanged(EXPIRY_TIME_OF_DAY_PROPERTY, oldExpiryTimeOfDay, newExpiryTimeOfDay);
	}
	
	public void initialize(JavaResourcePersistentType resourcePersistentType) {
		this.resourcePersistentType = resourcePersistentType;
		initialize(getCacheAnnotation());
		initialize(getExistenceCheckingAnnotation());
	}

	protected void initialize(CacheAnnotation cache) {
		this.specifiedType = this.specifiedType(cache);
		this.specifiedSize = this.specifiedSize(cache);
		this.specifiedShared = this.specifiedShared(cache);
		this.specifiedAlwaysRefresh = this.specifiedAlwaysRefresh(cache);
		this.specifiedRefreshOnlyIfNewer = this.specifiedRefreshOnlyIfNewer(cache);
		this.specifiedDisableHits = this.specifiedDisableHits(cache);
		this.specifiedCoordinationType = this.specifiedCoordinationType(cache);
		this.initializeExpiry(cache);
	}
	
	protected void initialize(ExistenceCheckingAnnotation existenceChecking) {
		this.existenceChecking = existenceChecking != null;
		this.specifiedExistenceType = specifiedExistenceType(existenceChecking);
		this.defaultExistenceType = this.caclulateDefaultExistenceType();
	}

	protected void initializeExpiry(CacheAnnotation cache) {
		if (cache.getExpiryTimeOfDay() == null) {
			this.expiry = cache.getExpiry();
		}
		else {
			if (cache.getExpiry() == null) { //handle with validation if both expiry and expiryTimeOfDay are set
				this.expiryTimeOfDay = new EclipseLinkJavaExpiryTimeOfDay(this);
				this.expiryTimeOfDay.initialize(cache.getExpiryTimeOfDay());
			}
		}
	}
	
	public void update(JavaResourcePersistentType resourcePersistentType) {
		this.resourcePersistentType = resourcePersistentType;
		update(getCacheAnnotation());
		update(getExistenceCheckingAnnotation());
		updateExpiry(getCacheAnnotation());
	}
	
	protected void update(CacheAnnotation cache) {
		setSpecifiedType_(this.specifiedType(cache));
		setSpecifiedSize_(this.specifiedSize(cache));
		setSpecifiedShared_(this.specifiedShared(cache));
		setSpecifiedAlwaysRefresh_(this.specifiedAlwaysRefresh(cache));
		setSpecifiedRefreshOnlyIfNewer_(this.specifiedRefreshOnlyIfNewer(cache));
		setSpecifiedDisableHits_(this.specifiedDisableHits(cache));
		setSpecifiedCoordinationType_(this.specifiedCoordinationType(cache));
	}

	protected void update(ExistenceCheckingAnnotation existenceChecking) {
		setExistenceChecking_(existenceChecking != null);
		setSpecifiedExistenceType_(specifiedExistenceType(existenceChecking));
		setDefaultExistenceType(caclulateDefaultExistenceType());
	}
	
	protected void updateExpiry(CacheAnnotation cache) {
		if (cache.getExpiryTimeOfDay() == null) {
			setExpiryTimeOfDay(null);
			setExpiry_(cache.getExpiry());
		}
		else {
			if (this.expiryTimeOfDay != null) {
				this.expiryTimeOfDay.update(cache.getExpiryTimeOfDay());
			}
			else if (cache.getExpiry() == null){
				setExpiryTimeOfDay(new EclipseLinkJavaExpiryTimeOfDay(this));
				this.expiryTimeOfDay.initialize(cache.getExpiryTimeOfDay());
			}
			else { //handle with validation if both expiry and expiryTimeOfDay are set
				setExpiryTimeOfDay(null);
			}
		}
	}

	protected CacheType specifiedType(CacheAnnotation cache) {
		return CacheType.fromJavaResourceModel(cache.getType());
	}

	protected Integer specifiedSize(CacheAnnotation cache) {
		return cache.getSize();
	}
	
	protected Boolean specifiedShared(CacheAnnotation cache) {
		return cache.getShared();
	}	
	
	protected Boolean specifiedAlwaysRefresh(CacheAnnotation cache) {
		return cache.getAlwaysRefresh();
	}	
	
	protected Boolean specifiedRefreshOnlyIfNewer(CacheAnnotation cache) {
		return cache.getRefreshOnlyIfNewer();
	}	
	
	protected Boolean specifiedDisableHits(CacheAnnotation cache) {
		return cache.getDisableHits();
	}
	
	protected CacheCoordinationType specifiedCoordinationType(CacheAnnotation cache) {
		return CacheCoordinationType.fromJavaResourceModel(cache.getCoordinationType());
	}
	
	protected Integer expiry(CacheAnnotation cache) {
		return cache.getExpiry();
	}
	
	protected ExistenceType specifiedExistenceType(ExistenceCheckingAnnotation existenceChecking) {
		if (existenceChecking == null) {
			return null;
		}
		return ExistenceType.fromJavaResourceModel(existenceChecking.getValue());
	}


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

	@Override
	public void validate(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) {
		super.validate(messages, reporter, astRoot);
		this.validateExpiry(messages, astRoot);
	}

	protected void validateExpiry(List<IMessage> messages, CompilationUnit astRoot) {
		CacheAnnotation cache = getCacheAnnotation();
		if (cache.getExpiry() != null && cache.getExpiryTimeOfDay() != null) {
			messages.add(
				DefaultEclipseLinkJpaValidationMessages.buildMessage(
					IMessage.HIGH_SEVERITY,
					EclipseLinkJpaValidationMessages.CACHE_EXPIRY_AND_EXPIRY_TIME_OF_DAY_BOTH_SPECIFIED,
					new String[] {this.getParent().getPersistentType().getName()},
					this, 
					getValidationTextRange(astRoot)
				)
			);
		}
	}
}
