/*******************************************************************************
 * Copyright (c) 2007, 2008 IBM Corporation and others.
 * 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.wst.validation;

import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.osgi.util.NLS;
import org.eclipse.wst.validation.internal.ConfigurationManager;
import org.eclipse.wst.validation.internal.MarkerManager;
import org.eclipse.wst.validation.internal.Misc;
import org.eclipse.wst.validation.internal.SummaryReporter;
import org.eclipse.wst.validation.internal.ValManager;
import org.eclipse.wst.validation.internal.ValMessages;
import org.eclipse.wst.validation.internal.ValOperation;
import org.eclipse.wst.validation.internal.ValOperationManager;
import org.eclipse.wst.validation.internal.ValPrefManagerGlobal;
import org.eclipse.wst.validation.internal.ValPrefManagerProject;
import org.eclipse.wst.validation.internal.ValType;
import org.eclipse.wst.validation.internal.ValidationConfiguration;
import org.eclipse.wst.validation.internal.ValidatorExtensionReader;
import org.eclipse.wst.validation.internal.ValidatorMetaData;
import org.eclipse.wst.validation.internal.core.ValidatorLauncher;
import org.eclipse.wst.validation.internal.delegates.ValidatorDelegateDescriptor;
import org.eclipse.wst.validation.internal.delegates.ValidatorDelegatesRegistry;
import org.eclipse.wst.validation.internal.model.FilterGroup;
import org.eclipse.wst.validation.internal.operations.IWorkbenchContext;
import org.eclipse.wst.validation.internal.operations.WorkbenchContext;
import org.eclipse.wst.validation.internal.plugin.ValidationPlugin;
import org.eclipse.wst.validation.internal.provisional.core.IMessage;
import org.eclipse.wst.validation.internal.provisional.core.IValidator;

/**
 * Represents a validator. This gets instantiated through one of the validator extension points.
 * 
 * @author karasiuk
 *
 */
public abstract class Validator implements Comparable {
	// Remember if you add a new instance variable, make sure that you update the copy and become methods
	
	/**
	 * The level of configuration for the validator.
	 * <ul>
	 * <li>Extension - Defined by an extension point.</li>
	 * <li>Global - Defined by a global preference.</li>
	 * <li>Project - Defined by a project property.</li>
	 * </ul>
	 */
	public enum Level {Extension, Global, Project};
	
	protected boolean	_buildValidation = true;
	
	/** If this is a delegating validator, then this field holds the validator that will be delegated to. */
	private String 		_delegatingId;
	
	/** 
	 * If this validator is also used to control an ISource validator, the id of the ISource validator is
	 * registered here.
	 */
	private String		_sourceId;
	
	protected boolean 	_manualValidation = true;
	
	/** An optional customized marker id for this validator. */
	private String 		_markerId;
	
	/** 
	 * Version of the filter definition. By increasing this number the framework can know that a plug-in has 
	 * changed it's filters.
	 */
	private int			_version = 1;
	
	/** Map simple message id's to message settings. */
	private Map<String, MessageSeveritySetting> _messageSettings;
	
	/** The project that you are defined in. This can be null which means that you are a global validator. */
	protected IProject	_project;
		
	/** How many times has a global field in this validator been changed since it was created (or copied)? */
	protected transient int _changeCountGlobal;
	
	/** How many times has a message field in this validator been changed since it was created (or copied)? */
	protected transient int _changeCountMessages;
	
	/**
	 * Create a new validator based on a abstract validator.
	 * 
	 * @param validator
	 *            The validator that is being wrapped.
	 * 
	 * @param project
	 *            The project that you are defined in. This can be null which
	 *            means that you are a global validator.
	 */
	public static Validator create(AbstractValidator validator, IProject project) {
		V2 v2 = new V2(validator, project);
		validator.setParent(v2);
		return v2;
	}
	
