/*******************************************************************************
 * Copyright (c) 2007, 2010 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.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;

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.IConfigurationElement;
import org.eclipse.core.runtime.IContributor;
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.ConfigurationConstants;
import org.eclipse.wst.validation.internal.ConfigurationManager;
import org.eclipse.wst.validation.internal.ContentTypeWrapper;
import org.eclipse.wst.validation.internal.ExtensionConstants;
import org.eclipse.wst.validation.internal.MarkerManager;
import org.eclipse.wst.validation.internal.Misc;
import org.eclipse.wst.validation.internal.NullValidator;
import org.eclipse.wst.validation.internal.SummaryReporter;
import org.eclipse.wst.validation.internal.Tracing;
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.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;
import org.eclipse.wst.validation.internal.provisional.core.IValidatorExtender;

/**
 * Represents a validator. This gets instantiated through one of the validator extension points.
 * <p>
 * <b>This class is not API</b>.
 * </p>
 * 
 * @author karasiuk
 *
 */
public abstract class Validator implements Comparable<Validator> {
	// 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;
	
	/** Has the validator been migrated from an earlier version in this session, but not yet saved? */
	private boolean _migrated;
	
	public Validator(IProject project){
		_project = project;
	}
		
	void setMigrated(boolean migrated){
		_migrated = migrated;
	}
	
	/**
	 * 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(IConfigurationElement validator, IProject project) {
		V2 v2 = new V2(validator, project);
		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, 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, ValOperation operation, IProgressMonitor monitor){
	}	
	
	/**
	 * Compare yourself based on Validator name.
	 */
	public int compareTo(Validator validator) {
		return getName().compareTo(validator.getName());			
	}
	
	/** Answer a deep copy of yourself. */
	public Validator copy(){
		return copy(false);
	}
	
	public abstract Validator copy(boolean includeChangeCounts);
	
	/**
	 * Update your direct, non transient fields from the fields in v.
	 */
	protected void copyLocal(Validator v, boolean includeChangeCounts){
		_buildValidation = v._buildValidation;
		_delegatingId = v._delegatingId;
		_manualValidation = v._manualValidation;
		_markerId = v._markerId;
		_messageSettings = v._messageSettings;
		_sourceId = v._sourceId;
		_version = v._version;
		_migrated = v._migrated;
		
		if (includeChangeCounts){
			_changeCountGlobal = v._changeCountGlobal;
			_changeCountMessages = v._changeCountMessages;
		}
	}
	
	/**
	 * Should the validation framework first clear the markers that this
	 * validator has placed on this resource? This method can be overridden by
	 * validator implementors to provide a validator specific behavior.
	 * 
	 * @param event
	 *            The validation event that triggered the validation.
	 * @return true if the validation framework should first clear all the
	 *         markers that this validator produced. This is the default
	 *         behavior. Return false to leave the markers unchanged. It then
	 *         becomes the responsibility of the validator to manage it's own
	 *         markers for this resource, for this validation event.
	 */
	public boolean shouldClearMarkers(ValidationEvent event){
		return true;
	}
	
	/**
	 * 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){
		return shouldValidate(resource, isManual, isBuild, new ContentTypeWrapper());
	}
	
	/**
	 * 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.
	 * @param contentTypeWrapper 
	 *            For repeated calls on the same resource, it is more efficient
	 *            to remember the content type.
	 * @return true if the resource should be validated.
	 * @see Friend#shouldValidate(Validator, IResource, boolean, boolean, ContentTypeWrapper)
	 */
	boolean shouldValidate(IResource resource, boolean isManual, boolean isBuild, 
		ContentTypeWrapper contentTypeWrapper){
		
		if (isManual && !_manualValidation)return false;
		if (isBuild && !_buildValidation)return false;
		
		return shouldValidate(resource, contentTypeWrapper);
	}
	
	/**
	 * 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 context to use when performing the check.
	 * 
	 * @return true if the resource should be validated.
	 */
	public boolean shouldValidate(IResource resource, ValType valType){
		return shouldValidate(resource, valType, new ContentTypeWrapper());
	}
	
