Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPierre-Charles David2017-05-03 09:09:19 +0000
committerPierre-Charles David2017-05-11 13:40:55 +0000
commit055cae502c47e5cd91a9bcde0d298ccfb492e32e (patch)
tree834d9a0cbca3fb424e2f2fd826672d51a4ffc704
parent924a5f6367f4bd025c3f115626dff607d4dca006 (diff)
downloadorg.eclipse.sirius-055cae502c47e5cd91a9bcde0d298ccfb492e32e.tar.gz
org.eclipse.sirius-055cae502c47e5cd91a9bcde0d298ccfb492e32e.tar.xz
org.eclipse.sirius-055cae502c47e5cd91a9bcde0d298ccfb492e32e.zip
[495036] Add EvaluationErrorHandler to SessionInterpreter
Add a configurable EvaluationErrorHandler to SessionInterpreter, which is invoked/consulted on every exception occuring while evaluating an expression. The default value does nothing, and any exception occurring is simply re-thrown as before. Bug: 495036 Change-Id: I19d55ebeb1821b2257e230d354cb3cc9ae052ad7 Signed-off-by: Pierre-Charles David <pierre-charles.david@obeo.fr>
-rw-r--r--plugins/org.eclipse.sirius/plugin.properties1
-rw-r--r--plugins/org.eclipse.sirius/src/org/eclipse/sirius/tools/internal/interpreter/EvaluationErrorHandler.java92
-rw-r--r--plugins/org.eclipse.sirius/src/org/eclipse/sirius/tools/internal/interpreter/SessionInterpreter.java185
-rw-r--r--plugins/org.eclipse.sirius/src/org/eclipse/sirius/viewpoint/Messages.java3
4 files changed, 242 insertions, 39 deletions
diff --git a/plugins/org.eclipse.sirius/plugin.properties b/plugins/org.eclipse.sirius/plugin.properties
index 2976dd058e..b8bbf909e6 100644
--- a/plugins/org.eclipse.sirius/plugin.properties
+++ b/plugins/org.eclipse.sirius/plugin.properties
@@ -241,6 +241,7 @@ SessionResourcesSynchronizer_cantHandleResourceChangeMsg = Can''t handle resourc
SessionResourcesSynchronizer_reloadOperationFailErrorMsg = a reload operation failed for unknown reason
SessionResourcesTracker_addReferencedSemanticResourcesMsg = Add referenced semantic resources
SessionResourcesTracker_semanticResourcesAccessErrorMsg = Error while accessing semantic resources
+SessionInterpreter_evaluationError = Error while evaluating expression
SessionVSMUpdater_VSMLoadErrorMsg = Unable to load the VSM at {0}
SetValueTask_label = Set a value
SiriusControlCommand_controlResourceMsg = Control resource
diff --git a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/tools/internal/interpreter/EvaluationErrorHandler.java b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/tools/internal/interpreter/EvaluationErrorHandler.java
new file mode 100644
index 0000000000..ac10135f0a
--- /dev/null
+++ b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/tools/internal/interpreter/EvaluationErrorHandler.java
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Obeo.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.tools.internal.interpreter;
+
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.sirius.viewpoint.SiriusPlugin;
+
+/**
+ * Allows client code to decide how errors occuring during expression evaluation should be treated.
+ *
+ * @author pcdavid
+ */
+public abstract class EvaluationErrorHandler {
+ /**
+ * Standard handler that ignores any exception.
+ */
+ public static final EvaluationErrorHandler IGNORE = new EvaluationErrorHandler() {
+ @Override
+ public void handleException(Exception ex) {
+ // Ignore.
+ }
+ };
+
+ /**
+ * Standard handler that triggers a rollback of the current transaction.
+ */
+ public static final EvaluationErrorHandler ROLLBACK = new EvaluationErrorHandler() {
+ @Override
+ public void handleException(Exception ex) {
+ requestTransactionRollback(ex);
+ }
+ };
+
+ /**
+ * Invoked when an expression's evaluation throws an exception.
+ *
+ * @param ex
+ * the unexpected exception which occurred during an operation.
+ * @throws RuntimeException
+ * if the handler decides that the correct behavior is to throw a real exception (the original one or
+ * another).
+ */
+ public abstract void handleException(Exception ex);
+
+ /**
+ * Can be used to log an error in the system log.
+ *
+ * @param message
+ * the message to log.
+ * @param ex
+ * the error.
+ */
+ protected void logError(String message, Exception ex) {
+ SiriusPlugin.getDefault().error(message, ex);
+ }
+
+ /**
+ * Can be used to log a warning in the system log.
+ *
+ * @param message
+ * the message to log.
+ * @param ex
+ * the error.
+ */
+ protected void logWarning(String message, Exception ex) {
+ SiriusPlugin.getDefault().warning(message, ex);
+ }
+
+ /**
+ * Can be used when the exception occured inside an EMF Transaction to request all the changes previously made in
+ * the transaction to be rolled back. This throws an exception and thus should be the last method called from
+ * {@link #handleException(EObject, String, Exception)}.
+ *
+ * @param cause
+ * the root cause.
+ */
+ protected void requestTransactionRollback(Exception cause) {
+ RuntimeException cancel = new OperationCanceledException();
+ cancel.initCause(cause);
+ throw cancel;
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/tools/internal/interpreter/SessionInterpreter.java b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/tools/internal/interpreter/SessionInterpreter.java
index 674ce1559d..875d906017 100644
--- a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/tools/internal/interpreter/SessionInterpreter.java
+++ b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/tools/internal/interpreter/SessionInterpreter.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2010, 2016 THALES GLOBAL SERVICES and others.
+ * Copyright (c) 2010, 2017 THALES GLOBAL SERVICES 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
@@ -17,7 +17,9 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.concurrent.atomic.AtomicReference;
+import org.eclipse.emf.common.util.BasicDiagnostic;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.util.ECrossReferenceAdapter;
@@ -39,6 +41,8 @@ import org.eclipse.sirius.common.tools.api.profiler.ProfilerTask;
import org.eclipse.sirius.ecore.extender.business.api.accessor.MetamodelDescriptor;
import org.eclipse.sirius.ecore.extender.business.api.accessor.ModelAccessor;
import org.eclipse.sirius.tools.api.profiler.SiriusTasksKey;
+import org.eclipse.sirius.viewpoint.Messages;
+import org.eclipse.sirius.viewpoint.SiriusPlugin;
import com.google.common.collect.Sets;
@@ -56,8 +60,8 @@ public class SessionInterpreter implements IInterpreter, IProposalProvider, IInt
private Collection<String> dependencies = Sets.newLinkedHashSet();
/**
- * If Sirius knows of any additional metamodel that may be necessary for the
- * interpreter, they'll be registered here.
+ * If Sirius knows of any additional metamodel that may be necessary for the interpreter, they'll be registered
+ * here.
*/
private Collection<MetamodelDescriptor> additionalMetamodels = Sets.newLinkedHashSet();
@@ -79,6 +83,26 @@ public class SessionInterpreter implements IInterpreter, IProposalProvider, IInt
/** The profiler tasks. */
private final Map<String, ProfilerTask> profilerTasks = new HashMap<String, ProfilerTask>();
+ private AtomicReference<EvaluationErrorHandler> evaluationErrorHandler = new AtomicReference<>(EvaluationErrorHandler.IGNORE);
+
+ /**
+ * Executes some code in a context where interpreted expression errors are handled by the given
+ * EvaluationErrorHandler.
+ *
+ * @param handler
+ * the handler for evaluation errors occuring while executing the code.
+ * @param body
+ * the code to execute.
+ */
+ public void withErrorHandler(EvaluationErrorHandler handler, Runnable body) {
+ EvaluationErrorHandler old = this.evaluationErrorHandler.getAndSet(handler);
+ try {
+ body.run();
+ } finally {
+ this.evaluationErrorHandler.compareAndSet(handler, old);
+ }
+ }
+
@Override
public void activateMetamodels(Collection<MetamodelDescriptor> metamodels) {
this.additionalMetamodels.addAll(metamodels);
@@ -120,74 +144,158 @@ public class SessionInterpreter implements IInterpreter, IProposalProvider, IInt
@Override
public IEvaluationResult evaluateExpression(final EObject target, final String expression) throws EvaluationException {
final IInterpreter interpreter = getInterpreter(expression);
- if (interpreter instanceof IInterpreterWithDiagnostic) {
- return ((IInterpreterWithDiagnostic) interpreter).evaluateExpression(target, expression);
+ IEvaluationResult result = null;
+ try {
+ if (interpreter instanceof IInterpreterWithDiagnostic) {
+ result = ((IInterpreterWithDiagnostic) interpreter).evaluateExpression(target, expression);
+ } else {
+ // Fall back on the default behavior otherwise with an OK diagnostic
+ final Object value = interpreter.evaluate(target, expression);
+ result = new IEvaluationResult() {
+ @Override
+ public Object getValue() {
+ return value;
+ }
+
+ @Override
+ public Diagnostic getDiagnostic() {
+ return Diagnostic.OK_INSTANCE;
+ }
+ };
+ }
+ } catch (EvaluationException evx) {
+ this.evaluationErrorHandler.get().handleException(evx);
+ result = creatErrorResult(evx);
+ // CHECKSTYLE:OFF
+ } catch (RuntimeException rex) {
+ // CHECKSTYLE:ON
+ this.evaluationErrorHandler.get().handleException(rex);
+ result = creatErrorResult(rex);
}
+ return result;
+ }
- // Fall back on the default behavior otherwise with an OK diagnostic
- final Object result = interpreter.evaluate(target, expression);
-
- IEvaluationResult evaluationResult = new IEvaluationResult() {
+ private IEvaluationResult creatErrorResult(Exception ex) {
+ final BasicDiagnostic diag = new BasicDiagnostic(Diagnostic.ERROR, SiriusPlugin.ID, 0, Messages.SessionInterpreter_evaluationError, new Object[] { ex });
+ return new IEvaluationResult() {
@Override
public Object getValue() {
- return result;
+ return null;
}
-
@Override
public Diagnostic getDiagnostic() {
- return Diagnostic.OK_INSTANCE;
+ return diag;
}
};
-
- return evaluationResult;
}
@Override
public Object evaluate(final EObject target, final String expression) throws EvaluationException {
- preEvaluation(expression);
- final Object evaluate = getInterpreter(expression).evaluate(target, expression);
- postEvaluation(expression);
- return evaluate;
+ try {
+ preEvaluation(expression);
+ final Object evaluate = getInterpreter(expression).evaluate(target, expression);
+ postEvaluation(expression);
+ return evaluate;
+ } catch (EvaluationException evx) {
+ this.evaluationErrorHandler.get().handleException(evx);
+ throw evx;
+ // CHECKSTYLE:OFF
+ } catch (RuntimeException rex) {
+ // CHECKSTYLE:ON
+ this.evaluationErrorHandler.get().handleException(rex);
+ throw rex;
+ }
}
@Override
public boolean evaluateBoolean(final EObject context, final String expression) throws EvaluationException {
- preEvaluation(expression);
- final boolean evaluateBoolean = getInterpreter(expression).evaluateBoolean(context, expression);
- postEvaluation(expression);
- return evaluateBoolean;
+ try {
+ preEvaluation(expression);
+ final boolean evaluateBoolean = getInterpreter(expression).evaluateBoolean(context, expression);
+ postEvaluation(expression);
+ return evaluateBoolean;
+ } catch (EvaluationException evx) {
+ this.evaluationErrorHandler.get().handleException(evx);
+ throw evx;
+ // CHECKSTYLE:OFF
+ } catch (RuntimeException rex) {
+ // CHECKSTYLE:ON
+ this.evaluationErrorHandler.get().handleException(rex);
+ throw rex;
+ }
+
}
@Override
public Collection<EObject> evaluateCollection(final EObject context, final String expression) throws EvaluationException {
- preEvaluation(expression);
- final Collection<EObject> evaluateCollection = getInterpreter(expression).evaluateCollection(context, expression);
- postEvaluation(expression);
- return evaluateCollection;
+ try {
+ preEvaluation(expression);
+ final Collection<EObject> evaluateCollection = getInterpreter(expression).evaluateCollection(context, expression);
+ postEvaluation(expression);
+ return evaluateCollection;
+ } catch (EvaluationException evx) {
+ this.evaluationErrorHandler.get().handleException(evx);
+ throw evx;
+ // CHECKSTYLE:OFF
+ } catch (RuntimeException rex) {
+ // CHECKSTYLE:ON
+ this.evaluationErrorHandler.get().handleException(rex);
+ throw rex;
+ }
}
@Override
public EObject evaluateEObject(final EObject context, final String expression) throws EvaluationException {
- preEvaluation(expression);
- final EObject evaluateEObject = getInterpreter(expression).evaluateEObject(context, expression);
- postEvaluation(expression);
- return evaluateEObject;
+ try {
+ preEvaluation(expression);
+ final EObject evaluateEObject = getInterpreter(expression).evaluateEObject(context, expression);
+ postEvaluation(expression);
+ return evaluateEObject;
+ } catch (EvaluationException evx) {
+ this.evaluationErrorHandler.get().handleException(evx);
+ throw evx;
+ // CHECKSTYLE:OFF
+ } catch (RuntimeException rex) {
+ // CHECKSTYLE:ON
+ this.evaluationErrorHandler.get().handleException(rex);
+ throw rex;
+ }
}
@Override
public Integer evaluateInteger(final EObject context, final String expression) throws EvaluationException {
- preEvaluation(expression);
- final Integer evaluateInteger = getInterpreter(expression).evaluateInteger(context, expression);
- postEvaluation(expression);
- return evaluateInteger;
+ try {
+ preEvaluation(expression);
+ final Integer evaluateInteger = getInterpreter(expression).evaluateInteger(context, expression);
+ postEvaluation(expression);
+ return evaluateInteger;
+ } catch (EvaluationException evx) {
+ this.evaluationErrorHandler.get().handleException(evx);
+ throw evx;
+ // CHECKSTYLE:OFF
+ } catch (RuntimeException rex) {
+ // CHECKSTYLE:ON
+ this.evaluationErrorHandler.get().handleException(rex);
+ throw rex;
+ }
}
@Override
public String evaluateString(final EObject context, final String expression) throws EvaluationException {
- preEvaluation(expression);
- final String evaluateString = getInterpreter(expression).evaluateString(context, expression);
- postEvaluation(expression);
- return evaluateString;
+ try {
+ preEvaluation(expression);
+ String evaluateString = getInterpreter(expression).evaluateString(context, expression);
+ postEvaluation(expression);
+ return evaluateString;
+ } catch (EvaluationException evx) {
+ this.evaluationErrorHandler.get().handleException(evx);
+ throw evx;
+ // CHECKSTYLE:OFF
+ } catch (RuntimeException rex) {
+ // CHECKSTYLE:ON
+ this.evaluationErrorHandler.get().handleException(rex);
+ throw rex;
+ }
}
@Override
@@ -393,5 +501,4 @@ public class SessionInterpreter implements IInterpreter, IProposalProvider, IInt
}
}
}
-
}
diff --git a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/viewpoint/Messages.java b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/viewpoint/Messages.java
index 116716945c..6cecb0d926 100644
--- a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/viewpoint/Messages.java
+++ b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/viewpoint/Messages.java
@@ -497,6 +497,9 @@ public final class Messages {
@TranslatableMessage
public static String SessionFactoryImpl_sessionLoadingMsg;
+
+ @TranslatableMessage
+ public static String SessionInterpreter_evaluationError;
@TranslatableMessage
public static String SessionManagerImpl_remoteServerConnectionErrorMsg;

Back to the top