	/**
	 * Create a new validator based on validator meta data.
	 * 
	 * @param project
	 *            The project that you are defined in. This can be null which
	 *            means that you are a global validator.
	 */
	public static Validator create(ValidatorMetaData vmd, ValidationConfiguration config, IProject project){
		V1 v1 = new V1(vmd, config);
		v1._project = project;
		return v1;
	}
	
	/**
	 * If you are a version 1 validator, answer yourself as one, otherwise answer null.
	 */
	public V1 asV1Validator(){
		return null;
	}
	
	/**
	 * If you are a version 2 validator, answer yourself as one, otherwise answer null.
	 */
	public V2 asV2Validator() {
		return null;
	}
	
	/**
	 * The project is being cleaned, this method gives the validator a chance to do any special cleanup.
	 * The default is to do nothing.
	 * 
	 * @param project the project being built.
	 * @param monitor the monitor that should be used for reporting progress if the clean takes a long time.
	 */
	public void clean(IProject project, IProgressMonitor monitor){
	}	
	
	/**
	 * Compare yourself based on Validator name.
	 */
	public int compareTo(Object validator) {
		if (validator instanceof Validator){
			Validator other = (Validator)validator;
			return getName().compareTo(other.getName());			
		}
		return -1;
	}
	
	/** Answer a deep copy of yourself. */
	public abstract Validator copy();
	
	/**
	 * Update your direct, non transient fields from the fields in v.
	 */
	protected void copyLocal(Validator v){
		_buildValidation = v._buildValidation;
		_delegatingId = v._delegatingId;
		_manualValidation = v._manualValidation;
		_markerId = v._markerId;
		_messageSettings = v._messageSettings;
		_project = v._project;
		_sourceId = v._sourceId;
		_version = v._version;
	}
	
	/**
	 * Answer true if this validator, based on it's filters, should validate this resource. This method
	 * does not check to see if global validation or project validation has been suspended or not.
	 * 
	 * @param resource the resource to be checked
	 * @param isManual if true then this validator must also be enabled for manual validation.
	 * @param isBuild if true then this validator must also be enabled for builder based validation.
	 * 
	 * @return true if the resource should be validated.
	 */
	public boolean shouldValidate(IResource resource, boolean isManual, boolean isBuild){
		if (isManual && !_manualValidation)return false;
		if (isBuild && !_buildValidation)return false;
		
		return shouldValidate(resource);
	}
	
	/**
	 * Answer true if this validator, based on it's filters, should validate this resource. This method
	 * does not check to see if global validation or project validation has been suspended or not.
	 * 
	 * @param resource the resource to be checked
	 * @param valType The content to use when perform the check.
	 * 
	 * @return true if the resource should be validated.
	 */
	public boolean shouldValidate(IResource resource, ValType valType){
		if (valType == ValType.Manual && !_manualValidation)return false;
		if (valType == ValType.Build && !_buildValidation)return false;
		
		return shouldValidate(resource);
	}
	
	/**
	 * Answer true if this validator, based on it's filters, should validate this project. This method
	 * does not check to see if global validation or project validation has been suspended or not.
	 * 
	 * @param project the project to be checked
	 * @param isManual if true then this validator must also be enabled for manual validation.
	 * @param isBuild if true then this validator must also be enabled for builder based validation.
	 * 
	 * @return true if the project should be validated.
	 */
	public boolean shouldValidateProject(IProject project, boolean isManual, boolean isBuild){
		if (isManual && !_manualValidation)return false;
		if (isBuild && !_buildValidation)return false;
		if (project == null || !project.isOpen())return false;
		return shouldValidateProject(project);
	}
	/**
	 * Validate the resource.
	 * 
	 * @param resource the resource to be validated
	 * @param kind the kind of resource change, see IResourceDelta for values.
	 * @param operation the operation that this validation is running under. This can be null.
	 * @param monitor a way to report progress. This can be null.
	 * 
	 * @return the result of doing the validation, it can be, but usually isn't null.
	 */
	public abstract ValidationResult validate(IResource resource, int kind, ValOperation operation, IProgressMonitor monitor);	

