diff options
author | cdamus | 2013-03-04 18:08:07 +0000 |
---|---|---|
committer | cdamus | 2013-03-04 18:08:07 +0000 |
commit | 8a11ef7db82c56f8aa635b1045fc45e8f2e1b4e0 (patch) | |
tree | 7ce93ed651942225a824997b9fd9e289c5451a7a | |
parent | ed6b24a88f1959e7298b24a267d89d7f5d802139 (diff) | |
download | org.eclipse.papyrus-8a11ef7db82c56f8aa635b1045fc45e8f2e1b4e0.tar.gz org.eclipse.papyrus-8a11ef7db82c56f8aa635b1045fc45e8f2e1b4e0.tar.xz org.eclipse.papyrus-8a11ef7db82c56f8aa635b1045fc45e8f2e1b4e0.zip |
Protect creation of CDO problem markers in a read transaction.
https://bugs.eclipse.org/bugs/show_bug.cgi?id=402188
13 files changed, 539 insertions, 104 deletions
diff --git a/plugins/cdo/org.eclipse.papyrus.cdo.ui/src/org/eclipse/papyrus/cdo/internal/ui/markers/CDOMarkerMonitor.java b/plugins/cdo/org.eclipse.papyrus.cdo.ui/src/org/eclipse/papyrus/cdo/internal/ui/markers/CDOMarkerMonitor.java index 7e805abac71..a779269e3a8 100644 --- a/plugins/cdo/org.eclipse.papyrus.cdo.ui/src/org/eclipse/papyrus/cdo/internal/ui/markers/CDOMarkerMonitor.java +++ b/plugins/cdo/org.eclipse.papyrus.cdo.ui/src/org/eclipse/papyrus/cdo/internal/ui/markers/CDOMarkerMonitor.java @@ -34,7 +34,9 @@ public class CDOMarkerMonitor } @Override - protected void initialize(ModelSet modelSet) { + public void initialize(ModelSet modelSet) { + super.initialize(modelSet); + this.util = new ProblemEditUtil( ((AdapterFactoryEditingDomain) modelSet .getTransactionalEditingDomain()).getAdapterFactory()); @@ -44,12 +46,14 @@ public class CDOMarkerMonitor } @Override - protected void dispose(ModelSet modelSet) { + public void dispose() { if (problemsListener != null) { - ProblemsManager.getProblemsManager(modelSet) + ProblemsManager.getProblemsManager(getModelSet()) .removeProblemsListener(problemsListener); problemsListener = null; } + + super.dispose(); } protected ProblemsListener createProblemsListener() { diff --git a/plugins/cdo/org.eclipse.papyrus.cdo.ui/src/org/eclipse/papyrus/cdo/internal/ui/markers/CDOMarkerProvider.java b/plugins/cdo/org.eclipse.papyrus.cdo.ui/src/org/eclipse/papyrus/cdo/internal/ui/markers/CDOMarkerProvider.java index d43c75ed652..77448d0e7c2 100644 --- a/plugins/cdo/org.eclipse.papyrus.cdo.ui/src/org/eclipse/papyrus/cdo/internal/ui/markers/CDOMarkerProvider.java +++ b/plugins/cdo/org.eclipse.papyrus.cdo.ui/src/org/eclipse/papyrus/cdo/internal/ui/markers/CDOMarkerProvider.java @@ -14,18 +14,26 @@ package org.eclipse.papyrus.cdo.internal.ui.markers; import java.util.Collection; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.SubMonitor; import org.eclipse.emf.cdo.eresource.CDOResource; import org.eclipse.emf.common.notify.AdapterFactory; import org.eclipse.emf.common.util.Diagnostic; +import org.eclipse.emf.common.util.WrappedException; +import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain; import org.eclipse.emf.edit.provider.ComposedAdapterFactory; +import org.eclipse.emf.transaction.RunnableWithResult; +import org.eclipse.emf.transaction.util.TransactionUtil; +import org.eclipse.papyrus.cdo.internal.ui.Activator; +import org.eclipse.papyrus.cdo.validation.problems.EProblem; import org.eclipse.papyrus.cdo.validation.problems.edit.ProblemEditUtil; import org.eclipse.papyrus.cdo.validation.problems.util.ProblemsManager; import org.eclipse.papyrus.infra.core.resource.ModelSet; import org.eclipse.papyrus.infra.services.markerlistener.IPapyrusMarker; -import org.eclipse.papyrus.infra.services.markerlistener.providers.IMarkerProvider; +import org.eclipse.papyrus.infra.services.markerlistener.providers.AbstractMarkerProvider; import com.google.common.collect.Iterators; import com.google.common.collect.Lists; @@ -34,7 +42,7 @@ import com.google.common.collect.Lists; * This is the CDOMarkerProvider type. Enjoy. */ public class CDOMarkerProvider - implements IMarkerProvider { + extends AbstractMarkerProvider { private final ProblemEditUtil defaultUtil = new ProblemEditUtil( new ComposedAdapterFactory( @@ -48,21 +56,119 @@ public class CDOMarkerProvider return resource instanceof CDOResource; } - public Collection<? extends IPapyrusMarker> getMarkers(Resource resource, - String type, boolean includeSubtypes) + public Collection<? extends IPapyrusMarker> getMarkers( + final Resource resource, String type, boolean includeSubtypes) throws CoreException { - return Lists.newArrayList(Iterators.transform( - getProblemsManager(resource).getAllProblems(resource), - CDOPapyrusMarker.wrap(getProblemEditUtil(resource)))); + // run in a read-only transaction because the problems manager accesses + // a cross-reference adapter + return run( + resource, + CoreException.class, + new RunnableWithResult.Impl<Collection<? extends IPapyrusMarker>>() { + + public void run() { + setResult(Lists.newArrayList(Iterators.transform( + getProblemsManager(resource).getAllProblems(resource), + CDOPapyrusMarker.wrap(getProblemEditUtil(resource))))); + } + }); + } + + @Override + public void createMarkers(final Resource resource, + final Diagnostic diagnostic, final IProgressMonitor monitor) + throws CoreException { + + // run in a read-only transaction because the problems manager accesses + // a cross-reference adapter. Note that a read/write transaction is not + // needed because we aren't modifying the contents of the resource set + // (the problems model is not stored in a resource) + run(resource, CoreException.class, new Runnable() { + + public void run() { + try { + basicCreateMarkers(resource, diagnostic, monitor); + } catch (CoreException e) { + throw new WrappedException(e); + } + } + }); + } + + final void basicCreateMarkers(Resource resource, Diagnostic diagnostic, + IProgressMonitor monitor) + throws CoreException { + + super.createMarkers(resource, diagnostic, monitor); + } + + @Override + protected void doCreateMarker(Resource resource, Diagnostic diagnostic) + throws CoreException { + + ProblemsManager mgr = getProblemsManager(resource); + EProblem problem = mgr.createProblem(diagnostic); + if (problem != null) { + mgr.addProblem(problem); + } + } + + @Override + protected void batchCreated(Resource resource) { + super.batchCreated(resource); + + ResourceSet rset = resource.getResourceSet(); + if (rset instanceof ModelSet) { + // yield the resource set to any other threads that might + // be waiting to read it + ((ModelSet) rset).getTransactionalEditingDomain().yield(); + } + } + + @Override + public void deleteMarkers(final EObject object, + final IProgressMonitor monitor) + throws CoreException { + + // run in a read-only transaction because the problems manager accesses + // a cross-reference adapter. Note that a read/write transaction is not + // needed because we aren't modifying the contents of the resource set + // (the problems model is not stored in a resource) + run(object.eResource(), CoreException.class, new Runnable() { + + public void run() { + try { + basicDeleteMarkers(object, monitor); + } catch (CoreException e) { + throw new WrappedException(e); + } + } + }); } - public void createMarkers(Resource resource, Diagnostic diagnostic) { - getProblemsManager(resource).addDiagnostic(diagnostic); + protected final void basicDeleteMarkers(EObject object, + IProgressMonitor monitor) + throws CoreException { + + super.deleteMarkers(object, monitor); } - public void deleteMarkers(Resource resource) { - getProblemsManager(resource).purgeProblems(resource); + public void deleteMarkers(final Resource resource, IProgressMonitor monitor) { + SubMonitor sub = SubMonitor.convert(monitor, IProgressMonitor.UNKNOWN); + + // run in a read-only transaction because the problems manager accesses + // a cross-reference adapter. Note that a read/write transaction is not + // needed because we aren't modifying the contents of the resource set + // (the problems model is not stored in a resource) + run(resource, new Runnable() { + + public void run() { + getProblemsManager(resource).purgeProblems(resource); + } + }); + + sub.done(); } private ProblemsManager getProblemsManager(Resource resource) { @@ -81,4 +187,56 @@ public class CDOMarkerProvider return result; } + + static <X extends Throwable> void run(Resource context, Runnable runnable) { + run(context, RuntimeException.class, runnable); + } + + static <X extends Throwable> void run(Resource context, + Class<X> exceptionType, Runnable runnable) + throws X { + + ResourceSet rset = context.getResourceSet(); + if (rset instanceof ModelSet) { + try { + ((ModelSet) rset).getTransactionalEditingDomain().runExclusive( + runnable); + } catch (WrappedException e) { + throw exceptionType.cast(e.exception()); + } catch (InterruptedException e) { + Activator.log.error( + "CDO problem markers runnable interrupted.", e); + } + } else { + runnable.run(); + } + } + + static <T, X extends Throwable> T run(Resource context, + Class<X> exceptionType, RunnableWithResult<T> runnable) + throws X { + + T result; + + ResourceSet rset = context.getResourceSet(); + if (rset instanceof ModelSet) { + try { + result = TransactionUtil + .runExclusive( + ((ModelSet) rset).getTransactionalEditingDomain(), + runnable); + } catch (WrappedException e) { + throw exceptionType.cast(e.exception()); + } catch (InterruptedException e) { + Activator.log.error( + "CDO problem markers runnable interrupted.", e); + result = null; + } + } else { + runnable.run(); + result = runnable.getResult(); + } + + return result; + } } diff --git a/plugins/infra/services/org.eclipse.papyrus.infra.services.markerlistener/src/org/eclipse/papyrus/infra/services/markerlistener/MarkersMonitorService.java b/plugins/infra/services/org.eclipse.papyrus.infra.services.markerlistener/src/org/eclipse/papyrus/infra/services/markerlistener/MarkersMonitorService.java index 716f026588c..a90af6730f7 100644 --- a/plugins/infra/services/org.eclipse.papyrus.infra.services.markerlistener/src/org/eclipse/papyrus/infra/services/markerlistener/MarkersMonitorService.java +++ b/plugins/infra/services/org.eclipse.papyrus.infra.services.markerlistener/src/org/eclipse/papyrus/infra/services/markerlistener/MarkersMonitorService.java @@ -53,6 +53,8 @@ public class MarkersMonitorService implements IService { private List<IMarkerMonitor> monitorExtensions;
+ private final IMarkerEventListener relay = createRelayListener();
+
/**
* Gets the services registry.
*
@@ -125,7 +127,8 @@ public class MarkersMonitorService implements IService { for (IMarkerMonitor next : monitorExtensions) {
try {
- next.initialize(modelSet, registeredMarkerEventListeners);
+ next.initialize(modelSet);
+ next.addMarkerEventListener(relay);
} catch (Exception e) {
Activator.log.error(
"Uncaught exception in initialization of marker monitor.",
@@ -142,6 +145,7 @@ public class MarkersMonitorService implements IService { public void disposeService() throws ServiceException {
for (IMarkerMonitor next : monitorExtensions) {
try {
+ next.removeMarkerEventListener(relay);
next.dispose();
} catch (Exception e) {
Activator.log.error(
@@ -190,4 +194,37 @@ public class MarkersMonitorService implements IService { resource, type, includeSubtypes);
}
+ private IMarkerEventListener createRelayListener() {
+ return new IMarkerEventListener() {
+
+ public void notifyMarkerChange(EObject eObjectOfMarker,
+ IPapyrusMarker marker, int addedOrRemoved) {
+
+ for (IMarkerEventListener next : registeredMarkerEventListeners) {
+ try {
+ next.notifyMarkerChange(eObjectOfMarker, marker, addedOrRemoved);
+ } catch (Exception e) {
+ Activator.log.error("Uncaught exception in marker listener.", e);
+ }
+ }
+ }
+
+ public void startService() {
+ // not needed
+ }
+
+ public void init(ServicesRegistry servicesRegistry) {
+ // not needed
+ }
+
+ public void disposeService() {
+ // not needed
+ }
+
+ public boolean isNotifiedOnInitialMarkerCheck() {
+ // not needed
+ return false;
+ }
+ };
+ }
}
diff --git a/plugins/infra/services/org.eclipse.papyrus.infra.services.markerlistener/src/org/eclipse/papyrus/infra/services/markerlistener/providers/AbstractMarkerMonitor.java b/plugins/infra/services/org.eclipse.papyrus.infra.services.markerlistener/src/org/eclipse/papyrus/infra/services/markerlistener/providers/AbstractMarkerMonitor.java index c8e5ce8a2a7..7c0252f9037 100644 --- a/plugins/infra/services/org.eclipse.papyrus.infra.services.markerlistener/src/org/eclipse/papyrus/infra/services/markerlistener/providers/AbstractMarkerMonitor.java +++ b/plugins/infra/services/org.eclipse.papyrus.infra.services.markerlistener/src/org/eclipse/papyrus/infra/services/markerlistener/providers/AbstractMarkerMonitor.java @@ -11,9 +11,10 @@ *****************************************************************************/ package org.eclipse.papyrus.infra.services.markerlistener.providers; -import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; import org.eclipse.papyrus.infra.core.resource.ModelSet; +import org.eclipse.papyrus.infra.services.markerlistener.Activator; import org.eclipse.papyrus.infra.services.markerlistener.IMarkerEventListener; import org.eclipse.papyrus.infra.services.markerlistener.IPapyrusMarker; @@ -25,37 +26,35 @@ public abstract class AbstractMarkerMonitor private ModelSet modelSet; - private List<IMarkerEventListener> listeners; + private final CopyOnWriteArrayList<IMarkerEventListener> listeners = new CopyOnWriteArrayList<IMarkerEventListener>(); public AbstractMarkerMonitor() { super(); } - public final void initialize(ModelSet modelSet, - List<IMarkerEventListener> listeners) { - + public void initialize(ModelSet modelSet) { this.modelSet = modelSet; - this.listeners = listeners; - - initialize(modelSet); } - protected abstract void initialize(ModelSet modelSet); - - public final void dispose() { - // I don't own the list, so don't clear it! - listeners = null; - - dispose(modelSet); + protected final ModelSet getModelSet() { + return modelSet; } - protected abstract void dispose(ModelSet modelSet); + public void dispose() { + listeners.clear(); + modelSet = null; + } protected void fireMarkerAdded(IPapyrusMarker marker) { if (this.listeners != null) { for (IMarkerEventListener listener : this.listeners) { - listener.notifyMarkerChange(marker.getEObject(), marker, - IMarkerEventListener.MARKER_ADDED); + try { + listener.notifyMarkerChange(marker.getEObject(), marker, + IMarkerEventListener.MARKER_ADDED); + } catch (Exception e) { + Activator.log.error( + "Uncaught exception in marker listener.", e); + } } } } @@ -63,10 +62,22 @@ public abstract class AbstractMarkerMonitor protected void fireMarkerRemoved(IPapyrusMarker marker) { if (this.listeners != null) { for (IMarkerEventListener listener : this.listeners) { - listener.notifyMarkerChange(marker.getEObject(), marker, - IMarkerEventListener.MARKER_REMOVED); + try { + listener.notifyMarkerChange(marker.getEObject(), marker, + IMarkerEventListener.MARKER_REMOVED); + } catch (Exception e) { + Activator.log.error( + "Uncaught exception in marker listener.", e); + } } } } + public void addMarkerEventListener(IMarkerEventListener listener) { + listeners.addIfAbsent(listener); + } + + public void removeMarkerEventListener(IMarkerEventListener listener) { + listeners.remove(listener); + } } diff --git a/plugins/infra/services/org.eclipse.papyrus.infra.services.markerlistener/src/org/eclipse/papyrus/infra/services/markerlistener/providers/AbstractMarkerProvider.java b/plugins/infra/services/org.eclipse.papyrus.infra.services.markerlistener/src/org/eclipse/papyrus/infra/services/markerlistener/providers/AbstractMarkerProvider.java new file mode 100644 index 00000000000..73df8a1d994 --- /dev/null +++ b/plugins/infra/services/org.eclipse.papyrus.infra.services.markerlistener/src/org/eclipse/papyrus/infra/services/markerlistener/providers/AbstractMarkerProvider.java @@ -0,0 +1,161 @@ +/***************************************************************************** + * Copyright (c) 2013 CEA LIST. + * + * 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: + * CEA LIST - Initial API and implementation + *****************************************************************************/ +package org.eclipse.papyrus.infra.services.markerlistener.providers; + +import java.util.Collection; +import java.util.List; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.SubMonitor; +import org.eclipse.emf.common.util.Diagnostic; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.papyrus.infra.services.markerlistener.IPapyrusMarker; +import org.eclipse.swt.widgets.Display; + +/** + * This is the AbstractMarkerProvider type. Enjoy. + */ +public abstract class AbstractMarkerProvider + implements IMarkerProvider { + + /** + * show progress all n marker deletions + */ + public static int DELETE_PMARKER_INTERVAL = 50; + + /** + * show progress all n marker creations + */ + public static int CREATE_PMARKER_INTERVAL = 20; + + public AbstractMarkerProvider() { + super(); + } + + public void createMarkers(Resource resource, Diagnostic diagnostic, + IProgressMonitor monitor) + throws CoreException { + + List<Diagnostic> children = diagnostic.getChildren(); + + SubMonitor sub = SubMonitor.convert(monitor, children.size() + / CREATE_PMARKER_INTERVAL); + CoreException exception = null; + + int i = 0; + for (Diagnostic next : children) { + try { + doCreateMarker(resource, next); + } catch (CoreException e) { + if (exception == null) { + exception = e; + } + + if (i++ > CREATE_PMARKER_INTERVAL) { + i = 0; + sub.worked(1); + batchCreated(resource); + } + } + } + + sub.done(); + + if (exception != null) { + throw exception; + } + } + + /** + * Creates a single marker for the specified {@code diagnostic}. This method + * should not iterate the children of the {@code diagnostic}. + * + * @param resource + * the resource on which to create a marker + * @param diagnostic + * the diagnostic describing the marker to create + * + * @throws CoreException + * on failure to create the marker + */ + protected abstract void doCreateMarker(Resource resource, + Diagnostic diagnostic) + throws CoreException; + + /** + * Notifies that a batch of markers has been created. This is an opportunity + * to update user interfaces, let other threads complete some work, etc. + * Subclasses should extend this method by calling {@code super}. + * + * @param resource + * the resource on which a batch of markers was created + */ + protected void batchCreated(Resource resource) { + Display display = Display.getCurrent(); + if (display != null) { + // process pending display events + while (display.readAndDispatch()); + } + } + + public void deleteMarkers(EObject eObject, IProgressMonitor monitor) + throws CoreException { + + Resource resource = eObject.eResource(); + Collection<? extends IPapyrusMarker> markers = getMarkers(resource, + null, true); + + SubMonitor sub = SubMonitor.convert(monitor, markers.size() + / DELETE_PMARKER_INTERVAL); + CoreException exception = null; + + int i = 0; + for (IPapyrusMarker marker : markers) { + if (isContainedBy(marker.getEObject(), eObject)) { + if (monitor.isCanceled()) { + break; + } + + try { + marker.delete(); + } catch (CoreException e) { + if (exception == null) { + exception = e; + } + } + } + + if (i++ > DELETE_PMARKER_INTERVAL) { + i = 0; + sub.worked(1); + } + } + + sub.done(); + + if (exception != null) { + throw exception; + } + } + + private boolean isContainedBy(EObject subEObj, EObject eObj) { + if (eObj == subEObj) + return true; + else if (subEObj != null) { + return isContainedBy(subEObj.eContainer(), eObj); + } + // reached, if subEObj == null + return false; + } +} diff --git a/plugins/infra/services/org.eclipse.papyrus.infra.services.markerlistener/src/org/eclipse/papyrus/infra/services/markerlistener/providers/IMarkerMonitor.java b/plugins/infra/services/org.eclipse.papyrus.infra.services.markerlistener/src/org/eclipse/papyrus/infra/services/markerlistener/providers/IMarkerMonitor.java index e591fcb890b..8f7dcedc982 100644 --- a/plugins/infra/services/org.eclipse.papyrus.infra.services.markerlistener/src/org/eclipse/papyrus/infra/services/markerlistener/providers/IMarkerMonitor.java +++ b/plugins/infra/services/org.eclipse.papyrus.infra.services.markerlistener/src/org/eclipse/papyrus/infra/services/markerlistener/providers/IMarkerMonitor.java @@ -11,17 +11,21 @@ *****************************************************************************/ package org.eclipse.papyrus.infra.services.markerlistener.providers; -import java.util.List; - import org.eclipse.papyrus.infra.core.resource.ModelSet; import org.eclipse.papyrus.infra.services.markerlistener.IMarkerEventListener; /** - * This is the IMarkerMonitor type. Enjoy. + * Interface for a pluggable marker monitor, which is reponsible for listening + * for marker changes on a particular {@link ModelSet}'s resources and + * broadcasting them to registered listeners. */ public interface IMarkerMonitor { - void initialize(ModelSet modelSet, List<IMarkerEventListener> listeners); + void initialize(ModelSet modelSet); void dispose(); + + void addMarkerEventListener(IMarkerEventListener listener); + + void removeMarkerEventListener(IMarkerEventListener listener); } diff --git a/plugins/infra/services/org.eclipse.papyrus.infra.services.markerlistener/src/org/eclipse/papyrus/infra/services/markerlistener/providers/IMarkerProvider.java b/plugins/infra/services/org.eclipse.papyrus.infra.services.markerlistener/src/org/eclipse/papyrus/infra/services/markerlistener/providers/IMarkerProvider.java index bf61afd35c0..0382015af0a 100644 --- a/plugins/infra/services/org.eclipse.papyrus.infra.services.markerlistener/src/org/eclipse/papyrus/infra/services/markerlistener/providers/IMarkerProvider.java +++ b/plugins/infra/services/org.eclipse.papyrus.infra.services.markerlistener/src/org/eclipse/papyrus/infra/services/markerlistener/providers/IMarkerProvider.java @@ -15,7 +15,9 @@ import java.util.Collection; import java.util.Collections; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.emf.common.util.Diagnostic; +import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.papyrus.infra.services.markerlistener.IPapyrusMarker; @@ -32,14 +34,20 @@ public interface IMarkerProvider { public Collection<? extends IPapyrusMarker> getMarkers( Resource resource, String type, boolean includeSubtypes) { + return Collections.emptyList(); } - - public void createMarkers(Resource resource, Diagnostic diagnostic) { + + public void createMarkers(Resource resource, Diagnostic diagnostic, + IProgressMonitor monitor) { // pass } - - public void deleteMarkers(Resource resource) { + + public void deleteMarkers(EObject object, IProgressMonitor monitor) { + // pass + } + + public void deleteMarkers(Resource resource, IProgressMonitor monitor) { // pass } }; @@ -79,7 +87,54 @@ public interface IMarkerProvider { String type, boolean includeSubtypes) throws CoreException; - void createMarkers(Resource resource, Diagnostic diagnostic); - - void deleteMarkers(Resource resource); + /** + * Creates markers on the specified {@code resource} from a tree of + * diagnostics. + * + * @param resource + * a resource on which to create markers + * @param diagnostic + * a tree of diagnostics for model elements in the + * {@code resource} + * @param monitor + * an optional monitor for reporting progress. May be + * {@code null} + * + * @throws CoreException + * on failure to create any marker + */ + void createMarkers(Resource resource, Diagnostic diagnostic, + IProgressMonitor monitor) + throws CoreException; + + /** + * Deletes all of the markers attached to an {@code object} and its content + * tree. + * + * @param object + * a content tree from which to delete markers + * @param monitor + * an optional monitor for reporting progress. May be + * {@code null} + * + * @throws CoreException + * on failure to delete any marker + */ + void deleteMarkers(EObject object, IProgressMonitor monitor) + throws CoreException; + + /** + * Deletes all of the markers attached to a {@code resource}. + * + * @param resource + * a resource from which to delete markers + * @param monitor + * an optional monitor for reporting progress. May be + * {@code null} + * + * @throws CoreException + * on failure to delete any marker + */ + void deleteMarkers(Resource resource, IProgressMonitor monitor) + throws CoreException; } diff --git a/plugins/infra/services/org.eclipse.papyrus.infra.services.markerlistener/src/org/eclipse/papyrus/infra/services/markerlistener/providers/MarkerProviderRegistry.java b/plugins/infra/services/org.eclipse.papyrus.infra.services.markerlistener/src/org/eclipse/papyrus/infra/services/markerlistener/providers/MarkerProviderRegistry.java index c4a7f7e5a62..a8c1684c576 100644 --- a/plugins/infra/services/org.eclipse.papyrus.infra.services.markerlistener/src/org/eclipse/papyrus/infra/services/markerlistener/providers/MarkerProviderRegistry.java +++ b/plugins/infra/services/org.eclipse.papyrus.infra.services.markerlistener/src/org/eclipse/papyrus/infra/services/markerlistener/providers/MarkerProviderRegistry.java @@ -25,8 +25,10 @@ import org.eclipse.core.expressions.ExpressionConverter; import org.eclipse.core.expressions.IEvaluationContext; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.Platform; import org.eclipse.emf.common.util.Diagnostic; +import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.plugin.RegistryReader; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.papyrus.infra.services.markerlistener.Activator; @@ -36,8 +38,9 @@ import org.eclipse.papyrus.infra.services.markerlistener.IPapyrusMarker; * This is the MarkerProviderRegistry type. Enjoy. */ public class MarkerProviderRegistry { + private static final String EXT_POINT = "markerproviders"; - + public static final MarkerProviderRegistry INSTANCE = new MarkerProviderRegistry(); private final List<IMarkerProvider> providers = new java.util.ArrayList<IMarkerProvider>(); @@ -264,12 +267,24 @@ public class MarkerProviderRegistry { .getMarkers(resource, type, includeSubtypes); } - public void createMarkers(Resource resource, Diagnostic diagnostic) { - getInstance().createMarkers(resource, diagnostic); + public void createMarkers(Resource resource, Diagnostic diagnostic, + IProgressMonitor monitor) + throws CoreException { + + getInstance().createMarkers(resource, diagnostic, monitor); + } + + public void deleteMarkers(EObject object, IProgressMonitor monitor) + throws CoreException { + + getInstance().deleteMarkers(object, monitor); } - public void deleteMarkers(Resource resource) { - getInstance().deleteMarkers(resource); + public void deleteMarkers(Resource resource, + IProgressMonitor monitor) + throws CoreException { + + getInstance().deleteMarkers(resource, monitor); } } } diff --git a/plugins/infra/services/org.eclipse.papyrus.infra.services.markerlistener/src/org/eclipse/papyrus/infra/services/markerlistener/providers/WorkspaceMarkerMonitor.java b/plugins/infra/services/org.eclipse.papyrus.infra.services.markerlistener/src/org/eclipse/papyrus/infra/services/markerlistener/providers/WorkspaceMarkerMonitor.java index be1ae3206db..59a25511684 100644 --- a/plugins/infra/services/org.eclipse.papyrus.infra.services.markerlistener/src/org/eclipse/papyrus/infra/services/markerlistener/providers/WorkspaceMarkerMonitor.java +++ b/plugins/infra/services/org.eclipse.papyrus.infra.services.markerlistener/src/org/eclipse/papyrus/infra/services/markerlistener/providers/WorkspaceMarkerMonitor.java @@ -39,7 +39,9 @@ public class WorkspaceMarkerMonitor } @Override - protected void initialize(ModelSet modelSet) { + public void initialize(ModelSet modelSet) { + super.initialize(modelSet); + this.fileObserver = new MarkerObserver(modelSet.getTransactionalEditingDomain()); //Start Listening @@ -47,9 +49,11 @@ public class WorkspaceMarkerMonitor } @Override - protected void dispose(ModelSet modelSet) { + public void dispose() { //Stop Listening FileChangeManager.getInstance().removeFileObserver(this.fileObserver); + + super.dispose(); } // File Listening Functions diff --git a/plugins/infra/services/org.eclipse.papyrus.infra.services.markerlistener/src/org/eclipse/papyrus/infra/services/markerlistener/providers/WorkspaceMarkerProvider.java b/plugins/infra/services/org.eclipse.papyrus.infra.services.markerlistener/src/org/eclipse/papyrus/infra/services/markerlistener/providers/WorkspaceMarkerProvider.java index 1ee362fd67f..1b84519e05c 100644 --- a/plugins/infra/services/org.eclipse.papyrus.infra.services.markerlistener/src/org/eclipse/papyrus/infra/services/markerlistener/providers/WorkspaceMarkerProvider.java +++ b/plugins/infra/services/org.eclipse.papyrus.infra.services.markerlistener/src/org/eclipse/papyrus/infra/services/markerlistener/providers/WorkspaceMarkerProvider.java @@ -20,6 +20,8 @@ import java.util.Collections; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IMarker; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.SubMonitor; import org.eclipse.emf.common.util.Diagnostic; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.papyrus.infra.services.markerlistener.IPapyrusMarker; @@ -31,7 +33,7 @@ import org.eclipse.papyrus.infra.services.markerlistener.util.MarkerListenerUtil * This is the WorkspaceMarkerProvider type. Enjoy. */ public class WorkspaceMarkerProvider - implements IMarkerProvider { + extends AbstractMarkerProvider { public WorkspaceMarkerProvider() { super(); @@ -58,15 +60,23 @@ public class WorkspaceMarkerProvider } public void createMarkers(Resource resource, Diagnostic diagnostic) { + } + + @Override + protected void doCreateMarker(Resource resource, Diagnostic diagnostic) + throws CoreException { + if (MarkerListenerUtils.eclipseResourcesUtil != null) { MarkerListenerUtils.eclipseResourcesUtil.createMarkers(resource, diagnostic); } } - public void deleteMarkers(Resource resource) { + public void deleteMarkers(Resource resource, IProgressMonitor monitor) { if (MarkerListenerUtils.eclipseResourcesUtil != null) { + SubMonitor sub = SubMonitor.convert(monitor, IProgressMonitor.UNKNOWN); MarkerListenerUtils.eclipseResourcesUtil.deleteMarkers(resource); + sub.done(); } } } diff --git a/plugins/infra/services/org.eclipse.papyrus.infra.services.validation/src/org/eclipse/papyrus/infra/services/validation/ValidationTool.java b/plugins/infra/services/org.eclipse.papyrus.infra.services.validation/src/org/eclipse/papyrus/infra/services/validation/ValidationTool.java index 81ca8aa3878..cec4ea7a0d6 100644 --- a/plugins/infra/services/org.eclipse.papyrus.infra.services.validation/src/org/eclipse/papyrus/infra/services/validation/ValidationTool.java +++ b/plugins/infra/services/org.eclipse.papyrus.infra.services.validation/src/org/eclipse/papyrus/infra/services/validation/ValidationTool.java @@ -142,31 +142,11 @@ public class ValidationTool { * @param monitor A progress monitor */ public void deleteSubMarkers(IProgressMonitor monitor) { - int i = 0; - for(IPapyrusMarker marker : getMarkers()) { - EObject eObjOfMarker = marker.getEObject(); - if(isContainedBy(eObjOfMarker, getEObject())) { - try { - marker.delete(); - - } catch (CoreException e) { - } - } - if(i++ > DELETE_PMARKER_RATIO) { - i = 0; - monitor.worked(1); - } - } - } - - private boolean isContainedBy(EObject subEObj, EObject eObj) { - if(eObj == subEObj) - return true; - else if(subEObj != null) { - return isContainedBy(subEObj.eContainer(), eObj); + try { + provider.deleteMarkers(getEObject(), monitor); + } catch (CoreException e) { + Activator.getDefault().getLog().log(e.getStatus()); } - // reached, if subEObj == null - return false; } public IRunnableWithProgress wrap(IRunnableWithProgress runnableWithProgress) { @@ -184,7 +164,11 @@ public class ValidationTool { return provider instanceof WorkspaceMarkerProvider; } - public void createMarkers(Diagnostic diagnostic) { - provider.createMarkers(resource, diagnostic); + public void createMarkers(Diagnostic diagnostic, IProgressMonitor monitor) { + try { + provider.createMarkers(resource, diagnostic, monitor); + } catch (CoreException e) { + Activator.getDefault().getLog().log(e.getStatus()); + } } } diff --git a/plugins/infra/services/org.eclipse.papyrus.infra.services.validation/src/org/eclipse/papyrus/infra/services/validation/commands/AbstractValidateCommand.java b/plugins/infra/services/org.eclipse.papyrus.infra.services.validation/src/org/eclipse/papyrus/infra/services/validation/commands/AbstractValidateCommand.java index cae520c4239..f9e64c38a08 100644 --- a/plugins/infra/services/org.eclipse.papyrus.infra.services.validation/src/org/eclipse/papyrus/infra/services/validation/commands/AbstractValidateCommand.java +++ b/plugins/infra/services/org.eclipse.papyrus.infra.services.validation/src/org/eclipse/papyrus/infra/services/validation/commands/AbstractValidateCommand.java @@ -20,6 +20,7 @@ import java.util.Iterator; import java.util.Map; import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.SubMonitor; import org.eclipse.emf.common.notify.AdapterFactory; import org.eclipse.emf.common.util.BasicDiagnostic; import org.eclipse.emf.common.util.Diagnostic; @@ -210,37 +211,22 @@ abstract public class AbstractValidateCommand extends AbstractTransactionalComma // final Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); if(resource != null) { if(validateElement != null) { + SubMonitor sub = SubMonitor.convert(monitor, 2); + ValidationTool vt = new ValidationTool(validateElement, resource); - int monitorDeletionSteps = vt.getMarkers().size() / ValidationTool.DELETE_PMARKER_RATIO; int markersToCreate = diagnostic.getChildren().size(); - int monitorCreationSteps = markersToCreate / ValidationTool.CREATE_PMARKER_RATIO; - monitor.beginTask("delete existing markers", monitorDeletionSteps + monitorCreationSteps); //$NON-NLS-1$ + sub.beginTask("Delete existing markers", 1); flushDisplayEvents(shell.getDisplay()); - vt.deleteSubMarkers(monitor); + vt.deleteSubMarkers(sub.newChild(1)); - // IFile file = WorkspaceSynchronizer.getFile(resource); - // eclipseResourcesUtil.deleteMarkers (file); - - int i = 0; monitor.setTaskName("Create markers (total: " + markersToCreate + " markers) and refresh diagrams"); //$NON-NLS-1$ flushDisplayEvents(shell.getDisplay()); - for(Diagnostic childDiagnostic : diagnostic.getChildren()) { - - if(monitor.isCanceled()) { - break; - } - vt.createMarkers(childDiagnostic); - if(i++ > ValidationTool.CREATE_PMARKER_RATIO) { - i = 0; - monitor.worked(1); - // let other threads work, in particular the marker update thread - Thread.yield(); - flushDisplayEvents(shell.getDisplay()); - } - } + vt.createMarkers(diagnostic, sub.newChild(1)); + + sub.done(); } } } diff --git a/plugins/infra/services/org.eclipse.papyrus.infra.services.validation/src/org/eclipse/papyrus/infra/services/validation/commands/ValidateDelMarkersFromModelCommand.java b/plugins/infra/services/org.eclipse.papyrus.infra.services.validation/src/org/eclipse/papyrus/infra/services/validation/commands/ValidateDelMarkersFromModelCommand.java index 9303f5056a6..99cb2a3b398 100644 --- a/plugins/infra/services/org.eclipse.papyrus.infra.services.validation/src/org/eclipse/papyrus/infra/services/validation/commands/ValidateDelMarkersFromModelCommand.java +++ b/plugins/infra/services/org.eclipse.papyrus.infra.services.validation/src/org/eclipse/papyrus/infra/services/validation/commands/ValidateDelMarkersFromModelCommand.java @@ -16,6 +16,7 @@ package org.eclipse.papyrus.infra.services.validation.commands; import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.emf.ecore.EObject; @@ -38,7 +39,12 @@ public class ValidateDelMarkersFromModelCommand extends AbstractValidateCommand protected CommandResult doExecuteWithResult(IProgressMonitor monitor, IAdaptable info) throws ExecutionException { Resource resource = getValidationResource(); if (resource != null) { - MarkerListenerUtils.getMarkerProvider(getValidationResource()).deleteMarkers(resource); + try { + MarkerListenerUtils.getMarkerProvider(getValidationResource()) + .deleteMarkers(resource, monitor); + } catch (CoreException e) { + throw new ExecutionException("Failed to delete all markers.", e); + } } return null; } |