Java tutorial
/** * <copyright> * * 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 Knemann - Bug 294200 (history) * E.D.Willink - rework of LPG OCL Console for Xtext * * </copyright> */ 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.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.ITextSelection; 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.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.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.IOutlineNode; 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 foer cancelation at a variety of significant * evaluation events, such as feature vists and {@link #getValueFactory()}. */ 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 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 oclConsole */ 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 color 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(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 = 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); IMenuManager menu = getSite().getActionBars().getMenuManager(); 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, 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) { 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(XtextResource state) throws Exception { assert state != null; IProgressService progressService = PlatformUI.getWorkbench().getProgressService(); EvaluationRunnable runnable = new EvaluationRunnable((BaseResource) state, expression); progressService.busyCursorWhile(runnable); return runnable.getValue(); } }); } 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()) ; } @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; } 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; } /** * 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(); } */ 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(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 { 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(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(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 = null; if (sel instanceof ITextSelection) { selectedObject = BaseUIUtil.getXtextTextSelection((ITextSelection) sel, getSite()); } else { if (sel instanceof IStructuredSelection) { IStructuredSelection ssel = (IStructuredSelection) sel; if (!ssel.isEmpty()) { selectedObject = ssel.getFirstElement(); } } if (selectedObject instanceof IOutlineNode) { selectedObject = BaseUIUtil.getXtextOutlineSelection((IOutlineNode) selectedObject, getSite()); } } 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); } */ }