	/**
	 * This method will be called before any validation takes place. It allows validators to perform any
	 * initialization that they might need. 
	 *  
	 * @param project the project that is being validated. For the very first call in the validation phase,
	 * this will be null. That is the signal to the validator that a top level validation is starting.
	 * Subsequently, the project will be set, as each of the individual projects are validated.
	 * 
	 * @param state a way to pass arbitrary, validator specific, data from one invocation of a validator to
	 * the next, during the validation phase.
	 * 
	 * @param monitor the monitor that should be used for reporting progress if the clean takes a long time.
	 */
	public void validationStarting(IProject project, ValidationState state, IProgressMonitor monitor){
		// subclasses need to override this, if they wish to let their validators know about this event
	}
	
	/**
	 * This method will be called when validation is complete. It allows validators to perform any
	 * cleanup that they might need to do.  
	 *  
	 * @param project the project that was validated. The very last call in the validation will set this to 
	 * null so that the validator knows that all the projects have now been validated.
	 * 
	 * @param state a way to pass arbitrary, validator specific, data from one invocation of a validator to
	 * the next, during the validation phase.
	 * 
	 * @param monitor the monitor that should be used for reporting progress if the clean takes a long time.
	 */
	public void validationFinishing(IProject project, ValidationState state, IProgressMonitor monitor){		
		// subclasses need to override this, if they wish to let their validators know about this event
	}
	
	void add(MessageSeveritySetting message){
		// I can't use getMessageSettings() here, as that will put us into an infinite loop
		if (_messageSettings == null){
			_messageSettings = new HashMap<String, MessageSeveritySetting>(10);
		}
		_messageSettings.put(message.getId(), message);
		bumpChangeCountMessages();
	}
	
	public IValidator asIValidator(){
		return null;
	}
	
	protected abstract boolean shouldValidate(IResource resource);
	protected abstract boolean shouldValidateProject(IProject project);
			
	public abstract String getId();
	
	public MessageSeveritySetting getMessage(String id){
		return getMessageSettings().get(id);
	}
	
	/**
	 * Answer all the message settings that this validator has defined.
	 * 
	 * @return an empty map if the validator did not define any message settings.
	 */
	public Map<String, MessageSeveritySetting> getMessageSettings(){
		Map<String, MessageSeveritySetting> settings = _messageSettings;
		if (settings == null){
			settings = new HashMap<String, MessageSeveritySetting>(10);
			init(settings);
			if (ValManager.getDefault().mustUseGlobalValidators(getProject())){
				ValPrefManagerGlobal gp = ValPrefManagerGlobal.getDefault();
				gp.loadMessages(this, settings);
			}
			else {
				ValPrefManagerProject vp = new ValPrefManagerProject(getProject());
				vp.loadMessages(this, settings);				
			}
			_messageSettings = settings;
		}
		return settings;
	}
	
	/**
	 * Answer a hash code for the configurable fields so that we can quickly determine if two
	 * validators are the same.
	 */
	public int hashCodeForConfig(){
		int h = 0;
		if (_buildValidation)h += 101;
		if (_delegatingId != null)h += _delegatingId.hashCode();
		if (_manualValidation)h += 201;
		if (_messageSettings != null){
			for (MessageSeveritySetting ms : _messageSettings.values())h += ms.hashCode();
		}
		if (_sourceId != null)h += _sourceId.hashCode();
		h += _version;
		return h;
	}
	
	private void init(Map<String, MessageSeveritySetting> settings) {
		for (MessageSeveritySetting ms : ValidatorExtensionReader.getDefault().addMessages(this)){
			settings.put(ms.getId(), ms);
		}		
	}

	public abstract String getName();
	
	/**
	 * Answer the project that you were enabled on. 
	 * 
	 * @return null if you are a global (i.e. workspace level) validator.
	 */
	public IProject getProject(){
		return _project;
	}
		
	/**
	 * Answer the name of the class that implements the validator.
	 * @return
	 */
	public abstract String getValidatorClassname();
	
