[130649] Tie source validation with batch validation preferences when possible
diff --git a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/SSEUIMessages.java b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/SSEUIMessages.java
index 17b69ba..b29a406 100644
--- a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/SSEUIMessages.java
+++ b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/SSEUIMessages.java
@@ -204,6 +204,7 @@
 	public static String StructuredTextEditorPreferencePage_30;
 	public static String StructuredTextEditorPreferencePage_37;
 	public static String StructuredTextEditorPreferencePage_38;
+	public static String StructuredTextEditorPreferencePage_40;
 	public static String TaskTagPreferenceTab_0;
 	public static String TaskTagPreferenceTab_1;
 	public static String TaskTagPreferenceTab_2;
diff --git a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/SSEUIPluginResources.properties b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/SSEUIPluginResources.properties
index a50fcb7..582969d 100644
--- a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/SSEUIPluginResources.properties
+++ b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/SSEUIPluginResources.properties
@@ -180,6 +180,7 @@
 StructuredTextEditorPreferencePage_37=Empty input
 StructuredTextEditorPreferencePage_38=is not a valid input.
 StructuredTextEditorPreferencePage_39=Inform when unsupported content type is in editor
+StructuredTextEditorPreferencePage_40=Also see the <a>''{0}''</a> preferences.
 TaskTagPreferenceTab_0=Low
 TaskTagPreferenceTab_1=Normal
 TaskTagPreferenceTab_2=High
diff --git a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/preferences/ui/StructuredTextEditorPreferencePage.java b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/preferences/ui/StructuredTextEditorPreferencePage.java
index 22468d0..a9e593e 100644
--- a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/preferences/ui/StructuredTextEditorPreferencePage.java
+++ b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/preferences/ui/StructuredTextEditorPreferencePage.java
@@ -43,6 +43,8 @@
 import org.eclipse.ui.IWorkbench;
 import org.eclipse.ui.IWorkbenchPreferencePage;
 import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.dialogs.PreferenceLinkArea;
+import org.eclipse.ui.preferences.IWorkbenchPreferenceContainer;
 import org.eclipse.wst.sse.ui.internal.SSEUIMessages;
 import org.eclipse.wst.sse.ui.internal.SSEUIPlugin;
 import org.eclipse.wst.sse.ui.internal.editor.IHelpContextIds;
@@ -152,6 +154,12 @@
 		label = SSEUIMessages.StructuredTextEditorPreferencePage_30; //$NON-NLS-1$
 		addCheckBox(appearanceComposite, label, CommonEditorPreferenceNames.EVALUATE_TEMPORARY_PROBLEMS, 0);
 		
+		PreferenceLinkArea contentTypeArea = new PreferenceLinkArea(appearanceComposite, SWT.NONE, "ValidationPreferencePage", SSEUIMessages.StructuredTextEditorPreferencePage_40, (IWorkbenchPreferenceContainer) getContainer(), null); //$NON-NLS-1$
+
+		GridData data = new GridData(GridData.FILL_HORIZONTAL | GridData.GRAB_HORIZONTAL);
+		data.horizontalIndent = 20;
+		contentTypeArea.getControl().setLayoutData(data);
+		
 		label = SSEUIMessages.StructuredTextEditorPreferencePage_39;
 		addCheckBox(appearanceComposite, label, EditorPreferenceNames.SHOW_UNKNOWN_CONTENT_TYPE_MSG, 0);
 
diff --git a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/reconcile/validator/ValidatorStrategy.java b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/reconcile/validator/ValidatorStrategy.java
index fb6f816..1a71aa8 100644
--- a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/reconcile/validator/ValidatorStrategy.java
+++ b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/reconcile/validator/ValidatorStrategy.java
@@ -12,6 +12,7 @@
  *******************************************************************************/
 package org.eclipse.wst.sse.ui.internal.reconcile.validator;
 
+import java.lang.reflect.InvocationTargetException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
@@ -20,6 +21,11 @@
 import java.util.List;
 import java.util.Set;
 
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
 import org.eclipse.core.runtime.Platform;
 import org.eclipse.core.runtime.content.IContentType;
 import org.eclipse.core.runtime.content.IContentTypeManager;
@@ -29,11 +35,17 @@
 import org.eclipse.jface.text.reconciler.IReconcileResult;
 import org.eclipse.jface.text.reconciler.IReconcileStep;
 import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.wst.sse.core.StructuredModelManager;
