blob: b631344d19829556061064b1e40193baa579aadf [file] [log] [blame]
/**
* <copyright>
*
* Copyright (c) 2005,2011 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
*
* </copyright>
*
* $Id: OCLConsolePage.java,v 1.9 2011/05/07 17:18:05 ewillink Exp $
*/
package org.eclipse.ocl.examples.xtext.console;
import java.math.BigDecimal;
import java.math.BigInteger;
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.emf.common.util.URI;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jface.action.Action;
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.source.SourceViewer;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.ocl.examples.domain.evaluation.DomainModelManager;
import org.eclipse.ocl.examples.domain.evaluation.InvalidEvaluationException;
import org.eclipse.ocl.examples.domain.evaluation.InvalidValueException;
import org.eclipse.ocl.examples.domain.values.BooleanValue;
import org.eclipse.ocl.examples.domain.values.IntegerValue;
import org.eclipse.ocl.examples.domain.values.RealValue;
import org.eclipse.ocl.examples.domain.values.StringValue;
import org.eclipse.ocl.examples.domain.values.Value;
import org.eclipse.ocl.examples.domain.values.ValueFactory;
import org.eclipse.ocl.examples.domain.values.impl.InvalidValueImpl;
import org.eclipse.ocl.examples.pivot.AssociationClassCallExp;
import org.eclipse.ocl.examples.pivot.CollectionItem;
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.EvaluationHaltedException;
import org.eclipse.ocl.examples.pivot.ExpressionInOcl;
import org.eclipse.ocl.examples.pivot.IterateExp;
import org.eclipse.ocl.examples.pivot.IteratorExp;
import org.eclipse.ocl.examples.pivot.OperationCallExp;
import org.eclipse.ocl.examples.pivot.ParserException;
import org.eclipse.ocl.examples.pivot.PropertyCallExp;
import org.eclipse.ocl.examples.pivot.TupleLiteralPart;
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.evaluation.PivotEvaluationEnvironment;
import org.eclipse.ocl.examples.pivot.helper.OCLHelper;
import org.eclipse.ocl.examples.pivot.manager.MetaModelManager;
import org.eclipse.ocl.examples.pivot.manager.MetaModelManagerResourceSetAdapter;
import org.eclipse.ocl.examples.pivot.util.Pivotable;
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.pivot.values.PivotValueFactory;
import org.eclipse.ocl.examples.xtext.console.actions.CloseAction;
import org.eclipse.ocl.examples.xtext.console.actions.LoadExpressionAction;
import org.eclipse.ocl.examples.xtext.console.actions.LoadResourceAction;
import org.eclipse.ocl.examples.xtext.console.actions.SaveExpressionAction;
import org.eclipse.ocl.examples.xtext.console.actions.ValidateAction;
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.Color;
import org.eclipse.swt.graphics.FontMetrics;
import org.eclipse.swt.graphics.GC;
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.IEditorPart;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.ISelectionService;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchWindow;
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.IPageSite;
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.model.IXtextDocument;
import org.eclipse.xtext.ui.editor.outline.IOutlineNode;
import org.eclipse.xtext.ui.editor.outline.impl.EObjectNode;
import org.eclipse.xtext.ui.editor.outline.impl.EStructuralFeatureNode;
import org.eclipse.xtext.ui.editor.outline.impl.OutlinePage;
import org.eclipse.xtext.util.concurrent.IUnitOfWork;
import org.osgi.framework.Bundle;
import com.google.inject.Injector;
/**
* The page implementing the Interactive OCL console.
*/
public class OCLConsolePage extends Page
{
private static int BUNDLE_AVAILABLE = Bundle.RESOLVED | Bundle.ACTIVE | Bundle.STARTING;
/**
* Queries whether a bundle is available.
*
* @param bundle a bundle
* @return whether it is active or resolved
*/
static boolean isAvailable(Bundle bundle) {
return (bundle.getState() & BUNDLE_AVAILABLE) != 0;
}
/* private class DropDownAction extends Action implements IMenuCreator {
private Menu menu;
private List<IAction> actions = new java.util.ArrayList<IAction>();
private IPropertyChangeListener listener = new IPropertyChangeListener() {
public void propertyChange(PropertyChangeEvent event) {
if (IAction.CHECKED.equals(event.getProperty())) {
if (Boolean.TRUE.equals(event.getNewValue())) {
actionChecked((IAction) event.getSource());
}
}
}};
DropDownAction() {
super();
setMenuCreator(this);
}
public void addAction(IAction action) {
actions.add(action);
action.addPropertyChangeListener(listener);
if (action.isChecked()) {
actionChecked(action);
}
}
private void actionChecked(IAction action) {
setImageDescriptor(action.getImageDescriptor());
setText(action.getText());
}
public Menu getMenu(Control parent) {
if (menu == null) {
menu = new Menu(parent);
for (IAction action : actions) {
addAction(menu, action);
}
}
return menu;
}
private void addAction(Menu m, IAction action) {
ActionContributionItem contrib = new ActionContributionItem(action);
contrib.fill(m, -1);
}
public void dispose() {
if (menu != null) {
menu.dispose();
}
}
public Menu getMenu(Menu parent) {
return null;
}
} */
protected static class CancelableEvaluationVisitor extends EvaluationVisitorImpl
{
private final IProgressMonitor monitor;
protected CancelableEvaluationVisitor(IProgressMonitor monitor, Environment env, EvaluationEnvironment evalEnv, DomainModelManager modelManager) {
super(env, evalEnv, modelManager);
this.monitor = monitor;
}
protected void checkMonitor() {
if (monitor.isCanceled()) {
throw new EvaluationHaltedException("Manual termination"); //$NON-NLS-1$
}
}
@Override
public EvaluationVisitor createNestedVisitor() {
EnvironmentFactory factory = environment.getFactory();
EvaluationEnvironment nestedEvalEnv = factory.createEvaluationEnvironment(evaluationEnvironment);
return new CancelableEvaluationVisitor(monitor, environment, nestedEvalEnv, modelManager);
}
@Override
public Value visitAssociationClassCallExp(AssociationClassCallExp ae) {
checkMonitor();
return super.visitAssociationClassCallExp(ae);
}
@Override
public Value visitCollectionItem(CollectionItem item) {
checkMonitor();
return super.visitCollectionItem(item);
}
@Override
public Value visitIterateExp(IterateExp iterateExp) {
checkMonitor();
return super.visitIterateExp(iterateExp);
}
@Override
public Value visitIteratorExp(IteratorExp iteratorExp) {
checkMonitor();
return super.visitIteratorExp(iteratorExp);
}
@Override
public Value visitOperationCallExp(OperationCallExp operationCallExp) {
checkMonitor();
return super.visitOperationCallExp(operationCallExp);
}
@Override
public Value visitPropertyCallExp(PropertyCallExp propertyCallExp) {
checkMonitor();
return super.visitPropertyCallExp(propertyCallExp);
}
@Override
public Value visitTupleLiteralPart(TupleLiteralPart tp) {
checkMonitor();
return super.visitTupleLiteralPart(tp);
}
}
protected static class CancelableMetaModelManager extends MetaModelManager
{
private IProgressMonitor monitor = null;
private final ValueFactory valueFactory;
public CancelableMetaModelManager() {
this.valueFactory = new PivotValueFactory(this)
{
@Override
public BooleanValue booleanValueOf(boolean value) {
checkMonitor();
return super.booleanValueOf(value);
}
@Override
public IntegerValue integerValueOf(BigInteger value) {
checkMonitor();
return super.integerValueOf(value);
}
@Override
public IntegerValue integerValueOf(long value) {
checkMonitor();
return super.integerValueOf(value);
}
@Override
public IntegerValue integerValueOf(String aValue) throws InvalidValueException {
checkMonitor();
return super.integerValueOf(aValue);
}
@Override
public RealValue realValueOf(double value) {
checkMonitor();
return super.realValueOf(value);
}
@Override
public RealValue realValueOf(BigDecimal value) {
checkMonitor();
return super.realValueOf(value);
}
@Override
public RealValue realValueOf(IntegerValue integerValue) {
checkMonitor();
return super.realValueOf(integerValue);
}
@Override
public RealValue realValueOf(String aValue) throws InvalidValueException {
checkMonitor();
return super.realValueOf(aValue);
}
@Override
public StringValue stringValueOf(String value) {
checkMonitor();
return super.stringValueOf(value);
}
};
}
protected void checkMonitor() {
if ((monitor != null) && monitor.isCanceled()) {
throw new EvaluationHaltedException(ConsoleMessages.Result_EvaluationTerminated);
}
}
@Override
public ValueFactory getValueFactory() {
return valueFactory;
}
public void setMonitor(IProgressMonitor monitor) {
this.monitor = monitor;
}
}
protected static class ExceptionValue extends InvalidValueImpl
{
private final String message;
private final Exception exception;
protected ExceptionValue(ValueFactory valueFactory, String message, Exception exception) {
super(valueFactory);
this.message = message;
this.exception = exception;
}
public Exception getException() {
return exception;
}
public String getMessage() {
return message;
}
@Override
public String toString() {
StringBuilder s = new StringBuilder();
if (exception != null) {
// s.append(" : "); //$NON-NLS-1$
s.append(exception.getMessage());
}
return s.toString();
}
}
private class EvaluationRunnable implements IRunnableWithProgress
{
private final XtextResource resource;
private final String expression;
private Value value = null;
public EvaluationRunnable(XtextResource resource, String expression) {
this.resource = resource;
this.expression = expression;
}
public Value 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);
ValueFactory valueFactory = metaModelManager.getValueFactory();
// 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(null, resource);
expressionInOcl = PivotUtil.getExpressionInOcl(resource);
} catch (ParserException e) {
value = new ExceptionValue(valueFactory, ConsoleMessages.Result_ParsingFailure, e);
return;
}
// monitor.worked(2);
monitor.subTask(ConsoleMessages.Progress_Extent);
PivotEnvironmentFactory envFactory = new PivotEnvironmentFactory(null, metaModelManager);
PivotEnvironment environment = envFactory.createEnvironment();
PivotEvaluationEnvironment evaluationEnvironment = envFactory.createEvaluationEnvironment();
Value contextValue = valueFactory.valueOf(contextObject);
evaluationEnvironment.add(expressionInOcl.getContextVariable(), contextValue);
// if (modelManager == null) {
// let the evaluation environment create one
modelManager = evaluationEnvironment.createModelManager(contextObject);
// }
monitor.worked(2);
monitor.subTask(ConsoleMessages.Progress_Evaluating);
try {
metaModelManager.setMonitor(monitor);
EvaluationVisitor evaluationVisitor = new CancelableEvaluationVisitor(monitor, environment, evaluationEnvironment, modelManager);
value = evaluationVisitor.visitExpressionInOcl(expressionInOcl);
} catch (EvaluationHaltedException e) {
value = new ExceptionValue(valueFactory, ConsoleMessages.Result_EvaluationTerminated, null);
} catch (InvalidEvaluationException e) {
value = new ExceptionValue(valueFactory, ConsoleMessages.Result_EvaluationFailure, e);
} 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) {
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) == 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 ModelingLevel modelingLevel = ModelingLevel.M2;
private ITextViewer output;
private ColorManager colorManager;
private SourceViewer input;
private EmbeddedXtextEditor editor;
private String lastOCLExpression;
private ISelectionService selectionService;
private ISelectionListener selectionListener;
private EObject contextObject;
private EClassifier contextClassifier;
private final CancelableMetaModelManager metaModelManager;
private DomainModelManager modelManager = null;
private ValidateAction validateAction = 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 oclConsole
*/
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 color the color to print the text with
* @param bold whether to print the text bold
*/
private void append(String text, Color color, boolean bold) {
IDocument doc = getDocument();
try {
int offset = doc.getLength();
int length = text.length();
text = text + '\n';
if (offset > 0) {
doc.replace(offset, 0, text);
} else {
doc.set(text);
}
StyleRange style = new StyleRange();
style.start = offset;
style.length = length;
style.foreground = color;
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(XtextResource state) throws Exception {
if (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 = getActiveSelection();
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);
Action loadResource = new LoadResourceAction(this);
validateAction = new ValidateAction(this);
IMenuManager menu = getSite().getActionBars().getMenuManager();
menu.add(loadResource);
menu.add(validateAction);
menu.add(loadExpression);
menu.add(saveExpression);
menu.add(clear);
menu.add(close);
// 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, loadResource);
toolbar.appendToGroup(IConsoleConstants.OUTPUT_GROUP, validateAction);
toolbar.appendToGroup(IConsoleConstants.OUTPUT_GROUP, loadExpression);
toolbar.appendToGroup(IConsoleConstants.OUTPUT_GROUP, saveExpression);
toolbar.appendToGroup(IConsoleConstants.OUTPUT_GROUP, clear);
toolbar.appendToGroup(IConsoleConstants.OUTPUT_GROUP, close);
}
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) {
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);
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.getColor(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
*/
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();
Color defaultColor = colorManager.getColor(ColorManager.DEFAULT);
Color resultsColor = colorManager.getColor(ColorManager.OUTPUT_RESULTS);
Color errorColor = colorManager.getColor(ColorManager.OUTPUT_ERROR);
if (doc.getLength() > 0) {
// separate previous output by a blank line
append("", defaultColor, false); //$NON-NLS-1$
}
append(ConsoleMessages.Heading_Evaluating, defaultColor, true);
append(expression, defaultColor, false);
append(ConsoleMessages.Heading_Results, defaultColor, true);
switch (modelingLevel) {
case M2:
final BaseDocument editorDocument = getEditorDocument();
Value value = null;
try {
value = editorDocument.readOnly(new IUnitOfWork<Value, XtextResource>() {
public Value exec(XtextResource state) throws Exception {
IProgressService progressService = PlatformUI.getWorkbench().getProgressService();
EvaluationRunnable runnable = new EvaluationRunnable(state, expression);
progressService.busyCursorWhile(runnable);
return runnable.getValue();
}});
}
catch (Exception e) {
append(e.getMessage(), errorColor, false);
}
if (value instanceof ExceptionValue) {
append(((ExceptionValue)value).getMessage(), errorColor, true);
append(String.valueOf(value), errorColor, false);
}
else if ((value != null) && (value.isCollectionValue() != null)) {
for (Value elementValue : value.isCollectionValue()) {
append(String.valueOf(elementValue), resultsColor, false);
}
}
else if (value != null) {
append(String.valueOf(value), resultsColor, false);
}
else {
append(String.valueOf(value), errorColor, false);
}
scrollText();
break;
case M1:
// helper.createConstraint(kind, expression);
// just report a successful parse
append(ConsoleMessages.Result_Parsed, resultsColor, false);
scrollText();
break;
}
// store the successfully parsed expression
lastOCLExpression = expression;
} catch (Exception e) {
result = false;
error((e.getLocalizedMessage() == null) ? e.getClass().getName()
: e.getLocalizedMessage());
}
return result;
}
protected ISelection getActiveSelection() {
try {
IPageSite site = getSite();
if (site == null) {
return null;
}
IWorkbenchWindow workbenchWindow = site.getWorkbenchWindow();
if (workbenchWindow == null) {
return null;
}
IWorkbenchPage activePage = workbenchWindow.getActivePage();
if (activePage == null) {
return null;
}
IEditorPart activeEditor = activePage.getActiveEditor();
if (activeEditor == null) {
return null;
}
IEditorSite editorSite = activeEditor.getEditorSite();
if (editorSite == null) {
return null;
}
ISelectionProvider selectionProvider = editorSite.getSelectionProvider();
if (selectionProvider == null) {
return null;
}
return selectionProvider.getSelection();
}
catch (Exception e) {
return null;
}
}
@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();
}
/**
* Gets the editor image for the specified element.
*
* @param element a model element
*
* @return the corresponding image
*
private ImageDescriptor getImage(EObject element) {
ImageDescriptor result = null;
IItemLabelProvider provider = (IItemLabelProvider) new ComposedAdapterFactory(
ComposedAdapterFactory.Descriptor.Registry.INSTANCE).adapt(
element, IItemLabelProvider.class);
if (provider != null) {
Object image = provider.getImage(element);
if (image != null) {
result = ExtendedImageRegistry.INSTANCE.getImageDescriptor(image);
}
}
return result;
} */
public String getLastOCLExpression() {
return lastOCLExpression;
}
/**
* Prints the specified <code>object</code> to the output viewer. The
* object is converted to a string using the best matching EMF label
* provider adapter if it is an {@link EObject}; otherwise, just use
* {@link String#valueOf(java.lang.Object)} on it. If the
* <code>object</code> is a collection or an array, then we print each
* element on a separate line.
*
* @param object the object or collection to print
* @param color the color to print the <code>object</code> with
* @param bold whether to display it in bold text
*
private void print(Value value, Color color, boolean bold) {
CollectionValue collectionValue = value.isCollectionValue();
if (collectionValue != null) {
for (Value elementValue : collectionValue) {
append(String.valueOf(elementValue), color, bold);
}
}
else {
append(String.valueOf(value), color, bold);
}
/* Collection<?> toPrint;
if (object == null) {
toPrint = Collections.EMPTY_SET;
} else if (object instanceof Collection) {
toPrint = (Collection<?>) object;
} else if (object.getClass().isArray()) {
toPrint = Arrays.asList((Object[]) object);
} else {
toPrint = Collections.singleton(object);
}
for (Iterator<?> iter = toPrint.iterator(); iter.hasNext();) {
append(toString(iter.next()), color, bold);
} * /
// append(String.valueOf(object), color, bold);
scrollText();
} */
protected void refreshSelection(final Object selected) {
final BaseDocument editorDocument = getEditorDocument();
editorDocument.modify(new IUnitOfWork<Object, XtextResource>()
{
public Value exec(XtextResource resource) throws Exception {
Object selectedObject = selected;
if (selectedObject instanceof IOutlineNode) {
if (selectedObject instanceof EObjectNode) {
EObjectNode selectedObjectNode = (EObjectNode) selectedObject;
URI eObjectURI = selectedObjectNode.getEObjectURI();
contextObject = metaModelManager.loadResource(eObjectURI, null, null);
contextClassifier = selectedObjectNode.getEClass();
}
else if (selectedObject instanceof EStructuralFeatureNode) {
contextObject = null;
contextClassifier = ((EStructuralFeatureNode) selectedObject).getEStructuralFeature().getEContainingClass();
}
else {
contextObject = null;
contextClassifier = null;
}
}
else {
if (selectedObject instanceof IAdaptable) {
selectedObject = ((IAdaptable) selectedObject).getAdapter(EObject.class);
}
if (selectedObject instanceof EObject) {
contextObject = (EObject) selectedObject;
contextClassifier = contextObject.eClass();
}
else {
contextObject = null;
contextClassifier = null;
}
}
editorDocument.setContext((EssentialOCLCSResource) resource, contextClassifier, null);
console.setSelection(contextClassifier, contextObject);
if (validateAction != null) {
validateAction.setSelection(contextObject);
}
return null;
}
});
}
/**
* 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 = null;
if (sel instanceof IStructuredSelection) {
IStructuredSelection ssel = (IStructuredSelection) sel;
if (!ssel.isEmpty()) {
selectedObject = ssel.getFirstElement();
}
}
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);
} */
}