	/**
	 * Is this validator currently enabled for validations that are triggered manually? 
	 */
	public boolean isManualValidation() {
		return _manualValidation;
	}

	/**
	 * Set whether this validator should be triggered as part of a manual validation.
	 * 
	 * @param manualValidation
	 */
	public void setManualValidation(boolean manualValidation) {
		setManualValidation2(manualValidation);
	}
	
	protected final void setManualValidation2(boolean manualValidation) {
		if (_manualValidation != manualValidation){
			bumpChangeCountGlobal();
			_manualValidation = manualValidation;
		}
	}

	/**
	 * Is this validator currently enabled for validations that are triggered by builds? 
	 */
	public boolean isBuildValidation() {
		return _buildValidation;
	}
	
	/**
	 * Has the validator changed since it was last created or copied?
	 */
	public boolean isChanged(){
		if (_changeCountGlobal > 0 || _changeCountMessages > 0)return true;
		return false;
	}

	/**
	 * Set whether this validator should be triggered by the build process.
	 * 
	 * @param buildValidation
	 */
	public void setBuildValidation(boolean buildValidation) {
		setBuildValidation2(buildValidation);
	}
	
	protected final void setBuildValidation2(boolean buildValidation) {
		if (_buildValidation != buildValidation){
			bumpChangeCountGlobal();
			_buildValidation = buildValidation;
		}
	}

	/**
	 * Get the id of the "real" validator, that is the validator that will be called when this delegating
	 * validator is asked to validate something. If this isn't a delegating validator answer null.
	 */
	public String getDelegatingId() {
		return _delegatingId;
	}
	
	public String getDependencyId(){
		return getId();
	}
	
	/**
	 * Set the id of the "real" validator, that is the validator that will be called when this delegating
	 * validator is asked to validate something.
	 * 
	 * @param delegating the id of the validator that is actually going to perform the validation.
	 */
	public void setDelegatingId(String delegating) {
		if (!Misc.same(_delegatingId, delegating)){
			_delegatingId = delegating;
			bumpChangeCountGlobal();
		}
	}
	
	public int getVersion() {
		return _version;
	}
	
	public void setVersion(int version) {
		if (_version != version){
			_version = version;
			bumpChangeCountGlobal();
		}
	}
	
	@Override
	public String toString() {
		return getName();
	}
		
/**
 * A validator that uses version 1 of the validation framework.
 * @author karasiuk
 *
 */ 
public static class V1 extends Validator {
	private ValidatorMetaData _vmd;
	
	/**
	 * Create a new version 1 validator. 
	 * @param vmd
	 * @param config this is used to set the global enablement options. In some case this can be null.
	 */
	public V1(ValidatorMetaData vmd, ValidationConfiguration config){
		_vmd = vmd;
		if (config != null){
			setBuildValidation(config.isBuildEnabled(vmd));
			setManualValidation(config.isManualEnabled(vmd));
		}
		setDelegatingId(ValidatorDelegatesRegistry.getInstance().getDefaultDelegate(getValidatorClassname()));
		if (_vmd.getMarkerIds() != null && _vmd.getMarkerIds().length > 0)setMarkerId(_vmd.getMarkerIds()[0]);
		resetChangeCounters();
	}
	
	@Override
	public IValidator asIValidator() {
		IValidator v = null;
		try {
			v = _vmd.getValidator();
		}
		catch (InstantiationException e){
			ValidationPlugin.getPlugin().handleException(e);
			return null;
		}
		return v;
	}
	
	public V1 asV1Validator() {
		return this;
	}
	
	@Override
	public void become(Validator val) {
		super.become(val);
		V1 v1 = val.asV1Validator();
		if (v1 == null)throw new IllegalArgumentException("Internal error, the incoming validator must be a v1 validator"); //$NON-NLS-1$
		_vmd = v1._vmd;
	}
		
	public Validator copy() {
		V1 v = new V1Copy(_vmd, null);
		v.copyLocal(this);
				
		return v;
	}
	