	/**
	 * 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 context to use when performing the check.
	 * @param contentTypeWrapper
	 *            For repeated calls on the same resource, it is more efficient
	 *            to remember the content type.
	 * 
	 * @return true if the resource should be validated.
	 * 
	 * @see Friend#shouldValidate(Validator, IResource, ValType, ContentTypeWrapper)
	 */
	boolean shouldValidate(IResource resource, ValType valType, ContentTypeWrapper contentTypeWrapper){
		if (Tracing.matchesExtraDetail(getId())){
			Tracing.log("Validator-01: checking if " + getId() + " should validate " + resource); //$NON-NLS-1$ //$NON-NLS-2$
		}
		if (valType == ValType.Manual && !_manualValidation)return false;
		if (valType == ValType.Build && !_buildValidation)return false;
		
		boolean result = shouldValidate(resource, contentTypeWrapper);
		if (Tracing.matchesExtraDetail(getId())){
			Tracing.log("Validator-02: result = " + result); //$NON-NLS-1$
		}
		
		return result;
	}
	
	/**
	 * 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 type The type of validation request
	 * 
	 * @return true if the project should be validated.
	 */
	public boolean shouldValidateProject(IProject project, ValType type){
		return shouldValidateProject(project, type == ValType.Manual, type == ValType.Build);
	}
	
