blob: 51799a3c692b1267bd00b142111d611f387765bb [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2013 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
* Zeligsoft - Bug 237205
* Patrick Könemann - Bug 294200 (history)
* E.D.Willink - rework of LPG OCL Console for Xtext
*******************************************************************************/
package org.eclipse.ocl.examples.xtext.console;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.TextViewer;
import org.eclipse.jface.text.contentassist.ContentAssistant;
import org.eclipse.jface.text.contentassist.IContentAssistant;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.ocl.examples.debug.vm.core.VMVariable;
import org.eclipse.ocl.examples.debug.vm.data.VMVariableData;
import org.eclipse.ocl.examples.domain.elements.DomainType;
import org.eclipse.ocl.examples.domain.evaluation.DomainLogger;
import org.eclipse.ocl.examples.domain.evaluation.DomainModelManager;
import org.eclipse.ocl.examples.domain.evaluation.EvaluationHaltedException;
import org.eclipse.ocl.examples.domain.utilities.DomainUtil;
import org.eclipse.ocl.examples.domain.values.CollectionValue;
import org.eclipse.ocl.examples.domain.values.Value;
import org.eclipse.ocl.examples.domain.values.impl.InvalidValueException;
import org.eclipse.ocl.examples.domain.values.util.ValuesUtil;
import org.eclipse.ocl.examples.pivot.Element;
import org.eclipse.ocl.examples.pivot.Environment;
import org.eclipse.ocl.examples.pivot.EnvironmentFactory;
import org.eclipse.ocl.examples.pivot.ExpressionInOCL;
import org.eclipse.ocl.examples.pivot.ParserException;
import org.eclipse.ocl.examples.pivot.Type;
import org.eclipse.ocl.examples.pivot.context.ClassContext;
import org.eclipse.ocl.examples.pivot.context.ParserContext;
import org.eclipse.ocl.examples.pivot.evaluation.EvaluationEnvironment;
import org.eclipse.ocl.examples.pivot.evaluation.EvaluationVisitor;
import org.eclipse.ocl.examples.pivot.evaluation.EvaluationVisitorImpl;
import org.eclipse.ocl.examples.pivot.helper.OCLHelper;
import org.eclipse.ocl.examples.pivot.manager.MetaModelManager;
import org.eclipse.ocl.examples.pivot.manager.MetaModelManagerListener;
import org.eclipse.ocl.examples.pivot.manager.MetaModelManagerResourceSetAdapter;
import org.eclipse.ocl.examples.pivot.manager.PivotIdResolver;
import org.eclipse.ocl.examples.pivot.util.Pivotable;
import org.eclipse.ocl.examples.pivot.utilities.BaseResource;
import org.eclipse.ocl.examples.pivot.utilities.PivotEnvironment;
import org.eclipse.ocl.examples.pivot.utilities.PivotEnvironmentFactory;
import org.eclipse.ocl.examples.pivot.utilities.PivotUtil;
import org.eclipse.ocl.examples.xtext.base.ui.utilities.BaseUIUtil;
import org.eclipse.ocl.examples.xtext.base.utilities.BaseCSResource;
import org.eclipse.ocl.examples.xtext.base.utilities.CS2PivotResourceAdapter;
import org.eclipse.ocl.examples.xtext.console.actions.CloseAction;
import org.eclipse.ocl.examples.xtext.console.actions.DebugAction;
import org.eclipse.ocl.examples.xtext.console.actions.LoadExpressionAction;
import org.eclipse.ocl.examples.xtext.console.actions.SaveExpressionAction;
import org.eclipse.ocl.examples.xtext.console.messages.ConsoleMessages;
import org.eclipse.ocl.examples.xtext.console.xtfo.EmbeddedXtextEditor;
import org.eclipse.ocl.examples.xtext.essentialocl.ui.model.BaseDocument;
import org.eclipse.ocl.examples.xtext.essentialocl.utilities.EssentialOCLCSResource;
import org.eclipse.ocl.examples.xtext.essentialocl.utilities.EssentialOCLPlugin;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.VerifyKeyListener;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.graphics.FontMetrics;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.ISelectionService;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.console.IConsole;
import org.eclipse.ui.console.IConsoleConstants;
import org.eclipse.ui.console.IConsoleView;
import org.eclipse.ui.console.actions.ClearOutputAction;
import org.eclipse.ui.part.IPage;
import org.eclipse.ui.part.Page;
import org.eclipse.ui.progress.IProgressService;
import org.eclipse.ui.views.contentoutline.ContentOutline;
import org.eclipse.xtext.resource.XtextResource;
import org.eclipse.xtext.ui.editor.contentassist.DefaultContentAssistantFactory;
import org.eclipse.xtext.ui.editor.model.IXtextDocument;
import org.eclipse.xtext.ui.editor.outline.impl.EObjectNode;
import org.eclipse.xtext.ui.editor.outline.impl.OutlinePage;
import org.eclipse.xtext.util.concurrent.IUnitOfWork;
import com.google.inject.Injector;
/**
* The page implementing the Interactive OCL console.
*/
public class OCLConsolePage extends Page implements MetaModelManagerListener
{
/**
* CancelableEvaluationVisitor refines the EvaluationVisitor to poll the monitor for cancellation at a variety of significant
* evaluation events, such as feature visits and {@link #createNestedEvaluator()}.
*/
protected static class CancelableEvaluationVisitor extends EvaluationVisitorImpl
{
private final @NonNull IProgressMonitor monitor;
protected CancelableEvaluationVisitor(@NonNull IProgressMonitor monitor, @NonNull Environment env, @NonNull EvaluationEnvironment evalEnv, @NonNull DomainModelManager modelManager) {
super(env, evalEnv, modelManager);
this.monitor = monitor;
}
@Override
public @NonNull EvaluationVisitor createNestedEvaluator() {
EnvironmentFactory factory = environment.getFactory();
EvaluationEnvironment nestedEvalEnv = factory.createEvaluationEnvironment(evaluationEnvironment);
CancelableEvaluationVisitor nestedVisitor = new CancelableEvaluationVisitor(monitor, environment, nestedEvalEnv, modelManager);
nestedVisitor.setLogger(getLogger());
return nestedVisitor;
}
}
public static enum ColorChoices
{
DEFAULT,
ERROR
}
public static class InterrogatableContentAssistantFactory extends DefaultContentAssistantFactory
{
@Override
protected ContentAssistant createAssistant() {
return new InterrogatableContentAssistant();
}
}
public static final class InterrogatableContentAssistant extends ContentAssistant
{
@Override
public boolean isProposalPopupActive() {
return super.isProposalPopupActive();
}
}
private class EvaluationRunnable implements IRunnableWithProgress
{
private final @NonNull BaseResource resource;
private final @NonNull String expression;
private Object value = null;
public EvaluationRunnable(@NonNull BaseResource resource, @NonNull String expression) {
this.resource = resource;
this.expression = expression;
}
public Object getValue() {
return value;
}
public void run(final IProgressMonitor monitor) {
monitor.beginTask(NLS.bind(ConsoleMessages.Progress_Title, expression), 10);
monitor.subTask(ConsoleMessages.Progress_Synchronising);
monitor.worked(1);
// CS2PivotResourceAdapter csAdapter = CS2PivotResourceAdapter.getAdapter((BaseCSResource)resource, metaModelManager);
MetaModelManager metaModelManager = getMetaModelManager(contextObject);
// monitor.subTask(ConsoleMessages.Progress_CST);
// try {
// csAdapter.refreshPivotMappings();
// } catch (Exception e) {
// value = new ExceptionValue(valueFactory, ConsoleMessages.Result_MappingFailure, e);
// return;
// }
// monitor.worked(2);
// monitor.subTask(ConsoleMessages.Progress_AST);
ExpressionInOCL expressionInOCL;
try {
PivotUtil.checkResourceErrors("", resource); //$NON-NLS-1$
expressionInOCL = parserContext.getExpression(resource);
} catch (ParserException e) {
value = new InvalidValueException(e, ConsoleMessages.Result_ParsingFailure);
return;
}
if (expressionInOCL != null) {
// monitor.worked(2);
monitor.subTask(ConsoleMessages.Progress_Extent);
PivotEnvironmentFactory envFactory = new PivotEnvironmentFactory(null, metaModelManager);
PivotEnvironment environment = envFactory.createEnvironment();
EvaluationEnvironment evaluationEnvironment = envFactory.createEvaluationEnvironment();
Object contextValue = metaModelManager.getIdResolver().boxedValueOf(contextObject);
evaluationEnvironment.add(DomainUtil.nonNullModel(expressionInOCL.getContextVariable()), contextValue);
// if (modelManager == null) {
// let the evaluation environment create one
@NonNull DomainModelManager modelManager2 = modelManager = evaluationEnvironment.createModelManager(contextObject);
// }
monitor.worked(2);
monitor.subTask(ConsoleMessages.Progress_Evaluating);
try {
// metaModelManager.setMonitor(monitor);
CancelableEvaluationVisitor evaluationVisitor = new CancelableEvaluationVisitor(monitor, environment, evaluationEnvironment, modelManager2);
evaluationVisitor.setLogger(new DomainLogger()
{
public void append(final @NonNull String message) {
OCLConsolePage.this.getControl().getDisplay().asyncExec(new Runnable()
{
public void run() {
OCLConsolePage.this.append(message, ColorManager.DEFAULT, false);
}
});
}
});
value = evaluationVisitor.visitExpressionInOCL(expressionInOCL);
} catch (EvaluationHaltedException e) {
value = new InvalidValueException(ConsoleMessages.Result_EvaluationTerminated);
} catch (InvalidValueException e) {
value = e;
} catch (Exception e) {
value = new InvalidValueException(e, ConsoleMessages.Result_EvaluationFailure);
} finally {
// metaModelManager.setMonitor(null);
}
}
monitor.worked(4);
}
}
/**
* A key listener that listens for the Enter key to evaluate the OCL
* expression.
*/
private class InputKeyListener implements KeyListener {
private boolean evaluationSuccess = false;
private List<String> history = new ArrayList<String>();
private int currentHistoryPointer = 0;
public void keyPressed(KeyEvent e) {
IContentAssistant contentAssistant = editor.getViewer().getContentAssistant();
if ((contentAssistant instanceof InterrogatableContentAssistant)
&& ((InterrogatableContentAssistant)contentAssistant).isProposalPopupActive()) {
return;
}
switch (e.keyCode) {
case SWT.CR :
if ((e.stateMask & (SWT.CTRL | SWT.SHIFT)) == 0) {
String text = getEditorDocument().get();
evaluationSuccess = evaluate(text.trim());
}
break;
case SWT.PAGE_UP :
if ((e.stateMask & (SWT.CTRL | SWT.SHIFT)) == 0) {
// history
if (currentHistoryPointer == 0 && history.size() > 0) {
if (history.size() > 0 && history.get(0).length() == 0) {
history.remove(0);
}
history.add(0, getEditorDocument().get().trim());
currentHistoryPointer = 1;
setTextFromHistory();
} else if (currentHistoryPointer < history.size() - 1) {
currentHistoryPointer++;
setTextFromHistory();
}
}
break;
case SWT.PAGE_DOWN :
if ((e.stateMask & (SWT.CTRL | SWT.SHIFT)) == 0) {
// history
if (currentHistoryPointer > 0) {
currentHistoryPointer--;
setTextFromHistory();
}
}
break;
}
}
public void keyReleased(KeyEvent e) {
switch (e.keyCode) {
case SWT.CR :
if ((e.stateMask & (SWT.CTRL | SWT.SHIFT)) == 0) {
if (evaluationSuccess) {
getEditorDocument().set(""); //$NON-NLS-1$
// history
if (history.size() > 0 && history.get(0).trim().length() == 0) {
history.remove(0);
}
if (history.size() == 0 || !history.get(0).equals(lastOCLExpression.trim())) {
history.add(0, lastOCLExpression.trim());
}
currentHistoryPointer = 0;
}
evaluationSuccess = false;
}
break;
// case ' ':
// if ((e.stateMask & SWT.CTRL) == SWT.CTRL) {
// input.getContentAssistant().showPossibleCompletions();
// }
}
}
protected void setTextFromHistory() {
String newText = history.get(currentHistoryPointer);
getEditorDocument().set(newText);
input.setSelectedRange(newText.length(), 0);
}
}
private final OCLConsole console;
private Composite page;
private ITextViewer output;
private ColorManager colorManager;
private SourceViewer input;
private EmbeddedXtextEditor editor;
private String lastOCLExpression;
private DebugAction debugAction;
private ISelectionService selectionService;
private ISelectionListener selectionListener;
private EObject contextObject;
private ParserContext parserContext;
// private final CancelableMetaModelManager metaModelManager;
private MetaModelManager nullMetaModelManager = null;
private DomainModelManager modelManager = null;
// private Map<TargetMetamodel, IAction> metamodelActions =
// new java.util.HashMap<TargetMetamodel, IAction>();
// private static final AdapterFactory reflectiveAdapterFactory =
// new ReflectiveItemProviderAdapterFactory();
// private static final AdapterFactory defaultAdapterFactory =
// new ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE);
/* public IItemLabelProvider tupleTypeLabelProvider = new IItemLabelProvider() {
public Object getImage(Object object) {
return null;
}
public String getText(Object object) {
@SuppressWarnings("unchecked")
TupleValue tuple = (TupleValue) object;
TupleType tupleType = tuple.getTupleType();
StringBuilder result = new StringBuilder();
result.append("Tuple{");//$NON-NLS-1$
for (Iterator<?> iter = tupleType.oclProperties().iterator();
iter.hasNext();) {
Object next = iter.next();
result.append(oclFactory.getName(next));
result.append(" = "); //$NON-NLS-1$
result.append(OCLConsolePage.this.toString(tuple.getValue(next)));
if (iter.hasNext()) {
result.append(", "); //$NON-NLS-1$
}
}
result.append('}');
return result.toString();
}}; */
/**
* Initializes me.
* @param console
*/
protected OCLConsolePage(OCLConsole console) {
super();
// this.metaModelManager = new CancelableMetaModelManager();
this.console = console;
}
/**
* Adds actions for the available target metamodels to the action bars.
*
* @param metamodelMenu the console's drop-down action bar menu
* @param metamodelAction the console's drop-down tool bar button
*
private void addMetamodelActions(IMenuManager metamodelMenu,
DropDownAction metamodelAction) {
IAction ecore = new EcoreMetamodelAction();
ecore.setChecked(true);
ImageDescriptor img = getImage(EcoreFactory.eINSTANCE.getEPackage());
if (img != null) {
ecore.setImageDescriptor(img);
}
metamodelMenu.add(ecore);
metamodelAction.addAction(ecore);
metamodelActions.put(TargetMetamodel.Ecore, ecore);
Bundle umlBundle = Platform.getBundle("org.eclipse.uml2.uml"); //$NON-NLS-1$
if ((umlBundle != null) && isAvailable(umlBundle)) {
IAction uml = new UMLMetamodelAction();
img = getImage(UMLFactory.eINSTANCE.createModel());
if (img != null) {
uml.setImageDescriptor(img);
}
metamodelMenu.add(uml);
metamodelAction.addAction(uml);
metamodelActions.put(TargetMetamodel.UML, uml);
}
} */
/**
* Appends the specified text to the output viewer.
*
* @param text the text to append
* @param rgb the color to print the text with
* @param bold whether to print the text bold
*/
protected void append(String text, RGB rgb, boolean bold) {
IDocument doc = getDocument();
try {
int offset = doc.getLength();
text = (text != null ? text : "") + '\n';
int length = text.length();
if (offset > 0) {
doc.replace(offset, 0, text);
} else {
doc.set(text);
}
StyleRange style = new StyleRange();
style.start = offset;
style.length = length;
style.foreground = colorManager.getColor(rgb);
if (bold) {
style.fontStyle = SWT.BOLD;
}
output.getTextWidget().setStyleRange(style);
} catch (BadLocationException e) {
IStatus status = new Status(IStatus.ERROR, XtextConsolePlugin.getPluginId(),
1, ConsoleMessages.Output_Exception, e);
XtextConsolePlugin.getInstance().getLog().log(status);
}
}
@Override
public void createControl(Composite parent) {
// force left-to-right text direction in the console, because it
// works with OCL text and the OCL language is based on English
page = new SashForm(parent, SWT.VERTICAL | SWT.LEFT_TO_RIGHT);
output = new TextViewer(page, SWT.BORDER | SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL);
output.getTextWidget().setLayoutData(new GridData(GridData.FILL_BOTH));
output.getTextWidget().setFont(JFaceResources.getFont(JFaceResources.TEXT_FONT));
output.setEditable(false);
output.setDocument(new Document());
colorManager = new ColorManager();
// document.setOCLFactory(oclFactory);
// document.setModelingLevel(modelingLevel);
createEditor(page);
input = editor.getViewer();
input.getTextWidget().addKeyListener(new InputKeyListener());
input.getTextWidget().setFont(JFaceResources.getFont(JFaceResources.TEXT_FONT));
selectionListener = new ISelectionListener() {
public void selectionChanged(IWorkbenchPart part, final ISelection selection) {
// System.out.println("selectionChanged: ");
if (part instanceof IConsoleView) {
IConsole console = ((IConsoleView)part).getConsole();
if (console instanceof OCLConsole) {
return;
}
}
if (part instanceof ContentOutline) {
ContentOutline contentOutline = (ContentOutline)part;
IPage currentPage = contentOutline.getCurrentPage();
if (currentPage instanceof OutlinePage) {
OutlinePage outlinePage = (OutlinePage)currentPage;
IXtextDocument xtextDocument = outlinePage.getXtextDocument();
Element pivotElement = xtextDocument.readOnly(new IUnitOfWork<Element, XtextResource>()
{
public Element exec(@Nullable XtextResource state) throws Exception {
if ((state != null) && (selection instanceof IStructuredSelection)) {
IStructuredSelection structuredSelection = (IStructuredSelection) selection;
if (structuredSelection.size() == 1) {
Object selectedObject = structuredSelection.getFirstElement();
if (selectedObject instanceof EObjectNode) {
EObjectNode eObjectNode = (EObjectNode)selectedObject;
URI uri = eObjectNode.getEObjectURI();
EObject csObject = state.getEObject(uri.fragment());
if (csObject instanceof Pivotable) {
Element pivotObject = ((Pivotable)csObject).getPivot();
if (pivotObject != null) {
return pivotObject;
}
}
}
}
}
return null;
}
});
if (pivotElement != null) {
OCLConsolePage.this.selectionChanged(new StructuredSelection(pivotElement));
return;
}
}
}
OCLConsolePage.this.selectionChanged(selection);
}};
selectionService = getSite().getWorkbenchWindow().getSelectionService();
selectionService.addPostSelectionListener(selectionListener);
// get current selection
// ISelection selection = selectionService.getSelection(); // Doesn't have a value preceding console start
ISelection selection = BaseUIUtil.getActiveSelection(getSite());
selectionChanged(selection);
((SashForm) page).setWeights(new int[] {2, 1});
ClearOutputAction clear = new ClearOutputAction(output);
CloseAction close = new CloseAction();
SaveExpressionAction saveExpression = new SaveExpressionAction(this);
LoadExpressionAction loadExpression = new LoadExpressionAction(this);
debugAction = new DebugAction(this);
IMenuManager menu = getSite().getActionBars().getMenuManager();
menu.add(loadExpression);
menu.add(saveExpression);
menu.add(clear);
menu.add(close);
menu.add(debugAction);
// IMenuManager metamodelMenu = new MenuManager(
// OCLInterpreterMessages.console_metamodelMenu,
// "org.eclipse.ocl.examples.xtext.console.metamodel"); //$NON-NLS-1$
// menu.add(metamodelMenu);
// DropDownAction metamodelAction = new DropDownAction();
// metamodelAction.setToolTipText(OCLInterpreterMessages.console_metamodelTip);
// addMetamodelActions(metamodelMenu, metamodelAction);
// IMenuManager levelMenu = new MenuManager(OCLInterpreterMessages.console_modelingLevel);
// menu.add(levelMenu);
// DropDownAction levelAction = new DropDownAction();
// levelAction.setToolTipText(OCLInterpreterMessages.console_modelingLevelTip);
// IAction m2 = new ModelingLevelAction(ModelingLevel.M2);
// m2.setChecked(true);
// levelMenu.add(m2);
// levelAction.addAction(m2);
// IAction m1 = new ModelingLevelAction(ModelingLevel.M1);
// levelMenu.add(m1);
// levelAction.addAction(m1);
// ActionContributionItem metamodelItem = new ActionContributionItem(
// metamodelAction);
// metamodelItem.setMode(ActionContributionItem.MODE_FORCE_TEXT);
IToolBarManager toolbar = getSite().getActionBars().getToolBarManager();
// toolbar.appendToGroup(IConsoleConstants.OUTPUT_GROUP, metamodelItem);
// toolbar.appendToGroup(IConsoleConstants.OUTPUT_GROUP, levelAction);
toolbar.appendToGroup(IConsoleConstants.OUTPUT_GROUP, loadExpression);
toolbar.appendToGroup(IConsoleConstants.OUTPUT_GROUP, saveExpression);
toolbar.appendToGroup(IConsoleConstants.OUTPUT_GROUP, clear);
toolbar.appendToGroup(IConsoleConstants.OUTPUT_GROUP, close);
toolbar.appendToGroup(IConsoleConstants.OUTPUT_GROUP, debugAction);
}
private int convertHeightInCharsToPixels(int i) {
// Create a GC to calculate font's dimensions
GC gc = new GC(Display.getDefault());
gc.setFont(editor.getViewer().getTextWidget().getFont());
// Determine string's dimensions
FontMetrics fontMetrics = gc.getFontMetrics();
int ret = (fontMetrics.getHeight() + fontMetrics.getAscent() + fontMetrics.getDescent() + fontMetrics.getLeading()) * i;
// Dispose that gc
gc.dispose();
return ret;
}
private void createEditor(Composite s1) {
Composite client = s1; //new Composite(s1, SWT.NULL);
Injector injector = XtextConsolePlugin.getInstance().getInjector(EssentialOCLPlugin.LANGUAGE_ID);
Composite editorComposite = client; //new Composite(client, SWT.NULL);
editor = new EmbeddedXtextEditor(editorComposite, injector, /*SWT.BORDER |*/ SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL);
// MetaModelManagerResourceSetAdapter.getAdapter(editor.getResourceSet(), metaModelManager);
/* editor.getViewer().getTextWidget().addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent e) {
String text = editor.getViewer().getTextWidget().getText();
System.out.println("modifyText: " + text);
// if (!text.equals(getEditedEObject().getAsString())) {
// getEditor().setDirty(true);
// getEditor().firePropertyChange(IEditorPart.PROP_DIRTY);
// } else {
// getEditor().setDirty(false);
// getEditor().firePropertyChange(IEditorPart.PROP_DIRTY);
// }
}
}); */
/* editor.getDocument().addModelListener(new IXtextModelListener() {
public void modelChanged(XtextResource resource) {
System.out.println("modelChanged: " + resource);
// reconcileChangedModel();
}
}); */
editor.getViewer().getTextWidget().addVerifyKeyListener(new VerifyKeyListener() {
public void verifyKey(VerifyEvent e) {
// System.out.println("verifyKey: " + e.keyCode);
if (e.keyCode == SWT.KEYPAD_CR || e.keyCode == SWT.CR) {
if ((e.stateMask & (SWT.CTRL | SWT.SHIFT)) == 0) {
e.doit = false;
}
}
}
});
GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
data.heightHint= convertHeightInCharsToPixels(1);
editorComposite.setLayoutData(data);
}
/**
* Extends the inherited method to dispose of additional colour resources.
*/
@Override
public void dispose() {
colorManager.dispose();
selectionService.removePostSelectionListener(selectionListener);
reset();
super.dispose();
}
/**
* Prints an error message to the output viewer, in red text.
*
* @param message the error message to print
*/
private void error(String message) {
append(message, ColorManager.OUTPUT_ERROR, false);
scrollText();
}
/**
* Evaluates an OCL expression using the OCL Interpreter's {@link OCLHelper}
* API.
*
* @param expression an OCL expression
*
* @return <code>true</code> on successful evaluation; <code>false</code>
* if the expression failed to parse or evaluate
*/
protected boolean evaluate(final String expression) {
// if (contextObject == null) {
// error(OCLInterpreterMessages.console_noContext);
// return false;
// }
if ((expression == null) || (expression.trim().length() <= 0)) {
error(ConsoleMessages.Result_NoExpression);
return false;
}
// editorDocument.getResource();
// create an OCL helper to do our parsing and evaluating
// ocl = oclFactory.createOCL(modelingLevel);
// OCLHelper helper = ocl.createOCLHelper();
boolean result = true;
try {
// set our helper's context classifier to parse against it
// ConstraintKind kind = modelingLevel.setContext(helper, context, oclFactory);
IDocument doc = getDocument();
if (doc.getLength() > 0) {
// separate previous output by a blank line
append("", ColorManager.DEFAULT, false); //$NON-NLS-1$
}
append(ConsoleMessages.Heading_Evaluating, ColorManager.DEFAULT, true);
append(expression, ColorManager.DEFAULT, false);
append(ConsoleMessages.Heading_Results, ColorManager.DEFAULT, true);
final BaseDocument editorDocument = getEditorDocument();
Object value = null;
try {
value = editorDocument.readOnly(new IUnitOfWork<Object, XtextResource>() {
public Object exec(@Nullable XtextResource state) throws Exception {
if (state != null) {
IProgressService progressService = PlatformUI.getWorkbench().getProgressService();
EvaluationRunnable runnable = new EvaluationRunnable((BaseResource) state, expression);
progressService.busyCursorWhile(runnable);
return runnable.getValue();
}
else {
return null;
}
}});
}
catch (Exception e) {
append(e.getMessage(), ColorManager.OUTPUT_ERROR, false);
}
if (value instanceof InvalidValueException) {
InvalidValueException exception = (InvalidValueException)value;
append(exception.getMessage(), ColorManager.OUTPUT_ERROR, true);
Throwable cause = exception.getCause();
if ((cause != null) && (cause != exception)) {
append(cause.getMessage(), ColorManager.OUTPUT_ERROR, false);
}
}
else if (value != null) {
CollectionValue collectionValue = ValuesUtil.isCollectionValue(value);
if (collectionValue != null) {
for (Object elementValue : collectionValue.iterable()) {
append(ValuesUtil.stringValueOf(elementValue), ColorManager.OUTPUT_RESULTS, false);
}
}
else {
append(ValuesUtil.stringValueOf(value), ColorManager.OUTPUT_RESULTS, false);
}
}
else {
append(ValuesUtil.stringValueOf(value), ColorManager.OUTPUT_ERROR, false);
}
scrollText();
// store the successfully parsed expression
lastOCLExpression = expression;
} catch (Exception e) {
result = false;
error((e.getLocalizedMessage() == null) ? e.getClass().getName()
: e.getLocalizedMessage());
}
return result;
}
protected void flushEvents() {
IWorkbench workbench = PlatformUI.getWorkbench();
while (workbench.getDisplay().readAndDispatch());
}
public EObject getContextObject() {
return contextObject;
}
@Override
public Control getControl() {
return page;
}
/**
* Obtains the document in the output viewer.
*
* @return the output document
*/
private IDocument getDocument() {
return output.getDocument();
}
public IXtextDocument getDocument(URI trimFragment) {
return getEditorDocument();
}
public BaseDocument getEditorDocument() {
return (BaseDocument) editor.getDocument();
}
public String getLastOCLExpression() {
return lastOCLExpression;
}
public @NonNull MetaModelManager getMetaModelManager(@Nullable EObject contextObject) {
MetaModelManager metaModelManager = contextObject != null ? PivotUtil.findMetaModelManager(contextObject) : null;
if (metaModelManager != null) {
return metaModelManager;
}
MetaModelManager nullMetaModelManager2 = nullMetaModelManager;
if (nullMetaModelManager2 == null) {
nullMetaModelManager2 = nullMetaModelManager = new MetaModelManager();
nullMetaModelManager2.addListener(this);
}
return nullMetaModelManager2;
}
protected ILaunch internalLaunchDebugger() {
return debugAction.launch();
}
public void metaModelManagerDisposed(@NonNull MetaModelManager metaModelManager) {
metaModelManager.removeListener(this);
reset();
}
protected void refreshSelection(final Object selected) {
final BaseDocument editorDocument = getEditorDocument();
editorDocument.modify(new IUnitOfWork<Object, XtextResource>()
{
public Value exec(@Nullable XtextResource resource) throws Exception {
Object selectedObject = selected;
if (selectedObject instanceof IAdaptable) {
Object adapted = ((IAdaptable) selectedObject).getAdapter(EObject.class);
if (adapted != null){
selectedObject = adapted;
}
}
/*if (selectedObject instanceof org.eclipse.uml2.uml.Element) {
org.eclipse.uml2.uml.Element selectedElement = (org.eclipse.uml2.uml.Element)selectedObject;
MetaModelManager metaModelManager = getMetaModelManager(selectedElement);
contextObject = metaModelManager.getPivotOf(Element.class, selectedElement);
}
else*/ if (selectedObject instanceof EObject) {
contextObject = (EObject) selectedObject;
}
else { // FIXME else Value in particular CollectionValue
contextObject = null;
}
if (resource instanceof BaseCSResource) {
CS2PivotResourceAdapter cs2PivotAdapter = ((BaseCSResource)resource).findCS2ASAdapter();
if (cs2PivotAdapter != null) {
cs2PivotAdapter.dispose();
}
}
MetaModelManager metaModelManager = getMetaModelManager(contextObject);
PivotIdResolver idResolver = metaModelManager.getIdResolver();
// DomainType staticType = idResolver.getStaticTypeOf(selectedObject);
DomainType staticType = idResolver.getStaticTypeOf(contextObject);
Type contextType = metaModelManager.getType(staticType);
// if (contextType != null) {
parserContext = new ClassContext(metaModelManager, null, contextType);
// }
// else {
// parserContext = new ModelContext(metaModelManager, null);
// }
// parserContext = new EObjectContext(metaModelManager, null, contextObject);
EssentialOCLCSResource csResource = (EssentialOCLCSResource) resource;
if (csResource != null) {
if (contextObject != null) {
csResource.getCS2ASAdapter(metaModelManager);
}
ResourceSet resourceSet = editor.getResourceSet();
if (resourceSet != null) {
MetaModelManagerResourceSetAdapter.getAdapter(resourceSet, metaModelManager);
}
csResource.setParserContext(parserContext);
}
console.setSelection(contextObject);
return null;
}
});
}
public void reset() {
if (editor != null) {
IXtextDocument document = editor.getDocument();
MetaModelManager metaModelManager = document.modify(new IUnitOfWork<MetaModelManager, XtextResource>() { // Cancel validation
public MetaModelManager exec(@Nullable XtextResource state) throws Exception {
if (state == null) {
return null;
}
if (state instanceof BaseResource) {
((BaseResource)state).setParserContext(null);
}
return PivotUtil.findMetaModelManager(state);
}
});
flushEvents();
if (metaModelManager != null) {
metaModelManager.dispose();
}
}
if (modelManager != null) {
// modelManager.dispose();
modelManager = null;
}
if (nullMetaModelManager != null) {
nullMetaModelManager.dispose();
nullMetaModelManager = null;
}
parserContext = null;
contextObject = null;
}
protected void resetDocument() {
IDocument doc = getDocument();
doc.set(""); //$NON-NLS-1$
}
/**
* Ensures that the last text printed to the output viewer is shown.
*/
private void scrollText() {
output.revealRange(getDocument().getLength(), 0);
}
private void selectionChanged(ISelection sel) {
Object selectedObject = BaseUIUtil.getSelectedObject(sel, getSite());
if (selectedObject instanceof VMVariable) { // FIXME move to BaseUIUtil once additional dependency acceptable
VMVariableData vmVar = ((VMVariable)selectedObject).getVmVar();
if (vmVar != null) {
selectedObject = vmVar.valueObject;
}
}
refreshSelection(selectedObject);
}
@Override
public void setFocus() {
input.getTextWidget().setFocus();
}
/**
* Programmatically sets my target metamodel.
*
* @param metamodel the target metamodel
*
public void setTargetMetamodel(TargetMetamodel metamodel) {
IAction action = metamodelActions.get(metamodel);
if (action != null) {
// deselect the old one
metamodelActions.get(oclFactory.getTargetMetamodel()).setChecked(false);
action.run();
action.setChecked(true);
}
} */
/**
* Converts a single object to a string, according to the rules described
* for the {@link #print(Object, Color, boolean)} method.
*
* @param object the object to print (not a collection type)
* @return the string form of the <code>object</code>
*
* @see #print(Object, Color, boolean)
*
String toString(Object object) {
if (ocl.isInvalid(object)) {
return "OclInvalid"; //$NON-NLS-1$
} else if (object instanceof String) {
return "'" + object + "'"; //$NON-NLS-1$//$NON-NLS-2$
} else if (object instanceof TupleValue) {
return tupleTypeLabelProvider.getText(object);
} else if (object instanceof EObject) {
EObject eObject = (EObject) object;
IItemLabelProvider labeler =
(IItemLabelProvider) defaultAdapterFactory.adapt(
eObject,
IItemLabelProvider.class);
if (labeler == null) {
labeler = (IItemLabelProvider) reflectiveAdapterFactory.adapt(
eObject,
IItemLabelProvider.class);
}
if (labeler != null) {
return labeler.getText(object);
}
}
return String.valueOf(object);
} */
}