	public String getName() {
		return _vmd.getValidatorDisplayName();
	}
	
	public ValidatorMetaData getVmd(){
		return _vmd;
	}
	
	public String getValidatorClassname(){
		String name = ""; //$NON-NLS-1$
		try {
			name = _vmd.getValidator().getClass().getName();
		}
		catch (Exception e){
			// eat it
		}
		return name;
	}
	public String getId() {
		return _vmd.getValidatorUniqueName();
	}
	
	@Override
	public void setBuildValidation(boolean buildValidation) {
		super.setBuildValidation(buildValidation);
		_vmd.setBuildValidation(buildValidation);
	}
	
	@Override
	public void setManualValidation(boolean manualValidation) {
		super.setManualValidation(manualValidation);
		_vmd.setManualValidation(manualValidation);
	}

	@Override
	protected boolean shouldValidate(IResource resource) {
		return _vmd.isApplicableTo(resource);
	}

	@Override
	protected boolean shouldValidateProject(IProject project) {
		// TODO determine if this can be optimized
		return true;
	}

	@Override
	public ValidationResult validate(IResource resource, int kind, ValOperation operation, 
		IProgressMonitor monitor) {
		
		if (monitor == null)monitor = new NullProgressMonitor();
		
		ValidationResult vr = new ValidationResult();
		IValidator v = asIValidator();
		if (v == null)return null;
		
		try {
			IProject project = resource.getProject();
			SummaryReporter reporter = new SummaryReporter(project, monitor);
			IWorkbenchContext helper = _vmd.getHelper(project);
			if (helper instanceof WorkbenchContext){
				WorkbenchContext wc = (WorkbenchContext)helper;
				List<String> files = new LinkedList<String>();
				// [213631] The JSP validator expects full paths not relative paths, but the XML validator
				// expects relative paths.
				files.add(wc.getPortableName(resource));
				wc.setValidationFileURIs(files);
			}
			ValidatorLauncher.getLauncher().start(helper, v, reporter);
			
			vr.incrementError(reporter.getSeverityHigh());
			vr.incrementWarning(reporter.getSeverityNormal());
			vr.incrementInfo(reporter.getSeverityLow());
			
		}
		catch (Exception e){
			ValidationPlugin.getPlugin().handleException(e);
		}
		return vr;
	}
	
	/*
	 * GRK - Because I didn't want to try to make a true copy of the V1 validator, (because I didn't
	 * want to copy the vmd object), I came up with this approach to only copy the fields that
	 * the preference page was worried about. 
	 */
	public static class V1Copy extends V1 {
		public V1Copy(ValidatorMetaData vmd, ValidationConfiguration vc){
			super(vmd, vc);
		}
		
		@Override
		public void setManualValidation(boolean bool) {
			setManualValidation2(bool);
		}
		
		@Override
		public void setBuildValidation(boolean bool) {
			setBuildValidation2(bool);
		}
		
		@Override
		public void become(Validator val) {
			super.become(val);
			super.setBuildValidation(val.isBuildValidation());
			super.setManualValidation(val.isManualValidation());
		}
		
	}
		
}

/**
 * A validator that uses version 2 of the validation framework.
 * @author karasiuk
 *
 */
public final static class V2 extends Validator implements IAdaptable {
	private AbstractValidator	_validator;
	
	private List<FilterGroup>	_groups = new LinkedList<FilterGroup>();
	private FilterGroup[]		_groupsArray;
	
	/** The full id of the extension. */
	private String			_id;
	
	/** Name of the validator. */
	private String			_name;
		
	/** 
	 * If this validator is a delegating validator, then this is the "real" validator (i.e. the one that
	 * does the work).
	 */
	private AbstractValidator	_delegated;
		
	/** How many times has a group field in this validator been changed since it was created (or copied)? */
	protected transient int _changeCountGroups;
		
	private Level _level;
	