	/**
	 * 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 (Tracing.matchesExtraDetail(getId())){
			Tracing.log("Validator-03: checking if " + getId() + " should validate " + project); //$NON-NLS-1$ //$NON-NLS-2$
		}
		if (isManual && !_manualValidation)return false;
		if (isBuild && !_buildValidation)return false;
		if (project == null || !project.isOpen())return false;
		boolean result = shouldValidateProject(project);
		if (Tracing.matchesExtraDetail(getId())){
			Tracing.log("Validator-04: result " + result); //$NON-NLS-1$
		}
		return result;
	}
	
	/**
	 * 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);
	
	/**
	 * 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.
	 * @param event
	 *            An event that describes in more detail what should be
	 *            validated and why it should be validated. This can be null.
	 * 
	 * @return the result of doing the validation, it can be, but usually isn't
	 *         null.
	 */
	public ValidationResult validate(IResource resource, int kind, ValOperation operation, IProgressMonitor monitor, ValidationEvent event){
		// The reason that the resource and kind are still specified, is that I didn't want to remove a public method in the service
		// stream. 
		return validate(resource, kind, operation, 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, ContentTypeWrapper contentTypeWrapper);
	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.
	 */
	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
	 * @return true if the setting changed.
	 */
	public boolean setManualValidation(boolean manualValidation) {
		return setManualValidation2(manualValidation);
	}
	
	protected final boolean setManualValidation2(boolean manualValidation) {
		boolean changed = false;
		if (_manualValidation != manualValidation){
			bumpChangeCountGlobal();
			changed = true;
			_manualValidation = manualValidation;
		}
		return changed;
	}

	/**
	 * 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? Or was it migrated from an earlier version. 
	 */
	public boolean isChanged(){
		if (_changeCountGlobal > 0 || _changeCountMessages > 0 || _migrated)return true;
		return false;
	}
	
	/**
	 * Has the validator's implementation been loaded yet? This is used by some test cases to ensure that 
	 * plug-ins are not loaded too early.
	 */
	abstract boolean isLoaded();
	

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

	/**
	 * 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;
	}
	
	/**
	 * 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, IProject project){
		super(project);
		_vmd = vmd;
		if (config != null){
			setBuildValidation(config.isBuildEnabled(vmd));
			setManualValidation(config.isManualEnabled(vmd));
		}
		setDelegatingId(ValidatorDelegatesRegistry.getInstance().getDefaultDelegate(_vmd.getValidatorUniqueName()));
		if (_vmd.getMarkerIds() != null && _vmd.getMarkerIds().length > 0)setMarkerId(_vmd.getMarkerIds()[0]);
		resetChangeCounters();
	}
	
	@Override
	public void validationFinishing(IProject project, ValidationState state, IProgressMonitor monitor) {
		if (project != null) {
			IValidator v = asIValidator();
			if (v instanceof IValidatorExtender) {
				IValidatorExtender vExt = (IValidatorExtender) v;
				vExt.validationFinishing(project, state, monitor);
			}	
		}
	}

	@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;
	}
			
	public Validator copy(boolean includeChangeCounts) {
		V1 v = new V1Copy(_vmd, null, _project);
		v.copyLocal(this, includeChangeCounts);
				
		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
	boolean isLoaded() {
		return _vmd.isActive();
	}
	
	@Override
	public boolean setBuildValidation(boolean buildValidation) {
		boolean changed = super.setBuildValidation(buildValidation);
		_vmd.setBuildValidation(buildValidation);
		return changed;
	}
	
	@Override
	public boolean setManualValidation(boolean manualValidation) {
		boolean changed = super.setManualValidation(manualValidation);
		_vmd.setManualValidation(manualValidation);
		return changed;
	}

	@Override
	protected boolean shouldValidate(IResource resource, ContentTypeWrapper contentTypeWrapper) {
		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;
		
		if (shouldSkipValidator(resource, operation))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);
			}
			try {
				ValidatorLauncher.getLauncher().start(helper, v, reporter);
			}
			finally {
				try {
					v.cleanup(reporter);
				}
				finally {
					helper.cleanup(reporter);
				}
			}
			
			vr.incrementError(reporter.getSeverityHigh());
			vr.incrementWarning(reporter.getSeverityNormal());
			vr.incrementInfo(reporter.getSeverityLow());
			
		}
		catch (Exception e){
			ValidationPlugin.getPlugin().handleException(e);
		}
		return vr;
	}
	

	private static final String VALIDATE_PROJECT_ONCE = "ValidateProjectOnce"; //$NON-NLS-1$

		@SuppressWarnings("unchecked")	
		private boolean shouldSkipValidator(IResource resource, ValOperation operation) {

			if (_vmd.isValidateByProject())
			{
				ValidationState validationState = operation.getState();
				Set<String> projectsNameSet = (Set<String>)validationState.get(VALIDATE_PROJECT_ONCE);
				String projectName = resource.getProject().getName();

				if (projectsNameSet == null) {
					projectsNameSet = new HashSet<String>();
					validationState.put(VALIDATE_PROJECT_ONCE, projectsNameSet);
				}

				if (projectsNameSet.contains(projectName))return true;
				else projectsNameSet.add(projectName);
			}
			return false;
		}

	/*
	 * 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 final static class V1Copy extends V1 {
		public V1Copy(ValidatorMetaData vmd, ValidationConfiguration vc, IProject project){
			super(vmd, vc, project);
		}
		
		@Override
		public boolean setManualValidation(boolean bool) {
			return setManualValidation2(bool);
		}
		
		@Override
		public boolean setBuildValidation(boolean bool) {
			return setBuildValidation2(bool);
		}
				
	}
		
}

/**
 * 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;
	
	/** 
	 * We don't want to create the validator too early, as it may trigger new plug-ins to be loaded.
	 * We delay that as long as possible, by starting with just the config element.
	 */
	private IConfigurationElement _validatorConfigElement;
	
	private String	_validatorClassName;
	
	/**
	 * An array containing the validator group IDs for which this validator is a member.
	 */
	private String[] _validatorGroupIds;
		
	/** 
	 * 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;
	
	/**
	 * Do we still need to invoke the validateStarting method for this validator, for the null project?
	 * 
	 * Because we do not want to activate a validator's plug-in too soon, we do not activate the validator
	 * as a reaction to the global validation starting event. Instead we mark it pending, and wait until
	 * we are sure that we have something to validate.
	 * 
	 * If this flag is true, it means that the validateStarting method still needs to be called for this validator.
	 */
	private AtomicBoolean _pendingValidationStarted = new AtomicBoolean();
	
	V2(IConfigurationElement configElement, IProject project){
		super(project);
		assert configElement != null;
		_validatorConfigElement = configElement;
		_validatorClassName = configElement.getAttribute(ExtensionConstants.AttribClass);

		IConfigurationElement[] groupReferenceElements = configElement.getChildren(ExtensionConstants.Group.elementGroup);
		List<String> validatorGroupIDs = new ArrayList<String>();
		for (IConfigurationElement groupElement : groupReferenceElements) {
			String id = groupElement.getAttribute(ExtensionConstants.Group.attId);
			if (id != null)validatorGroupIDs.add(id);
		}
		_validatorGroupIds = validatorGroupIDs.toArray(new String[validatorGroupIDs.size()]);
			
		init();
	}
	
	private V2(IProject project, String validatorClassName, AbstractValidator validator){
		super(project);
		assert validator != null;
		
		_validatorClassName = validatorClassName;
		_validator = validator;
		init();
	}
	
	private void init(){
		try {
			String id = ConfigurationManager.getManager().getConfiguration(_project).getDelegateForTarget(_validatorClassName);
			if (id == null) id = ValidatorDelegatesRegistry.getInstance().getDefaultDelegate(_validatorClassName);
			setDelegatingId(id);
		}
		catch (InvocationTargetException e){
			ValidationPlugin.getPlugin().handleException(e);
		}
		resetChangeCounters();		
	}

	public synchronized void add(FilterGroup fg) {
		assert fg != null;
		_groupsArray = null;
		_groups.add(fg);
		bumpChangeCountGroups();
	}
	
	@Override
	public IValidator asIValidator() {
		AbstractValidator av = getDelegatedValidator();
		if (av instanceof IValidator)return (IValidator)av;
		return super.asIValidator();
	}
	
	@Override
	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).
	 * 
	 */
	@Override
	public void clean(IProject project, ValOperation operation, IProgressMonitor monitor) {
		getDelegatedValidator().clean(project, operation.getState(), monitor);
	}
	