+import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
 import org.eclipse.wst.sse.ui.internal.IReleasable;
+import org.eclipse.wst.sse.ui.internal.Logger;
 import org.eclipse.wst.sse.ui.internal.reconcile.DocumentAdapter;
 import org.eclipse.wst.sse.ui.internal.reconcile.ReconcileAnnotationKey;
 import org.eclipse.wst.sse.ui.internal.reconcile.StructuredTextReconcilingStrategy;
 import org.eclipse.wst.sse.ui.internal.reconcile.TemporaryAnnotation;
+import org.eclipse.wst.validation.internal.ConfigurationManager;
+import org.eclipse.wst.validation.internal.ProjectConfiguration;
+import org.eclipse.wst.validation.internal.ValidationRegistryReader;
 import org.eclipse.wst.validation.internal.provisional.core.IValidator;
 
 
@@ -50,6 +62,7 @@
 	private List fMetaData = null;
 	/** validator id (as declared in ext point) -> ReconcileStepForValidator * */
 	private HashMap fVidToVStepMap = null;
+	private ProjectConfiguration fProjectConfiguration = null;
 
 	/*
 	 * List of ValidatorMetaDatas of total scope validators that have been run
@@ -164,29 +177,35 @@
 		for (int i = 0; i < fMetaData.size() && !isCanceled(); i++) {
 			vmd = (ValidatorMetaData) fMetaData.get(i);
 			if (vmd.canHandlePartitionType(getContentTypeIds(), partitionType)) {
-				int validatorScope = vmd.getValidatorScope();
-				ReconcileStepForValidator validatorStep = null;
-				// get step for partition type
-				Object o = fVidToVStepMap.get(vmd.getValidatorId());
-				if (o != null) {
-					validatorStep = (ReconcileStepForValidator) o;
-				}
-				else {
-					// if doesn't exist, create one
-					IValidator validator = vmd.createValidator();
+				/*
+				 * Check if validator is enabled according to validation
+				 * preferences before attempting to create/use it
+				 */
+				if (isValidatorEnabled(vmd)) {
+					int validatorScope = vmd.getValidatorScope();
+					ReconcileStepForValidator validatorStep = null;
+					// get step for partition type
+					Object o = fVidToVStepMap.get(vmd.getValidatorId());
+					if (o != null) {
+						validatorStep = (ReconcileStepForValidator) o;
+					}
+					else {
+						// if doesn't exist, create one
+						IValidator validator = vmd.createValidator();
 
-					validatorStep = new ReconcileStepForValidator(validator, validatorScope);
-					validatorStep.setInputModel(new DocumentAdapter(doc));
+						validatorStep = new ReconcileStepForValidator(validator, validatorScope);
+						validatorStep.setInputModel(new DocumentAdapter(doc));
 
-					fVidToVStepMap.put(vmd.getValidatorId(), validatorStep);
-				}
+						fVidToVStepMap.put(vmd.getValidatorId(), validatorStep);
+					}
 
-				if (!fTotalScopeValidatorsAlreadyRun.contains(vmd)) {
-					annotationsToAdd.addAll(Arrays.asList(validatorStep.reconcile(dr, dr)));
+					if (!fTotalScopeValidatorsAlreadyRun.contains(vmd)) {
+						annotationsToAdd.addAll(Arrays.asList(validatorStep.reconcile(dr, dr)));
 
-					if (validatorScope == ReconcileAnnotationKey.TOTAL) {
-						// mark this validator as "run"
-						fTotalScopeValidatorsAlreadyRun.add(vmd);
+						if (validatorScope == ReconcileAnnotationKey.TOTAL) {
+							// mark this validator as "run"
+							fTotalScopeValidatorsAlreadyRun.add(vmd);
+						}
 					}
 				}
 			}
@@ -224,4 +243,75 @@
 			step.setInputModel(new DocumentAdapter(document));
 		}
 	}
