[313384] Validation Framework invokes the V1 validators too often
diff --git a/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/RegistryConstants.java b/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/RegistryConstants.java
index 81a78b4..140240a 100644
--- a/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/RegistryConstants.java
+++ b/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/RegistryConstants.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2001, 2007 IBM Corporation and others.
+ * Copyright (c) 2001, 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
@@ -54,6 +54,9 @@
* only one validator may use an aggregate of that type. */
String TAG_AGGREGATE_VALIDATORS = "aggregateValidator"; //$NON-NLS-1$
+ /** runStrategy - identifies the run strategy of Validator*/
+ String TAG_RUN_STRATEGY = "runStrategy"; //$NON-NLS-1$
+
/** objectClass - identifies a type */
String ATT_OBJECT_CLASS = "objectClass"; //$NON-NLS-1$
@@ -119,6 +122,16 @@
/** false - The "can validator run asynchronously" default. In the future this may be changed to true. */
boolean ATT_ASYNC_DEFAULT = false;
+ /**
+ * project - identifies whether or not the validator is called per project.
+ * Default is false (i.e. the validator is called per resource).
+ */
+ String ATT_PROJECT = "project"; //$NON-NLS-1$
+
+ /** false - The project default. */
+ boolean ATT_PROJECT_DEFAULT = false;
+
+
/** migrate - the "migrate" section of the validator */
String TAG_MIGRATE = "migrate"; //$NON-NLS-1$
diff --git a/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/ValidationRegistryReader.java b/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/ValidationRegistryReader.java
index 9766048..7a4d5f1 100644
--- a/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/ValidationRegistryReader.java
+++ b/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/ValidationRegistryReader.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2001, 2009 IBM Corporation and others.
+ * Copyright (c) 2001, 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
@@ -1221,7 +1221,7 @@
getIncremental(element), getFullBuild(element), element, helperImplName, getMigrationMetaData(element),
pluginId, getRuleGroup(element), runChildren[0], validatorName.intern(), validatorImplName.intern(),
getContentTypeBindings(element), getDependentValidatorValue(element), getEnablementElement(element),
- getFacetIds(element), getFilters(element), getProjectNatureFilters(element), markerIds);
+ getFacetIds(element), getFilters(element), getProjectNatureFilters(element), markerIds, getRunStragety(element));
if (Tracing.isTraceV1()) {
@@ -1349,5 +1349,22 @@
return vmd.getValidator();
return null;
}
+ /**
+ * Given an IConfigurationElement from plugin.xml, return whether or not the validator is called by project
+ *
+ * <p>If no project attribute is specified, the default is false (validator is called by resource)
+ */
+ private boolean getRunStragety(IConfigurationElement element) {
+
+ IConfigurationElement[] runChildren = element.getChildren(TAG_RUN_STRATEGY);
+
+ if (runChildren == null || runChildren.length < 1) return RegistryConstants.ATT_PROJECT_DEFAULT;
+ String project = runChildren[0].getAttribute(ATT_PROJECT);
+ if (project == null)return RegistryConstants.ATT_PROJECT_DEFAULT;
+
+ return Boolean.valueOf(project.trim());
+
+ }
+
}
diff --git a/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/ValidatorMetaData.java b/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/ValidatorMetaData.java
index 6b26bf6..4fef8a4 100644
--- a/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/ValidatorMetaData.java
+++ b/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/ValidatorMetaData.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2001, 2008 IBM Corporation and others.
+ * Copyright (c) 2001, 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
@@ -78,13 +78,14 @@
private final Map<IValidatorJob, IWorkbenchContext> _helpers =
Collections.synchronizedMap( new HashMap<IValidatorJob, IWorkbenchContext>() );
private final Expression _enablementExpression;
+ private boolean _validateByProject = true;
ValidatorMetaData(boolean async, String[] aggregatedValidators, boolean isEnabledByDefault, boolean supportsIncremental,
boolean supportsFullBuild, IConfigurationElement helperClassElement, String helperClassName,
MigrationMetaData migrationMetaData, String pluginId, int ruleGroup, IConfigurationElement validatorClassElement,
String validatorDisplayName, String validatorUniqueName, String[] contentTypeIds, boolean dependentValidator,
Expression enablementExpression, String[] facetFilters, ValidatorFilter[] filters,
- ValidatorNameFilter[] projectNatureFilters, String[] markerIds) {
+ ValidatorNameFilter[] projectNatureFilters, String[] markerIds, boolean validateByProject) {
_async = async;
_aggregatedValidators = aggregatedValidators;
_isEnabledByDefault = isEnabledByDefault;
@@ -106,6 +107,7 @@
_projectNatureFilters = projectNatureFilters;
_markerIds = markerIds;
_validatorNames = buildValidatorNames();
+ _validateByProject = validateByProject;
}
protected String[] getFacetFilters() {
@@ -544,5 +546,9 @@
}
return false;
}
+
+public boolean isValidateByProject() {
+ return _validateByProject;
+}
}
diff --git a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/Validator.java b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/Validator.java
index 7a9da1c..88f5ec5 100644
--- a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/Validator.java
+++ b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/Validator.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2009 IBM Corporation and others.
+ * 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
@@ -13,10 +13,12 @@
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;
@@ -748,6 +750,8 @@
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);
@@ -783,6 +787,29 @@
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
diff --git a/plugins/org.eclipse.wst.validation/xsds/validatorExtSchema.exsd b/plugins/org.eclipse.wst.validation/xsds/validatorExtSchema.exsd
index 25d2602..0e9667e 100644
--- a/plugins/org.eclipse.wst.validation/xsds/validatorExtSchema.exsd
+++ b/plugins/org.eclipse.wst.validation/xsds/validatorExtSchema.exsd
@@ -1,6 +1,6 @@
<?xml version='1.0' encoding='UTF-8'?>
<!-- Schema file written by PDE -->
-<schema targetNamespace="org.eclipse.wst.validation">
+<schema targetNamespace="org.eclipse.wst.validation" xmlns="http://www.w3.org/2001/XMLSchema">
<annotation>
<appInfo>
<meta.schema plugin="org.eclipse.wst.validation" id="validator" name="Validator"/>
@@ -13,6 +13,11 @@
<include schemaLocation="schema://org.eclipse.core.expressions/schema/expressionLanguage.exsd"/>
<element name="extension">
+ <annotation>
+ <appInfo>
+ <meta.element />
+ </appInfo>
+ </annotation>
<complexType>
<sequence>
<element ref="validator"/>
@@ -49,13 +54,14 @@
<sequence>
<element ref="projectNature" minOccurs="0" maxOccurs="unbounded"/>
<element ref="filter" minOccurs="0" maxOccurs="unbounded"/>
- <element ref="enablement" minOccurs="0" maxOccurs="unbounded"/>/>
+ <element ref="enablement" minOccurs="0" maxOccurs="unbounded"/>
<element ref="helper"/>
<element ref="dependentValidator" minOccurs="0" maxOccurs="1"/>
<element ref="run"/>
<element ref="markerId" minOccurs="0" maxOccurs="1"/>
<element ref="facet" minOccurs="0" maxOccurs="unbounded"/>
<element ref="contentTypeBinding" minOccurs="0" maxOccurs="unbounded"/>
+ <element ref="runStrategy"/>
</sequence>
<attribute name="to" type="string">
<annotation>
@@ -94,15 +100,14 @@
</attribute>
</complexType>
</element>
-
-
+
<element name="contentTypeBinding">
<annotation>
<appInfo>
<meta.element labelAttribute="contentTypeId"/>
</appInfo>
<documentation>
- Associates a particular content type with the current validator, and enables the validator to be run on resources of the specified content type.
+ Associates a particular content type with the current validator, and enables the validator to be run on resources of the specified content type.
</documentation>
</annotation>
<complexType>
@@ -115,9 +120,6 @@
</attribute>
</complexType>
</element>
-
-
-
<element name="filter">
<complexType>
@@ -284,6 +286,19 @@
</complexType>
</element>
+ <element name="runStrategy">
+ <complexType>
+ <attribute name="project" type="boolean">
+ <annotation>
+ <documentation>
+ If true then the validator is only called once per project. If false (or missing) then the validator could be called once per resource (based on the other filter rules).
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+
<annotation>
<appInfo>
<meta.section type="since"/>
@@ -293,39 +308,14 @@
</documentation>
</annotation>
- <annotation>
- <appInfo>
- <meta.section type="examples"/>
- </appInfo>
- <documentation>
-
- </documentation>
- </annotation>
- <annotation>
- <appInfo>
- <meta.section type="apiInfo"/>
- </appInfo>
- <documentation>
-
- </documentation>
- </annotation>
-
- <annotation>
- <appInfo>
- <meta.section type="implementation"/>
- </appInfo>
- <documentation>
-
- </documentation>
- </annotation>
<annotation>
<appInfo>
<meta.section type="copyright"/>
</appInfo>
<documentation>
- Copyright (c) 2005 IBM Corporation and others.<br>
+ Copyright (c) 2005, 2010 IBM Corporation and others.<br>
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 <a