	@Override
	public Validator copy(boolean includeChangeCounts) {
		V2 v = null;
		if (_validatorConfigElement != null)v = new V2(_validatorConfigElement, _project);
		else v = new V2(_project, _validatorClassName, _validator);
		v.copyLocal(this, includeChangeCounts);
		
		if (includeChangeCounts)v._changeCountGroups = _changeCountGroups;
		
		FilterGroup[] groups = getGroups();
		v._groupsArray = new FilterGroup[groups.length];
		for (int i=0; i<groups.length; i++){
			v._groupsArray[i] = groups[i];
			v._groups.add(groups[i]);
		}

		v._id = _id;
		v._name = _name;
		v._validatorGroupIds = _validatorGroupIds;
		v._pendingValidationStarted = _pendingValidationStarted;
				
		return v;
	}
	
	public int getChangeCountGroups(){
		return _changeCountGroups;
	}
	
	public void bumpChangeCountGroups(){
		_changeCountGroups++;
	}
	
	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.
	 */
	public AbstractValidator getDelegatedValidator(){
		AbstractValidator delegated = _delegated;
		if (delegated != null)return delegated;
		else if (getDelegatingId() == null)return getValidator();
		try {
			ValidatorDelegateDescriptor vdd = ValidatorDelegatesRegistry.getInstance()
				.getDescriptor(getValidatorClassname(), getDelegatingId());
			if (vdd == null)return getValidator();
			delegated = vdd.getValidator2();
		}
		catch (Exception e){
			ValidationPlugin.getPlugin().handleException(e);
			delegated = new NullValidator();
		}
		delegated.setParent(this);
		_delegated = delegated;
		return delegated;
	}
		