	V2(AbstractValidator base, IProject project){
		_validator = base;
		_project = project;
		base.setParent(this);
		try {
			String target = getValidatorClassname();
			String id = ConfigurationManager.getManager().getConfiguration(project).getDelegateForTarget(target);
			if (id == null) id = ValidatorDelegatesRegistry.getInstance().getDefaultDelegate(target);
			setDelegatingId(id);
		}
		catch (InvocationTargetException e){
			ValidationPlugin.getPlugin().handleException(e);
		}
		resetChangeCounters();
	}

	public synchronized void add(FilterGroup fg) {
		_groupsArray = null;
		_groups.add(fg);
		bumpChangeCountGroups();
	}
	
	@Override
	public IValidator asIValidator() {
		AbstractValidator av = getDelegatedValidator();
		if (av instanceof IValidator)return (IValidator)av;
		return super.asIValidator();
	}
	
	public V2 asV2Validator() {
		return this;
	}
	
	/**
	 * Let the validator know that a clean is about to happen.
	 * 
	 * @param project the project that is being cleaned. This can be null which means that the workspace
	 * is being cleaned (in which case a separate call will be made for each open project).
	 */
	public void clean(IProject project, IProgressMonitor monitor) {
		getDelegatedValidator().clean(project, ValOperationManager.getDefault().getOperation().getState(), monitor);
	}
	
	public Validator copy() {
		V2 v = new V2(_validator, _project);
		v.copyLocal(this);
		
		FilterGroup[] groups = getGroups();
		v._groupsArray = new FilterGroup[groups.length];
		for (int i=0; i<groups.length; i++){
			v._groupsArray[i] = groups[i].copy();
			v._groups.add(v._groupsArray[i]);
		}

		v._id = _id;
		v._name = _name;
				
		return v;
	}
	
	public int getChangeCountGroups(){
		return _changeCountGroups;
	}
	
	public void bumpChangeCountGroups(){
		_changeCountGroups++;
	}
	
	public String getDependencyId(){
		String id = getDelegatedValidator().getDependencyId();
		if (id != null)return id;
		return getId();
	}

	public Level getLevel() {
		return _level;
	}

	public void setLevel(Level level) {
		assert _level == null;
		_level = level;
	}
	
	/**
	 * Answer the actual validator that is going to perform the validation. If this is a normal validator this
	 * method will simply answer itself. However if this is a delegating validator, then this will answer the
	 * "real" validator.
	 *
	 * @return
	 */
	public AbstractValidator getDelegatedValidator(){
		AbstractValidator delegated = _delegated;
		if (delegated != null)return delegated;
		else if (getDelegatingId() == null)return _validator;
		try {
			ValidatorDelegateDescriptor vdd = ValidatorDelegatesRegistry.getInstance()
				.getDescriptor(getValidatorClassname(), getDelegatingId());
			if (vdd == null)return _validator;
			delegated = vdd.getValidator2();
		}
		catch (Exception e){
			ValidationPlugin.getPlugin().handleException(e);
		}
		if (delegated == null)return _validator;
		delegated.setParent(this);
		_delegated = delegated;
		return delegated;
	}
	
	public String getId() {
		return _id;
	}
	
	/**
	 * Answer the validator's filter groups.
	 *  
	 * @return an empty array if the validator does not have any filter groups.
	 */
	public synchronized FilterGroup[] getGroups(){
		FilterGroup[] groups = _groupsArray;
		if (groups == null){
			groups = new FilterGroup[_groups.size()];
			_groups.toArray(groups);
			_groupsArray = groups;
		}
		return groups;
	}
	
	public String getName() {
		return _name;
	}
	
	public AbstractValidator getValidator() {
		return _validator;
	}
	
	public String getValidatorClassname(){
		return getValidator().getClass().getName();
	}
	
	@Override
	public int hashCodeForConfig() {
		int h =  super.hashCodeForConfig();
		if (_id != null)h += _id.hashCode();
		if (_groups != null){
			for (FilterGroup fg : _groups)h += fg.hashCodeForConfig();
		}
		return h;
	}
	