+
+	/**
+	 * Checks if validator is enabled according to Validation preferences
+	 * 
+	 * @param vmd
+	 * @return
+	 */
+	private boolean isValidatorEnabled(ValidatorMetaData vmd) {
+		boolean enabled = false;
+		ProjectConfiguration configuration = getProjectConfiguration();
+		org.eclipse.wst.validation.internal.ValidatorMetaData metadata = ValidationRegistryReader.getReader().getValidatorMetaData(vmd.getValidatorClass());
+		if (configuration != null && metadata != null) {
+			if (configuration.isBuildEnabled(metadata) || configuration.isManualEnabled(metadata))
+				enabled = true;
+		}
+		return enabled;
+	}
+
+	/**
+	 * Gets current validation project configuration based on current project
+	 * (which is based on current document)
+	 * 
+	 * @return ProjectConfiguration
+	 */
+	private ProjectConfiguration getProjectConfiguration() {
+		if (fProjectConfiguration == null) {
+			IFile file = getFile();
+			if (file != null) {
+				IProject project = file.getProject();
+				if (project != null) {
+					try {
+						fProjectConfiguration = ConfigurationManager.getManager().getProjectConfiguration(project);
+					}
+					catch (InvocationTargetException e) {
+						Logger.log(Logger.WARNING_DEBUG, e.getMessage(), e);
+					}
+				}
+			}
+		}
+
+		return fProjectConfiguration;
+	}
+
+	/**
+	 * Gets IFile from current document
+	 * 
+	 * @return IFile
+	 */
+	private IFile getFile() {
+		IStructuredModel model = null;
+		IFile file = null;
+		try {
+			model = StructuredModelManager.getModelManager().getExistingModelForRead(getDocument());
+			if (model != null) {
+				String baseLocation = model.getBaseLocation();
+				// The baseLocation may be a path on disk or relative to the
+				// workspace root. Don't translate on-disk paths to
+				// in-workspace resources.
+				IPath basePath = new Path(baseLocation);
+				if (basePath.segmentCount() > 1 && !basePath.toFile().exists()) {
+					file = ResourcesPlugin.getWorkspace().getRoot().getFile(basePath);
+				}
+			}
+		}
+		finally {
+			if (model != null) {
+				model.releaseFromRead();
+			}
+		}
+		return file;
+	}
 }
diff --git a/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/validation/DelegatingSourceValidator.java b/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/validation/DelegatingSourceValidator.java
index 6dc6364..b169542 100644
--- a/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/validation/DelegatingSourceValidator.java
+++ b/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/validation/DelegatingSourceValidator.java
@@ -112,10 +112,10 @@
 		}
 
 		public IProject getProject() {
-      if (file != null) {        
-        return file.getProject();
-      }
-      return null;
+			if (file != null) {
+				return file.getProject();
+			}
+			return null;
 		}
 	}
 
@@ -185,23 +185,23 @@
 				// any threading problems
 				byte[] byteArray = xmlModel.getStructuredDocument().get().getBytes();
 
-				IValidator validator = getDelegateValidator();
-				if (validator != null) {
-					// Validate the file:
-					IValidationContext vHelper = new MyHelper(new ByteArrayInputStream(byteArray), file);
-					MyReporter vReporter = new MyReporter();
-					if(validator instanceof IValidatorJob)
-					{
-					  ((IValidatorJob)validator).validateInJob(vHelper, vReporter);
-					}
-					else
-					{
-					  validator.validate(vHelper, vReporter);
-					}
-					List messages = vReporter.list;
+				if (isDelegateValidatorEnabled(file)) {
+					IValidator validator = getDelegateValidator();
+					if (validator != null) {
+						// Validate the file:
+						IValidationContext vHelper = new MyHelper(new ByteArrayInputStream(byteArray), file);
+						MyReporter vReporter = new MyReporter();
+						if (validator instanceof IValidatorJob) {
+							((IValidatorJob) validator).validateInJob(vHelper, vReporter);
+						}
+						else {
+							validator.validate(vHelper, vReporter);
+						}
+						List messages = vReporter.list;
 
-					// set the offset and length
-					updateValidationMessages(messages, document, reporter);
+						// set the offset and length
+						updateValidationMessages(messages, document, reporter);
+					}
 				}
 			}
 
@@ -498,9 +498,22 @@
 			}
 			return startEndPositions;
 		}
-//		catch (Exception e) { // e.printStackTrace();
-//		}
-		finally {}
-//		return null;
+		// catch (Exception e) { // e.printStackTrace();
+		// }
+		finally {
+		}
+		// return null;
+	}
+
+	/**
+	 * Returns true if delegate validator is enabled based on Validation
+	 * preferences
+	 * 
+	 * @param file
+	 * @return false if delegate validator is not enabled based on Validatoin
+	 *         preferences, true otherwise
+	 */
+	protected boolean isDelegateValidatorEnabled(IFile file) {
+		return true;
 	}
 }