	@Override
	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;
	}
	
	@Override
	public String getName() {
		return _name;
	}
	
	public AbstractValidator getValidator() {
		if (_validator == null){
			try {
				_validator = (AbstractValidator)_validatorConfigElement.createExecutableExtension(ExtensionConstants.AttribClass);
			}
			catch (Exception e){
				ValidationPlugin.getPlugin().handleException(e);
				IContributor contrib = _validatorConfigElement.getContributor();
				String message = NLS.bind(ValMessages.ErrConfig, contrib.getName());
				ValidationPlugin.getPlugin().logMessage(IStatus.ERROR, message);
				_validator = new NullValidator();
			}
			_validator.setParent(this);
			_validatorConfigElement = null;

		}
		return _validator;
	}
	
	@Override
	public String getValidatorClassname(){
		return _validatorClassName;
	}
	
	public String[] getValidatorGroups(){
		return _validatorGroupIds;
	}
	
	@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();
	}
	
	@Override
	boolean isLoaded() {
		return _validator != null;
	}
	
	@Override
	public boolean shouldClearMarkers(ValidationEvent event) {
		return getValidator().shouldClearMarkers(event);
	}
		
	/**
	 * Answer true if this validator, based on it's filters, should validate this resource.
	 * 
	 * @return true if the resource should be validated.
	 */
	@Override
	protected boolean shouldValidate(IResource resource, ContentTypeWrapper contentTypeWrapper) {
	    if (resource.isDerived()){
	      return false;
	    }
		FilterGroup[] groups = getGroups();
		IProject project = resource.getProject();
		for (FilterGroup group : groups){
			if (!group.shouldValidate(project, resource, contentTypeWrapper))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){
		return validate(resource, kind, operation, monitor, null);
	}
	
	@Override
	public ValidationResult validate(IResource resource, int kind, ValOperation operation, IProgressMonitor monitor, ValidationEvent event) {
		ValidationResult vr = null;
		if (operation == null)operation = new ValOperation();
		if (monitor == null)monitor = new NullProgressMonitor();
		try {
			if (event == null)event = new ValidationEvent(resource, kind, null);
			vr = getDelegatedValidator().validate(event, operation.getState(), monitor);
			if (vr == null)vr = getDelegatedValidator().validate(resource, kind, operation.getState(), monitor);
		}
		catch (Exception e){
			try {
				String msg = NLS.bind(ValMessages.LogValEnd, getName(), resource.getLocationURI());
				ValidationPlugin.getPlugin().logMessage(IStatus.ERROR, msg);
			}
			catch (Exception e2 ){
				// ignore it
			}
			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(getId(), 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) {
//		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;
		ClassLoader classloader = getDelegatedValidator().getClass().getClassLoader();
		for (IMessage message : rh.getMessages()){
			Object target = message.getTargetObject();
			if (target != null){
				IResource res = null;
				if (target instanceof IResource)res = (IResource)target;
				if (res == null){
					target = message.getAttribute(IMessage.TargetResource);
					if (target != null && target instanceof IResource)res = (IResource)target;
				}
				if (res != null){
					
					ValidatorMessage vm = ValidatorMessage.create(message.getText(classloader), 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);
						}
					}
					String groupName = message.getGroupName();
					if (groupName != null){
						vm.setAttribute(ConfigurationConstants.VALIDATION_MARKER_GROUP, groupName);
					}
					
					copyAttributes(message, vm);
				}
			}
		}		
	}

	@SuppressWarnings("unchecked")
	private void copyAttributes(IMessage message, ValidatorMessage vm) {
		// I made this a separate method, so that I could localize the suppression of unchecked warnings.
		Map attributes = message.getAttributes();
		if (attributes != null){						
			for (Iterator it = attributes.entrySet().iterator(); it.hasNext();){
				Map.Entry me = (Map.Entry)it.next();
				String key = (String)me.getKey();
				vm.setAttribute(key, me.getValue());
			}
		}
	}
	
	@Override
	public void validationStarting(IProject project, ValidationState state, IProgressMonitor monitor) {
		if (project == null)_pendingValidationStarted.set(true);
		else {
			AbstractValidator val = getDelegatedValidator();
			if (_pendingValidationStarted.getAndSet(false)){
				val.validationStarting(null, state, monitor);
			}
			val.validationStarting(project, state, monitor);
		}
	}
	
	@Override
	public void validationFinishing(IProject project, ValidationState state, IProgressMonitor monitor) {
		if (project == null){
			if (!_pendingValidationStarted.getAndSet(false))getDelegatedValidator().validationFinishing(null, state, monitor);
		}
		else getDelegatedValidator().validationFinishing(project, state, monitor);
	}

	@SuppressWarnings("unchecked")
	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();
		ContentTypeWrapper ctw = new ContentTypeWrapper();
		for (FilterGroup group : groups){
			if (!group.shouldValidate(project, null, ctw))return false;
		}
		return true;
	}
	
	public synchronized void replaceFilterGroup(FilterGroup existing, FilterGroup merged) {
		remove(existing);
		add(merged);
	}

}

public String getSourceId() {
	return _sourceId;
}

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


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

public int getChangeCountGlobal() {
	return _changeCountGlobal;
}

public boolean hasGlobalChanges(){
	return _migrated || _changeCountGlobal > 0;
}

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.
 */
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);
}

}
