eu.esdihumboldt.hale.ui.scripting.groovy.GroovyEditor.java Source code

Java tutorial

Introduction

Here is the source code for eu.esdihumboldt.hale.ui.scripting.groovy.GroovyEditor.java

Source

/*
 * Copyright (c) 2012 Data Harmonisation Panel
 * 
 * All rights reserved. This program and the accompanying materials are made
 * available under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation, either version 3 of the License,
 * or (at your option) any later version.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this distribution. If not, see <http://www.gnu.org/licenses/>.
 * 
 * Contributors:
 *     Data Harmonisation Panel <http://www.dhpanel.eu>
 */

package eu.esdihumboldt.hale.ui.scripting.groovy;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;

import org.eclipse.jface.fieldassist.ControlDecoration;
import org.eclipse.jface.fieldassist.FieldDecoration;
import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.jface.layout.TableColumnLayout;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.DocumentEvent;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentListener;
import org.eclipse.jface.text.source.CompositeRuler;
import org.eclipse.jface.text.source.IVerticalRuler;
import org.eclipse.jface.text.source.LineNumberRulerColumn;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.graphics.Point;
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.swt.widgets.Label;

import eu.esdihumboldt.hale.common.align.model.impl.PropertyEntityDefinition;
import eu.esdihumboldt.hale.common.align.transformation.function.PropertyValue;
import eu.esdihumboldt.hale.common.align.transformation.function.impl.PropertyValueImpl;
import eu.esdihumboldt.hale.common.scripting.Script;
import eu.esdihumboldt.hale.ui.HaleUI;
import eu.esdihumboldt.hale.ui.common.definition.viewer.DefinitionLabelProvider;
import eu.esdihumboldt.hale.ui.common.editors.AbstractEditor;
import eu.esdihumboldt.hale.ui.util.IColorManager;
import eu.esdihumboldt.hale.ui.util.groovy.GroovyColorManager;
import eu.esdihumboldt.hale.ui.util.groovy.GroovySourceViewerUtil;
import eu.esdihumboldt.hale.ui.util.groovy.SimpleGroovySourceViewerConfiguration;
import eu.esdihumboldt.hale.ui.util.source.SourceViewerKeyBindings;

/**
 * Editor for groovy scripts.
 * 
 * @author Kai Schwierczek
 */
public class GroovyEditor extends AbstractEditor<String> {

    private final Composite composite;
    private final Script script;
    //   private final Class<?> binding;
    private final SourceViewer viewer;
    private TableViewer varTable;
    private Collection<PropertyEntityDefinition> variables = Collections.emptySet();
    private String currentValue = "";
    private boolean valid;
    private final TestValues testValues;
    private final ControlDecoration decorator;
    private IColorManager colorManager;

