/******************************************************************************* * Copyright (c) 2006-2013 The RCP Company 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: * The RCP Company - initial API and implementation *******************************************************************************/ package com.rcpcompany.uibindings.debug.internals.views; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import org.eclipse.core.databinding.observable.value.IObservableValue; import org.eclipse.emf.common.notify.Adapter; import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.common.notify.impl.AdapterImpl; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.edit.domain.EditingDomain; import org.eclipse.jface.viewers.ISelection; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.widgets.Composite; import org.eclipse.ui.ISelectionListener; import org.eclipse.ui.ISelectionService; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.part.ViewPart; import com.rcpcompany.uibindings.IBindingContext; import com.rcpcompany.uibindings.IValueBinding; import com.rcpcompany.uibindings.UIBindingsUtils; import com.rcpcompany.uibindings.debug.IDebugFactory; import com.rcpcompany.uibindings.debug.IDebugPackage; import com.rcpcompany.uibindings.debug.IScriptConsoleContext; import com.rcpcompany.uibindings.model.utils.BasicUtils; import com.rcpcompany.uibindings.scripting.IScriptEngineDescriptor; import com.rcpcompany.uibindings.scripting.IScriptEvaluationContext; import com.rcpcompany.uibindings.scripting.IScriptExpression; import com.rcpcompany.uibindings.scripting.IScriptManager; import com.rcpcompany.uibindings.scripting.ScriptEngineException; import com.rcpcompany.uibindings.utils.IFormChooser; import com.rcpcompany.uibindings.utils.IFormChooserCreator; import com.rcpcompany.uibindings.utils.IFormCreator; import com.rcpcompany.uibindings.utils.SelectionUtils; import com.rcpcompany.utils.logging.LogUtils; /** * Simple Script Console. * * @author Tonny Madsen, The RCP Company */ public class ScriptConsole extends ViewPart { private IFormCreator myForm; private final IScriptConsoleContext myData; protected IValueBinding myScriptBinding; private final EditingDomain myEditingDomain; public ScriptConsole() { myData = IDebugFactory.eINSTANCE.createScriptConsoleContext(); myData.eAdapters().add(myAdapter); myEditingDomain = UIBindingsUtils.createEditingDomain(); } @Override public void dispose() { final ISelectionService ss = getSite().getPage().getWorkbenchWindow().getSelectionService(); ss.removePostSelectionListener(mySelectionListener); final IScriptExpression e = myData.getExpression(); if (e != null) { e.dispose(); myData.setExpression(null); } myData.eAdapters().remove(myAdapter); super.dispose(); } private final Adapter myAdapter = new AdapterImpl() { @Override public void notifyChanged(Notification msg) { if (msg.isTouch()) return; if (msg.getNotifier() == myData) { if (msg.getFeature() == IDebugPackage.Literals.SCRIPT_CONSOLE_CONTEXT__LANGUAGE || msg.getFeature() == IDebugPackage.Literals.SCRIPT_CONSOLE_CONTEXT__OBJECT || msg.getFeature() == IDebugPackage.Literals.SCRIPT_CONSOLE_CONTEXT__SCRIPT) { updateExpression(); } } if (msg.getNotifier() instanceof IScriptExpression) { updateResult(); } }; }; private final ISelectionListener mySelectionListener = new ISelectionListener() { @Override public void selectionChanged(IWorkbenchPart part, ISelection selection) { final List<EObject> s = SelectionUtils.computeSelection(selection, EObject.class); if (s == null || s.size() != 1) return; myData.setObject(s.get(0)); } }; @Override public void createPartControl(Composite parent) { myForm = IFormCreator.Factory.createScrolledForm(myData, parent, "Script"); /* * We have our own editing domain.... */ myForm.getContext().setEditingDomain(myEditingDomain); final StyledText output = new StyledText(myForm.addComposite(true, true), SWT.V_SCROLL | SWT.H_SCROLL); output.setText(""); myForm.addField("object(readonly,type=qualifiedName)"); final IValueBinding languageBinding = myForm.addField("language"); final IFormChooser languageChooser = myForm.addFormChooser(languageBinding); final Collection<IScriptEngineDescriptor> engines = IScriptManager.Factory.getManager().getEngines().values(); for (final IScriptEngineDescriptor l : engines) { languageChooser.addFormValue(l.getLanguage(), new IFormChooserCreator() { @Override public void createForm(IBindingContext context, IObservableValue discriminant, Composite parent) { final IFormCreator subForm = myForm.subForm(parent); myScriptBinding = subForm.addField("script").type("script-" + l.getLanguage()); myForm.finish(); myForm.getTop().layout(); myScriptBinding.setFocus(); } }); } myForm.addField("result(readonly)"); myForm.addField("exception(readonly)"); myForm.finish(); final ISelectionService ss = getSite().getPage().getWorkbenchWindow().getSelectionService(); ss.addPostSelectionListener(mySelectionListener); } /** * Updates the language and expression of the facet based on the script */ protected void updateExpression() { IScriptExpression e = myData.getExpression(); if (e != null && (e.getEngine() == null || !e.getEngine().getLanguage().equals(myData.getLanguage()))) { e.dispose(); e.eAdapters().remove(myAdapter); myData.setExpression(null); e = null; } final EObject object = myData.getObject(); if (e == null) { /* * Need the language first */ if (myData.getLanguage() == null) return; final IScriptManager manager = IScriptManager.Factory.getManager(); try { final IScriptEvaluationContext context = manager.getRegisteredEvaluationContext(object); final Map<String, Object> locals = new HashMap<String, Object>(); locals.put("SELECTION", object); e = manager.addScript(myData.getLanguage(), myData.getScript(), String.class, context, locals); e.eAdapters().add(myAdapter); myData.setExpression(e); } catch (final ScriptEngineException ex) { LogUtils.error(this, ex); myData.setException(ex.getMessage()); myData.setResult(""); return; } } else if (!BasicUtils.equals(e.getScript(), myData.getScript())) { e.setScript(myData.getScript()); } else if (!BasicUtils.equals(e.getEvaluationContext().getVariables().get("SELECTION"), object)) { e.getEvaluationContext().getVariables().put("SELECTION", object); } // e.evaluate(); } /** * Updates the results part of the view. */ protected void updateResult() { final IScriptExpression e = myData.getExpression(); if (e == null) { myData.setException(""); myData.setResult(""); return; } myData.setException(e.getErrorMessage()); myData.setResult("" + e.getCurrentValue()); } @Override public void setFocus() { myForm.setFocus(); } }