diff --git a/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/validation/DelegatingSourceValidatorForXML.java b/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/validation/DelegatingSourceValidatorForXML.java
index 7c1b16a..cde9107 100644
--- a/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/validation/DelegatingSourceValidatorForXML.java
+++ b/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/validation/DelegatingSourceValidatorForXML.java
@@ -11,6 +11,13 @@
 
 package org.eclipse.wst.xml.ui.internal.validation;
 
+import java.lang.reflect.InvocationTargetException;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.wst.validation.internal.ConfigurationManager;
+import org.eclipse.wst.validation.internal.ProjectConfiguration;
+import org.eclipse.wst.validation.internal.ValidationRegistryReader;
+import org.eclipse.wst.validation.internal.ValidatorMetaData;
 import org.eclipse.wst.validation.internal.provisional.ValidationFactory;
 import org.eclipse.wst.validation.internal.provisional.core.IValidator;
 import org.eclipse.wst.xml.ui.internal.Logger;
@@ -36,4 +43,20 @@
 		}
 		return result;
 	}
+
+	protected boolean isDelegateValidatorEnabled(IFile file) {
+		boolean enabled = true;
+		try {
+			ProjectConfiguration configuration = ConfigurationManager.getManager().getProjectConfiguration(file.getProject());
+			ValidatorMetaData vmd = ValidationRegistryReader.getReader().getValidatorMetaData(VALIDATOR_CLASS);
+			if (configuration.isBuildEnabled(vmd) || configuration.isManualEnabled(vmd))
+				enabled = true;
+			else
+				enabled = false;
+		}
+		catch (InvocationTargetException e) {
+			Logger.log(Logger.WARNING_DEBUG, e.getMessage(), e);
+		}
+		return enabled;
+	}
 }
diff --git a/bundles/org.eclipse.wst.xsd.ui/src-adt-xsd/org/eclipse/wst/xsd/ui/internal/validation/DelegatingSourceValidatorForXSD.java b/bundles/org.eclipse.wst.xsd.ui/src-adt-xsd/org/eclipse/wst/xsd/ui/internal/validation/DelegatingSourceValidatorForXSD.java
index d84ba1a..accfdc9 100644
--- a/bundles/org.eclipse.wst.xsd.ui/src-adt-xsd/org/eclipse/wst/xsd/ui/internal/validation/DelegatingSourceValidatorForXSD.java
+++ b/bundles/org.eclipse.wst.xsd.ui/src-adt-xsd/org/eclipse/wst/xsd/ui/internal/validation/DelegatingSourceValidatorForXSD.java
@@ -10,8 +10,16 @@
  *******************************************************************************/
 package org.eclipse.wst.xsd.ui.internal.validation;
 
+import java.lang.reflect.InvocationTargetException;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.wst.validation.internal.ConfigurationManager;
+import org.eclipse.wst.validation.internal.ProjectConfiguration;
+import org.eclipse.wst.validation.internal.ValidationRegistryReader;
+import org.eclipse.wst.validation.internal.ValidatorMetaData;
 import org.eclipse.wst.validation.internal.provisional.ValidationFactory;
 import org.eclipse.wst.validation.internal.provisional.core.IValidator;
+import org.eclipse.wst.xml.ui.internal.Logger;
 import org.eclipse.wst.xml.ui.internal.validation.DelegatingSourceValidator;
 
 /**
@@ -37,4 +45,20 @@
     }
     return null;
   }
+  
+	protected boolean isDelegateValidatorEnabled(IFile file) {
+		boolean enabled = true;
+		try {
+			ProjectConfiguration configuration = ConfigurationManager.getManager().getProjectConfiguration(file.getProject());
+			ValidatorMetaData vmd = ValidationRegistryReader.getReader().getValidatorMetaData(VALIDATOR_CLASS);
+			if (configuration.isBuildEnabled(vmd) || configuration.isManualEnabled(vmd))
+				enabled = true;
+			else
+				enabled = false;
+		}
+		catch (InvocationTargetException e) {
+			Logger.log(Logger.WARNING_DEBUG, e.getMessage(), e);
+		}
+		return enabled;
+	}
 }