    /**
     * Default constructor.
     * 
     * @param parent the parent composite
     * @param script the script object
     * @param binding the target binding
     */
    public GroovyEditor(Composite parent, Script script, Class<?> binding) {
        this.script = script;
        this.colorManager = new GroovyColorManager();
        //      this.binding = binding;
        testValues = new InstanceTestValues();

        composite = new Composite(parent, SWT.NONE);
        composite.setLayout(GridLayoutFactory.swtDefaults().create());

        viewer = createAndLayoutTextField(composite);
        viewer.configure(new SimpleGroovySourceViewerConfiguration(colorManager));
        IDocument document = new Document("");
        GroovySourceViewerUtil.setupDocument(document);
        viewer.setDocument(document);

        viewer.getControl().addDisposeListener(new DisposeListener() {

            @Override
            public void widgetDisposed(DisposeEvent e) {
                // color manager needs to be disposed
                colorManager.dispose();
            }
        });

        // control decoration
        decorator = new ControlDecoration(viewer.getControl(), SWT.LEFT | SWT.TOP, composite);
        // set initial status
        decorator.hide();
        // set image
        FieldDecoration fieldDecoration = FieldDecorationRegistry.getDefault()
                .getFieldDecoration(FieldDecorationRegistry.DEC_ERROR);
        decorator.setImage(fieldDecoration.getImage());

        viewer.getDocument().addDocumentListener(new IDocumentListener() {

            @Override
            public void documentChanged(DocumentEvent event) {
                // update value
                String newValue = event.getDocument().get();
                fireValueChanged(VALUE, currentValue, newValue);
                currentValue = newValue;

                validate();
            }

            @Override
            public void documentAboutToBeChanged(DocumentEvent event) {
                // ignore
            }
        });

        // variables
        Label label = new Label(composite, SWT.NONE);
        label.setText("Available variables (double click to insert)");
        label.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false));

        // variables table
        Composite tableComposite = new Composite(composite, SWT.NONE);
        tableComposite.setLayoutData(GridDataFactory.fillDefaults().grab(true, true).create());
        TableColumnLayout columnLayout = new TableColumnLayout();
        tableComposite.setLayout(columnLayout);
        varTable = new TableViewer(tableComposite, SWT.BORDER | SWT.SINGLE | SWT.FULL_SELECTION);
        TableViewerColumn column = new TableViewerColumn(varTable, SWT.NONE);
        columnLayout.setColumnData(column.getColumn(), new ColumnWeightData(1, false));
        varTable.setContentProvider(ArrayContentProvider.getInstance());
        varTable.setLabelProvider(new DefinitionLabelProvider(true, true) {

            /**
             * @see eu.esdihumboldt.hale.ui.common.definition.viewer.DefinitionLabelProvider#getText(java.lang.Object)
             */
            @Override
            public String getText(Object element) {
                return GroovyEditor.this.script.getVariableName((PropertyEntityDefinition) element);
            }
        });
        varTable.getTable().addMouseListener(new MouseAdapter() {

            /**
             * @see MouseAdapter#mouseDoubleClick(MouseEvent)
             */
            @Override
            public void mouseDoubleClick(MouseEvent e) {
                int index = varTable.getTable().getSelectionIndex();
                if (index >= 0) {
                    String var = varTable.getTable().getItem(index).getText();
                    Point selRange = viewer.getSelectedRange();
                    try {
                        viewer.getDocument().replace(selRange.x, selRange.y, var);
                    } catch (BadLocationException ble) {
                        // ignore
                    }
                }
            }
        });

        validate();
    }

    /**
     * Validates the current input against the currently available variables.
     */
    private void validate() {
        // also the returned type isn't checked.
        String result = GroovyEditor.this.script.validate(currentValue, createPropertyValues(),
                HaleUI.getServiceProvider());
        boolean oldValid = valid;
        valid = result == null;
        if (valid)
            decorator.hide();
        else {
            decorator.setDescriptionText(result);
            decorator.show();
        }
        if (valid != oldValid)
            fireStateChanged(IS_VALID, oldValid, valid);
    }

    /**
     * Returns an {@link Iterable} for the current variables for use with the
     * {@link Script}.
     * 
     * @return an {@link Iterable} for the current variables for use with the
     *         {@link Script}
     */
    protected Iterable<PropertyValue> createPropertyValues() {
        Collection<PropertyValue> values = new ArrayList<PropertyValue>(variables.size());
        for (PropertyEntityDefinition property : variables)
            values.add(new PropertyValueImpl(testValues.get(property), property));

        return values;
    }

    /**
     * Create the text field.
     * 
     * @param parent the parent composite
     * @return the input text field.
     */
    private SourceViewer createAndLayoutTextField(Composite parent) {
        IVerticalRuler ruler = createRuler();
        SourceViewer viewer = new SourceViewer(parent, ruler, SWT.BORDER | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
        viewer.getControl().setLayoutData(GridDataFactory.fillDefaults().grab(true, false).indent(7, 0).create());
        viewer.getTextWidget().setFont(JFaceResources.getTextFont());

        SourceViewerKeyBindings.installDefault(viewer);

        return viewer;
    }

    /**
     * Create the vertical ruler for the source viewer.
     * 
     * @return the vertical ruler
     */
    private IVerticalRuler createRuler() {
        final Display display = Display.getCurrent();
        CompositeRuler ruler = new CompositeRuler(3);
        LineNumberRulerColumn lineNumbers = new LineNumberRulerColumn();
        lineNumbers.setBackground(display.getSystemColor(SWT.COLOR_GRAY)); // SWT.COLOR_INFO_BACKGROUND));
        lineNumbers.setForeground(display.getSystemColor(SWT.COLOR_BLACK)); // SWT.COLOR_INFO_FOREGROUND));
        lineNumbers.setFont(JFaceResources.getTextFont());
        ruler.addDecorator(0, lineNumbers);
        return ruler;
    }

    /**
     * @see eu.esdihumboldt.hale.ui.common.Editor#getControl()
     */
    @Override
    public Control getControl() {
        return composite;
    }

    /**
     * @see eu.esdihumboldt.hale.ui.common.Editor#setValue(java.lang.Object)
     */
    @Override
    public void setValue(String value) {
        viewer.getDocument().set(value);
        currentValue = value;
    }

    /**
     * @see eu.esdihumboldt.hale.ui.common.Editor#getValue()
     */
    @Override
    public String getValue() {
        return currentValue;
    }

    /**
     * @see eu.esdihumboldt.hale.ui.common.Editor#setAsText(java.lang.String)
     */
    @Override
    public void setAsText(String text) {
        setValue(text);
    }

    /**
     * @see eu.esdihumboldt.hale.ui.common.Editor#getAsText()
     */
    @Override
    public String getAsText() {
        return getValue();
    }

    /**
     * @see eu.esdihumboldt.hale.ui.common.Editor#isValid()
     */
    @Override
    public boolean isValid() {
        return valid;
    }

    /**
     * @see eu.esdihumboldt.hale.ui.common.editors.AbstractEditor#setVariables(java.util.Collection)
     */
    @Override
    public void setVariables(Collection<PropertyEntityDefinition> properties) {
        variables = properties;
        varTable.setInput(variables);
        validate();
    }

    /**
     * @see eu.esdihumboldt.hale.ui.common.Editor#getValueType()
     */
    @Override
    public String getValueType() {
        return script.getId();
    }
}