	@Override
	public boolean isChanged() {
		if (_changeCountGroups > 0)return true;
		return super.isChanged();
	}
		
	/**
	 * Answer true if this validator, based on it's filters, should validate this resource.
	 * 
	 * @return true if the resource should be validated.
	 */
	protected boolean shouldValidate(IResource resource) {
		FilterGroup[] groups = getGroups();
		IProject project = resource.getProject();
		for (FilterGroup group : groups){
			if (!group.shouldValidate(project, resource))return false;
		}
		return true;
	}
	
	
	@Override
	public void setDelegatingId(String delegating) {
		super.setDelegatingId(delegating);
		_delegated = null;
	}
	
	public synchronized void setGroups(List<FilterGroup> groups){
		_groups = groups;
		_groupsArray = null;
		bumpChangeCountGroups();
	}

	public void setId(String id) {
		if (!Misc.same(_id, id)){
			_id = id;
			bumpChangeCountGlobal();
		}
	}
	
	public void setName(String name) {
		if (!Misc.same(_name, name)){
			_name = name;
			bumpChangeCountGlobal();
		}
	}
	
	@Override
	public ValidationResult validate(IResource resource, int kind, ValOperation operation, IProgressMonitor monitor) {
		ValidationResult vr = null;
		if (operation == null)operation = new ValOperation();
		if (monitor == null)monitor = new NullProgressMonitor();
		try {
			vr = getDelegatedValidator().validate(resource, kind, operation.getState(), monitor);
		}
		catch (Exception e){
			ValidationPlugin.getPlugin().handleException(e);
		}
		
		if (vr != null){
			if (vr.getValidationException() != null){
				ValidationPlugin.getPlugin().handleException(vr.getValidationException());
			}
			updateResults(vr);
			if (vr.getDependsOn() != null){
				ValidationFramework.getDefault().getDependencyIndex().set(getDependencyId(), resource, vr.getDependsOn());
			}
			IResource[] validated = vr.getValidated();
			if (validated != null){
				for (int i=0; i<validated.length; i++){
					operation.addValidated(getId(), validated[i]);
				}
			}
			
			ValidatorMessage[] msgs = vr.getMessages();
			if (sanityTest(msgs.length, resource)){
				MarkerManager mm = MarkerManager.getDefault();
				for (ValidatorMessage m : msgs){
					mm.createMarker(m, getId());
				}
			}
			else {
				setBuildValidation(false);
				setManualValidation(false);
			}
		}
		return vr;		
	}
	
	/**
	 * Perform a simple sanity test to ensure that the validator is configured correctly.
	 * @param numberofMessages number of messages that the validator produced.
	 * @return true if the test passed
	 */
	private boolean sanityTest(int numberofMessages, IResource resource) {
		//FIXME make this more general and configurable
		if (numberofMessages < 201)return true;
		
		String resName = ""; //$NON-NLS-1$
		if (resource != null)resName = resource.getName();
		String message = NLS.bind(ValMessages.ConfigError, new Object[]{
				getName(), getId(), String.valueOf(numberofMessages), resName});
		ValidationPlugin.getPlugin().logMessage(IStatus.ERROR, message);
		
		return false;
	}

	/**
	 * If the validator is using a report helper then update it with any of the messages that were
	 * added directly to the validation result.
	 * @param vr
	 */
	private void updateResults(ValidationResult vr) {
		ReporterHelper rh = vr.getReporterHelper();
		if (rh == null)return;
		for (IMessage message : rh.getMessages()){
			Object target = message.getTargetObject();
			if (target != null){
				if (target instanceof IResource){
					IResource res = (IResource)target;
					ValidatorMessage vm = ValidatorMessage.create(message.getText(), res);
					if (getMarkerId() != null)vm.setType(getMarkerId());
					vr.add(vm);
					int markerSeverity = IMarker.SEVERITY_INFO;
					int sev = message.getSeverity();
					if ((sev & IMessage.HIGH_SEVERITY) != 0)markerSeverity = IMarker.SEVERITY_ERROR;
					else if ((sev & IMessage.NORMAL_SEVERITY) != 0)markerSeverity = IMarker.SEVERITY_WARNING;
					vm.setAttribute(IMarker.SEVERITY, markerSeverity);
					vm.setAttribute(IMarker.LINE_NUMBER, message.getLineNumber());
					int offset = message.getOffset();
					if (offset != IMessage.OFFSET_UNSET){
						vm.setAttribute(IMarker.CHAR_START, offset);
						int len = message.getLength();
						if (len != IMessage.OFFSET_UNSET){
							vm.setAttribute(IMarker.CHAR_START, offset);
							vm.setAttribute(IMarker.CHAR_END, offset+len);
						}
					}					
				}
			}
		}		
	}

