[258000] Multi threading fixes
diff --git a/plugins/org.eclipse.wst.validation.ui/vf2/org/eclipse/wst/validation/ui/internal/ManualValidationRunner.java b/plugins/org.eclipse.wst.validation.ui/vf2/org/eclipse/wst/validation/ui/internal/ManualValidationRunner.java
index 52b47ea..f70bcce 100644
--- a/plugins/org.eclipse.wst.validation.ui/vf2/org/eclipse/wst/validation/ui/internal/ManualValidationRunner.java
+++ b/plugins/org.eclipse.wst.validation.ui/vf2/org/eclipse/wst/validation/ui/internal/ManualValidationRunner.java
@@ -22,9 +22,9 @@
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.MultiRule;
import org.eclipse.swt.widgets.Display;
-import org.eclipse.wst.validation.ValidationResult;
import org.eclipse.wst.validation.internal.ValOperation;
import org.eclipse.wst.validation.internal.ValType;
+import org.eclipse.wst.validation.internal.ValidationResultSummary;
import org.eclipse.wst.validation.internal.ValidationRunner;
import org.eclipse.wst.validation.ui.internal.dialog.ResultsDialog;
@@ -85,14 +85,14 @@
int resourceCount = 0;
for (Set s : _projects.values())resourceCount += s.size();
final int finalResourceCount = resourceCount;
- if (vo.getResult().isCanceled())return Status.CANCEL_STATUS;
+ if (vo.isCanceled())return Status.CANCEL_STATUS;
if (_showResults){
Display display = Display.getDefault();
Runnable run = new Runnable(){
public void run() {
- ValidationResult vr = vo.getResult();
+ ValidationResultSummary vr = vo.getResult();
ResultsDialog rd = new ResultsDialog(null, vr, time, finalResourceCount);
rd.open();
}
diff --git a/plugins/org.eclipse.wst.validation.ui/vf2/org/eclipse/wst/validation/ui/internal/dialog/ResultsDialog.java b/plugins/org.eclipse.wst.validation.ui/vf2/org/eclipse/wst/validation/ui/internal/dialog/ResultsDialog.java
index 4522eea..c50e50e 100644
--- a/plugins/org.eclipse.wst.validation.ui/vf2/org/eclipse/wst/validation/ui/internal/dialog/ResultsDialog.java
+++ b/plugins/org.eclipse.wst.validation.ui/vf2/org/eclipse/wst/validation/ui/internal/dialog/ResultsDialog.java
@@ -24,10 +24,10 @@
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
-import org.eclipse.wst.validation.ValidationResult;
import org.eclipse.wst.validation.internal.Misc;
import org.eclipse.wst.validation.internal.ValManager;
import org.eclipse.wst.validation.internal.ValPrefManagerGlobal;
+import org.eclipse.wst.validation.internal.ValidationResultSummary;
import org.eclipse.wst.validation.internal.model.GlobalPreferences;
import org.eclipse.wst.validation.internal.ui.ValidationUIMessages;
import org.eclipse.wst.validation.ui.internal.ValUIMessages;
@@ -39,7 +39,7 @@
*/
public class ResultsDialog extends IconAndMessageDialog {
- private ValidationResult _result;
+ private ValidationResultSummary _result;
private long _time;
private int _resourceCount;
private Button _hideButton;
@@ -52,7 +52,7 @@
* @param time the time that the validation took in milliseconds
* @param resourceCount the number of resources that were validated
*/
- public ResultsDialog(Shell parentShell, ValidationResult results, long time, int resourceCount) {
+ public ResultsDialog(Shell parentShell, ValidationResultSummary results, long time, int resourceCount) {
super(parentShell);
_result = results;
_time = time;
diff --git a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/ValidationResults.java b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/ValidationResults.java
index f614121..c32d273 100644
--- a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/ValidationResults.java
+++ b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/ValidationResults.java
@@ -10,6 +10,7 @@
*******************************************************************************/
package org.eclipse.wst.validation;
+
/**
* The combined results of validating multiple resources.
* <p>
@@ -22,10 +23,24 @@
*
*/
public class ValidationResults {
- private ValidationResult _result;
+
+ private ValidatorMessage[] _messages;
+ private int _error;
+ private int _warn;
+ private int _info;
public ValidationResults(ValidationResult result){
- _result = result;
+ if (result == null){
+ _messages = new ValidatorMessage[0];
+ }
+ else {
+ ValidatorMessage[] messages = result.getMessages();
+ _messages = new ValidatorMessage[messages.length];
+ System.arraycopy(messages, 0, _messages, 0, messages.length);
+ _error = result.getSeverityError();
+ _warn = result.getSeverityWarning();
+ _info = result.getSeverityInfo();
+ }
}
/**
@@ -33,32 +48,28 @@
* @return an array is returned even if there are no messages.
*/
public ValidatorMessage[] getMessages(){
- if (_result == null)return new ValidatorMessage[0];
- return _result.getMessages();
+ return _messages;
}
/**
* Answer the number of error messages that were generated as part of this validation operation.
*/
public int getSeverityError() {
- if (_result == null)return 0;
- return _result.getSeverityError();
+ return _error;
}
/**
* Answer the number of informational messages that were generated as part of this validation operation.
*/
public int getSeverityInfo() {
- if (_result == null)return 0;
- return _result.getSeverityInfo();
+ return _info;
}
/**
* Answer the number of warning messages that were generated as part of this validation operation.
*/
public int getSeverityWarning() {
- if (_result == null)return 0;
- return _result.getSeverityWarning();
+ return _warn;
}
}
diff --git a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/ValidationState.java b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/ValidationState.java
index 3c194ac..bee84c4 100644
--- a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/ValidationState.java
+++ b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/ValidationState.java
@@ -10,8 +10,8 @@
*******************************************************************************/
package org.eclipse.wst.validation;
-import java.util.HashMap;
import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
import org.eclipse.wst.validation.internal.plugin.ValidationPlugin;
@@ -48,7 +48,10 @@
*/
public static final String TriggerResource = ValidationPlugin.PLUGIN_ID + ".Trigger"; //$NON-NLS-1$
- private Map<String, Object> _map = new HashMap<String, Object>(50);
+ private Map<String, Object> _map = new ConcurrentHashMap<String, Object>(50);
+
+ public ValidationState(){
+ }
/**
* Save some state information.
diff --git a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ValManager.java b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ValManager.java
index 1865096..8ecd1ac 100644
--- a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ValManager.java
+++ b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ValManager.java
@@ -662,7 +662,7 @@
Tracing.log("ValManager-01: " + msg); //$NON-NLS-1$
}
if (vr != null){
- operation.getResult().mergeResults(vr);
+ operation.mergeResults(vr);
if (vr.getSuspendValidation() != null)operation.suspendValidation(vr.getSuspendValidation(), validator);
}
}
diff --git a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ValOperation.java b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ValOperation.java
index 7f35a71..a5de936 100644
--- a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ValOperation.java
+++ b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ValOperation.java
@@ -10,7 +10,6 @@
*******************************************************************************/
package org.eclipse.wst.validation.internal;
-import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
@@ -36,50 +35,61 @@
* @author karasiuk
*
*/
-public class ValOperation {
+public final class ValOperation {
- private ValidationState _state = new ValidationState();
- private ValidationResult _result = new ValidationResult();
+ private final ValidationState _state = new ValidationState();
+ private final ValidationResult _result = new ValidationResult();
/**
* Each project can have a set of validators that are suspended for the duration of the validation operation.
* The set contains the validator's id.
*/
- private Map<IProject, Set<String>> _suspended =
- Collections.synchronizedMap(new HashMap<IProject, Set<String>>(40));
+ private final Map<IProject, Set<String>> _suspended = new HashMap<IProject, Set<String>>(40);
/** The time that the operation started. */
- private long _started = System.currentTimeMillis();
+ private final long _started = System.currentTimeMillis();
/**
- * Are we in a multi project validation? This can be triggered by either clean all or
+ * Are we in a multi project validation? That is, could we be validating several
+ * projects at the same time? This can be triggered by either clean all or
* if auto build is turned off, a build all.
*/
- private boolean _multiProject;
+ private final boolean _multiProject;
/**
* Holds all the resources that have been validated as a side-effect of running other validations.
* The key is the validator id and the value is a Set of IResources.
*/
- private Map<String, Set<IResource>> _validated = new HashMap<String, Set<IResource>>(20);
+ private final Map<String, Set<IResource>> _validated = new HashMap<String, Set<IResource>>(20);
public ValOperation(){
+ _multiProject = false;
+ }
+
+ /**
+ *
+ * @param multiProject Set to true if we could be validating several projects at the same time.
+ */
+ public ValOperation(boolean multiProject){
+ _multiProject = multiProject;
}
public ValidationState getState() {
return _state;
}
- public void setState(ValidationState state) {
- _state = state;
- }
- public ValidationResult getResult() {
- return _result;
- }
- public void setResult(ValidationResult result) {
- _result = result;
+ /**
+ * Answer a summary of the validation results.
+ * @return
+ */
+ public ValidationResultSummary getResult() {
+ synchronized(_result){
+ ValidationResultSummary vrs = new ValidationResultSummary(_result.getSeverityError(),
+ _result.getSeverityWarning(), _result.getSeverityInfo());
+ return vrs;
+ }
}
-
+
public ValidationResults getResults(){
return new ValidationResults(_result);
}
@@ -91,12 +101,14 @@
* @param resource resource that has been validated.
*/
public void addValidated(String id, IResource resource){
- Set<IResource> set = _validated.get(id);
- if (set == null){
- set = new HashSet<IResource>(20);
- _validated.put(id, set);
+ synchronized(_validated){
+ Set<IResource> set = _validated.get(id);
+ if (set == null){
+ set = new HashSet<IResource>(20);
+ _validated.put(id, set);
+ }
+ set.add(resource);
}
- set.add(resource);
}
/**
@@ -107,10 +119,12 @@
* @param resource
*/
public boolean isValidated(String id, IResource resource){
- Set<IResource> set = _validated.get(id);
- if (set == null)return false;
-
- return set.contains(resource);
+ synchronized(_validated){
+ Set<IResource> set = _validated.get(id);
+ if (set == null)return false;
+
+ return set.contains(resource);
+ }
}
/**
@@ -125,8 +139,10 @@
*/
public boolean isSuspended(Validator val, IProject project) {
if (project == null)return false;
- Set<String> set = getSuspended(project);
- return set.contains(val.getId());
+ synchronized(_suspended){
+ Set<String> set = getSuspended(project);
+ return set.contains(val.getId());
+ }
}
private Set<String> getSuspended(IProject project){
@@ -152,12 +168,34 @@
return _multiProject;
}
- /**
- * Are we in a multi project validation? That is, could we be validating several
- * projects at the same time? This can be triggered by either clean all or
- * if auto build is turned off, a build all.
+ /**
+ * Indicate if the operation was canceled.
+ *
+ * @param canceled
+ * Set to true if it was canceled and false if it was not canceled.
*/
- public void setMultiProject(boolean multiProject) {
- _multiProject = multiProject;
- }
+ public void setCanceled(boolean canceled) {
+ synchronized (_result) {
+ _result.setCanceled(canceled);
+ }
+
+ }
+
+ /**
+ * Was the operation canceled before it completed? For example if the validation is being run through the
+ * user interface, the end user can cancel the operation through the progress monitor.
+ *
+ * @return true if the operation was canceled
+ */
+ public boolean isCanceled() {
+ synchronized (_result) {
+ return _result.isCanceled();
+ }
+ }
+
+ public void mergeResults(ValidationResult vr) {
+ synchronized (_result) {
+ _result.mergeResults(vr);
+ }
+ }
}
diff --git a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ValOperationManager.java b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ValOperationManager.java
index e78b6e1..63d78ea 100644
--- a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ValOperationManager.java
+++ b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ValOperationManager.java
@@ -10,6 +10,8 @@
*******************************************************************************/
package org.eclipse.wst.validation.internal;
+import java.util.concurrent.atomic.AtomicInteger;
+
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
@@ -112,7 +114,7 @@
* If we are doing a clean all, with auto build turned on, we increment this by one,
* so that we know to throw away the first workspace, auto build, post event.
*/
- private int _discardAutoPost;
+ private AtomicInteger _discardAutoPost = new AtomicInteger();
public static ValOperationManager getDefault(){
return Singleton.valOperationManager;
@@ -129,8 +131,9 @@
}
if (isBuildStarting(event)){
- _operation = new ValOperation();
- _operation.setMultiProject(true);
+ synchronized(this){
+ _operation = new ValOperation(true);
+ }
IValidatorVisitor visitor = new IValidatorVisitor(){
public void visit(Validator validator, IProject project, ValType valType,
@@ -146,7 +149,9 @@
if (isBuildFinished(event)){
ValOperationJob finished = new ValOperationJob(getOperation());
finished.schedule();
- _operation = null;
+ synchronized(this){
+ _operation = null;
+ }
}
@@ -195,7 +200,7 @@
if (ResourcesPlugin.getWorkspace().isAutoBuilding()){
if (isWorkspace && preBuild && kind == IncrementalProjectBuilder.CLEAN_BUILD){
- _discardAutoPost = 1;
+ _discardAutoPost.set(1);
return true;
}
@@ -215,8 +220,9 @@
* @return return true if we are just finishing a build.
*/
private boolean isBuildFinished(IResourceChangeEvent event) {
-
- if (_operation == null)return false;
+ synchronized(this){
+ if (_operation == null)return false;
+ }
int type = event.getType();
int kind = event.getBuildKind();
@@ -226,8 +232,7 @@
if (ResourcesPlugin.getWorkspace().isAutoBuilding()){
if (isWorkspace && postBuild && kind == IncrementalProjectBuilder.AUTO_BUILD){
- if (_discardAutoPost == 1)_discardAutoPost = 0;
- else return true;
+ if (!_discardAutoPost.compareAndSet(1, 0))return true;
}
}
else {
@@ -252,7 +257,7 @@
* Answer the current validation operation. If we are not in a multiple project validation
* we will return a new one.
*/
- public ValOperation getOperation() {
+ public synchronized ValOperation getOperation() {
/*
* If we don't have a current operation, we create a new one. The only time we save
* the operation is when we are sure that we are in a multi project validation.
diff --git a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ValidationResultSummary.java b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ValidationResultSummary.java
new file mode 100644
index 0000000..2c124bd
--- /dev/null
+++ b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ValidationResultSummary.java
@@ -0,0 +1,27 @@
+package org.eclipse.wst.validation.internal;
+
+public class ValidationResultSummary {
+
+ private int _error;
+ private int _warning;
+ private int _info;
+
+ public ValidationResultSummary(int error, int warning, int info){
+ _error = error;
+ _warning = warning;
+ _info = info;
+ }
+
+ public int getSeverityError() {
+ return _error;
+ }
+
+ public int getSeverityWarning() {
+ return _warning;
+ }
+
+ public int getSeverityInfo() {
+ return _info;
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ValidationRunner.java b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ValidationRunner.java
index c60af24..4cdb2dc 100644
--- a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ValidationRunner.java
+++ b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ValidationRunner.java
@@ -27,10 +27,15 @@
/**
* Run the validators on a selected set of resources.
+ * <p>
+ * This is used to run manual validations (i.e. the user selects the Validate menu item),
+ * or it is invoked programmatically by a third party through the ValidationFramework API.
+ * It is not used for the build based invocation.
+ * </p>
* @author karasiuk
*
*/
-public class ValidationRunner implements IWorkspaceRunnable {
+public final class ValidationRunner implements IWorkspaceRunnable {
private Map<IProject, Set<IResource>> _projects;
private ValType _valType;
@@ -91,7 +96,7 @@
for (Map.Entry<IProject, Set<IResource>> me : _projects.entrySet()){
if (monitor.isCanceled()){
- _valOperation.getResult().setCanceled(true);
+ _valOperation.setCanceled(true);
return _valOperation;
}
IProject project = me.getKey();