	@Override
	public void validationStarting(IProject project, ValidationState state, IProgressMonitor monitor) {
		getDelegatedValidator().validationStarting(project, state, monitor);
	}
	
	@Override
	public void validationFinishing(IProject project, ValidationState state, IProgressMonitor monitor) {
		getDelegatedValidator().validationFinishing(project, state, monitor);
	}

	public Object getAdapter(Class adapter) {
		return Platform.getAdapterManager().getAdapter(this, adapter);
	}

	public synchronized void remove(FilterGroup group) {
		_groups.remove(group);
		_groupsArray = null;	
		bumpChangeCountGroups();
	}
	
	@Override
	public void resetChangeCounters() {
		super.resetChangeCounters();
		_changeCountGroups = 0;
	}

	@Override
	protected boolean shouldValidateProject(IProject project) {
		FilterGroup[] groups = getGroups();
		for (FilterGroup group : groups){
			if (!group.shouldValidate(project, null))return false;
		}
		return true;
	}
	
	@Override
	public void become(Validator val) {
		super.become(val);
		V2 v2 = val.asV2Validator();
		if (v2 == null)throw new IllegalArgumentException(ValMessages.Error20);
		_changeCountGroups = v2._changeCountGroups;
		_delegated = v2._delegated;
		_groups = v2._groups;
		_groupsArray = v2._groupsArray;
		_id = v2._id;
		_name = v2._name;
		_validator = v2._validator;
	}
}

public String getSourceId() {
	return _sourceId;
}

public void setSourceId(String sourceId) {
	if (!Misc.same(_sourceId, sourceId)){
		_sourceId = sourceId;
		bumpChangeCountGlobal();
	}
}

/**
 * Take the instance variables from the incoming validator and set them to yourself.
 * @param validator
 */
public void become(Validator validator) {
	_buildValidation = validator._buildValidation;
	_delegatingId = validator._delegatingId;
	_manualValidation = validator._manualValidation;
	_markerId = validator._markerId;
	_messageSettings = validator._messageSettings;
	_project = validator._project;
	_sourceId = validator._sourceId;
	_version = validator._version;
	_changeCountGlobal = validator._changeCountGlobal;
	_changeCountMessages = validator._changeCountMessages;
}

void setMessages(Map<String, MessageSeveritySetting> map) {
	_messageSettings = map;
	bumpChangeCountMessages();
}

public int getChangeCountGlobal() {
	return _changeCountGlobal;
}

public int getChangeCountMessages() {
	return _changeCountMessages;
}

public void bumpChangeCountMessages(){
	_changeCountMessages++;
}

public void resetChangeCounters() {
	_changeCountGlobal = 0;
	_changeCountMessages = 0;
}

public void bumpChangeCountGlobal(){
	_changeCountGlobal++;
}

/**
 * Answer true if you have the same configuration settings as validator.
 * @param validator this can be null.
 * @return
 */
public boolean sameConfig(Validator validator) {
	if (validator == null)return false;
	return hashCodeForConfig() == validator.hashCodeForConfig();
}

public String getMarkerId() {
	return _markerId;
}

public void setMarkerId(String markerId) {
	_markerId = markerId;
	if (markerId != null)MarkerManager.getDefault().getMarkers().add(markerId);
}

}
