org.fusesource.ide.camel.editor.dialogs.ConditionalBreakpointEditorDialog.java Source code

Java tutorial

Introduction

Here is the source code for org.fusesource.ide.camel.editor.dialogs.ConditionalBreakpointEditorDialog.java

Source

/*******************************************************************************
 * Copyright (c) 2014 Red Hat, Inc.
 * Distributed under license by Red Hat, Inc. All rights reserved.
 * This program is 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:
 *     Red Hat, Inc. - initial API and implementation
 ******************************************************************************/
package org.fusesource.ide.camel.editor.dialogs;

import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.dialogs.TitleAreaDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ST;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Shell;
import org.fusesource.ide.camel.model.service.core.CamelServiceManagerUtil;
import org.fusesource.ide.camel.model.service.core.ICamelManagerService;
import org.fusesource.ide.camel.model.service.core.catalog.CamelModelFactory;
import org.fusesource.ide.camel.model.service.core.model.AbstractCamelModelElement;
import org.fusesource.ide.camel.model.service.core.util.LanguageUtils;
import org.fusesource.ide.foundation.core.util.Strings;
import org.fusesource.ide.preferences.PreferenceManager;
import org.fusesource.ide.preferences.PreferencesConstants;

/**
 * @author lhein
 */
public class ConditionalBreakpointEditorDialog extends TitleAreaDialog {

    private static final String PATTERN_SIMPLE = "${%s}";
    private static final String[] SIMPLE_VARS = new String[] { "camelId", "camelContext.OGNL", "exchangeId", "id",
            "body", "in.body", "body.OGNL", "in.body.OGNL", "bodyAs(type)", "mandatoryBodyAs(type)", "out.body",
            "header.foo", "header[foo]", "headers.foo", "headers[foo]", "in.header.foo", "in.header[foo]",
            "in.headers.foo", "in.headers[foo]", "header.foo[bar]", "in.header.foo[bar]", "in.headers.foo[bar]",
            "header.foo.OGNL", "in.header.foo.OGNL", "in.headers.foo.OGNL", "out.header.foo", "out.header[foo]",
            "out.headers.foo", "out.headers[foo]", "headerAs(key,type)", "headers", "in.headers", "property.foo",
            "property[foo]", "property.foo.OGNL", "sys.foo", "sysenv.foo", "exception", "exception.OGNL",
            "exception.message", "exception.stacktrace", "date:command:pattern", "bean:bean expression",
            "properties:locations:key", "routeId", "threadName", "ref:xxx", "type:name.field" };

    private static final String PATTERN_SCRIPTING = "%s";
    private static final String[] SCRIPTING_VARS = new String[] { "context", "camelContext", "exchange", "request",
            "response", "properties", "request.headers.get('foo')", "response.headers.get('foo')" };

    private static final String PATTERN_SPEL = "#{%s}";
    private static final String[] SPEL_VARS = new String[] { "this", "exchange", "exception", "exchangeId", "fault",
            "body", "request", "request.headers['foo']", "request.body", "response", "response.headers['foo']",
            "response.body", "properties", "property(foo)", "property(foo, type)" };

    private String language;
    private String condition;
    private AbstractCamelModelElement node;
    private Group grp_language;
    private Group grp_condition;
    private Combo combo_language;
    private StyledText text_condition;
    private Button btn_variables;
    private Menu textMenu;
    private Menu variablesContextSubMenu;
    private MenuItem mVarItem;

    /**
     * 
     * @param parentShell
     * @param node
     */
    public ConditionalBreakpointEditorDialog(Shell parentShell, AbstractCamelModelElement node) {
        super(parentShell);
        this.node = node;
    }

    /* (non-Javadoc)
     * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
     */
    @Override
    protected void configureShell(Shell newShell) {
        super.configureShell(newShell);
        newShell.setText(String.format("Edit Conditional Breakpoint on %s ...", this.node.getDisplayText()));
    }

    /* (non-Javadoc)
     * @see org.eclipse.jface.dialogs.Dialog#create()
     */
    @Override
    public void create() {
        super.create();
        setTitle("Edit the condition and language of your breakpoint...");
        setMessage("Please choose a language and define a condition for the breakpoint...",
                IMessageProvider.INFORMATION);
    }

    /* (non-Javadoc)
     * @see org.eclipse.jface.dialogs.TitleAreaDialog#createDialogArea(org.eclipse.swt.widgets.Composite)
     */
    @Override
    protected Control createDialogArea(Composite parent) {
        Composite area = (Composite) super.createDialogArea(parent);

        Composite container = new Composite(area, SWT.NONE);
        container.setLayoutData(new GridData(GridData.FILL_BOTH));
        GridLayout layout = new GridLayout(1, true);
        container.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
        container.setLayout(layout);

        // create the language selection combo
        createLanguageControls(container);

        // then create the condition text area
        createConditionControls(container);

        container.pack();

        prepareContextMenu();

        return area;
    }

    /* (non-Javadoc)
     * @see org.eclipse.jface.dialogs.TitleAreaDialog#createContents(org.eclipse.swt.widgets.Composite)
     */
    @Override
    protected Control createContents(Composite parent) {
        Control c = super.createContents(parent);
        validate();
        return c;
    }

    /* (non-Javadoc)
     * @see org.eclipse.jface.dialogs.Dialog#okPressed()
     */
    @Override
    protected void okPressed() {
        if (validate()) {
            saveInputs();
            super.okPressed();
        }
    }

    /* (non-Javadoc)
     * @see org.eclipse.jface.dialogs.Dialog#isResizable()
     */
    @Override
    protected boolean isResizable() {
        return true;
    }

    /* (non-Javadoc)
     * @see org.eclipse.jface.dialogs.TrayDialog#isHelpAvailable()
     */
    @Override
    public boolean isHelpAvailable() {
        return true;
    }

    /**
     * creates the language combo box and depending controls
     * 
     * @param container
     */
    private void createLanguageControls(Composite container) {
        FillLayout grpLayout = new FillLayout(SWT.VERTICAL);
        grpLayout.marginHeight = 10;
        grpLayout.marginWidth = 10;

        grp_language = new Group(container, SWT.NONE);
        grp_language.setText("Language");
        grp_language.setToolTipText("Please select a language from the drop down box...");
        grp_language.setLayout(grpLayout);
        grp_language.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

        combo_language = new Combo(grp_language, SWT.BORDER | SWT.DROP_DOWN | SWT.READ_ONLY);
        combo_language.setToolTipText("Please select a language from the drop down box...");
        combo_language.setItems(getSupportedLanguages());
        combo_language.addSelectionListener(new SelectionAdapter() {
            /* (non-Javadoc)
             * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
             */
            @Override
            public void widgetSelected(SelectionEvent e) {
                super.widgetSelected(e);
                validate();
                prepareContextMenu();
            }
        });

        // if we have a preset language then we will use that if possible
        if (this.language != null) {
            int idx = combo_language.indexOf(this.language);
            if (idx != -1) {
                combo_language.select(idx);
                return;
            }
        }

        // if we have a saved preference default language we will use that if possible
        String defaultLanguage = PreferenceManager.getInstance()
                .loadPreferenceAsString(PreferencesConstants.EDITOR_DEFAULT_LANGUAGE);
        int idx = combo_language.indexOf(defaultLanguage);
        if (idx != -1) {
            combo_language.select(idx);
            return;
        }

        // if we have no old language value and no default language set in preferences then we take the first in list
        if (combo_language.getItemCount() > 0)
            combo_language.select(0);
    }

    private String[] getSupportedLanguages() {
        return LanguageUtils.languageArray(node.getCamelFile());
    }

    /**
     * creates the condition text area and depending controls
     * 
     * @param container
     */
    private void createConditionControls(Composite container) {
        GridLayout grpLayout = new GridLayout(1, true);
        grpLayout.verticalSpacing = 10;
        grpLayout.marginHeight = 10;
        grpLayout.marginWidth = 10;

        grp_condition = new Group(container, SWT.NONE);
        grp_condition.setText("Condition");
        grp_condition.setToolTipText("Please define your condition...");
        grp_condition.setLayout(grpLayout);
        grp_condition.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

        GridData data_text_condition = new GridData(SWT.FILL, SWT.FILL, true, true);
        data_text_condition.verticalSpan = 4;

        text_condition = new StyledText(grp_condition,
                SWT.FULL_SELECTION | SWT.MULTI | SWT.WRAP | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
        text_condition.setEditable(true);
        text_condition.setEnabled(true);
        text_condition.setToolTipText("Please specify your condition...");
        text_condition.setLayoutData(data_text_condition);
        text_condition.addModifyListener(new ModifyListener() {
            @Override
            public void modifyText(ModifyEvent e) {
                validate();
            }
        });

        GridData data_btn_variables = new GridData(SWT.RIGHT, SWT.TOP, true, false);
        btn_variables = new Button(grp_condition, SWT.FLAT | SWT.PUSH);
        btn_variables.setText("Variables");
        btn_variables.setToolTipText("Select a predefined variable...");
        btn_variables.setLayoutData(data_btn_variables);
        btn_variables.addSelectionListener(new SelectionAdapter() {
            /* (non-Javadoc)
             * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
             */
            @Override
            public void widgetSelected(SelectionEvent e) {
                onVariablesButtonPressed(e);
            }
        });

        // if we have a preset text then we fill it in
        if (this.condition != null) {
            text_condition.setText(this.condition);
        }
    }

    /**
     * the variables button was pressed - here its handled
     * 
     * @param e
     */
    private void onVariablesButtonPressed(SelectionEvent e) {
        Point point = btn_variables.toDisplay(new Point(e.x, e.y));
        Menu varsSubMenu = createVariablesMenu(btn_variables);
        createVariableSubmenu(varsSubMenu);
        varsSubMenu.setLocation(point.x, point.y);
        varsSubMenu.setVisible(true);
    }

    /**
     * adds the context menu to the parent menu
     */
    private void prepareContextMenu() {
        if (this.textMenu == null) {
            this.textMenu = createVariablesMenu(this.text_condition);

            mVarItem = new MenuItem(this.textMenu, SWT.CASCADE, 0);
            mVarItem.setText("Variables");
            variablesContextSubMenu = new Menu(textMenu);
            createVariableSubmenu(variablesContextSubMenu);
            mVarItem.setMenu(variablesContextSubMenu);

            new MenuItem(this.textMenu, SWT.SEPARATOR, 1);

            MenuItem cutItem = new MenuItem(this.textMenu, SWT.PUSH, 2);
            cutItem.setText("Cut");
            cutItem.addSelectionListener(new SelectionAdapter() {
                /* (non-Javadoc)
                 * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
                 */
                @Override
                public void widgetSelected(SelectionEvent e) {
                    text_condition.invokeAction(ST.CUT);
                }
            });

            MenuItem copyItem = new MenuItem(this.textMenu, SWT.PUSH, 3);
            copyItem.setText("Copy");
            copyItem.addSelectionListener(new SelectionAdapter() {
                /* (non-Javadoc)
                 * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
                 */
                @Override
                public void widgetSelected(SelectionEvent e) {
                    text_condition.invokeAction(ST.COPY);
                }
            });

            MenuItem pasteItem = new MenuItem(this.textMenu, SWT.PUSH, 4);
            pasteItem.setText("Paste");
            pasteItem.addSelectionListener(new SelectionAdapter() {
                /* (non-Javadoc)
                 * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
                 */
                @Override
                public void widgetSelected(SelectionEvent e) {
                    text_condition.invokeAction(ST.PASTE);
                }
            });

            new MenuItem(this.textMenu, SWT.SEPARATOR, 5);

            MenuItem markAllItem = new MenuItem(this.textMenu, SWT.PUSH, 6);
            markAllItem.setText("Select all");
            markAllItem.addSelectionListener(new SelectionAdapter() {
                /* (non-Javadoc)
                 * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
                 */
                @Override
                public void widgetSelected(SelectionEvent e) {
                    text_condition.invokeAction(ST.SELECT_ALL);
                }
            });
        } else {
            variablesContextSubMenu = new Menu(textMenu);
            createVariableSubmenu(variablesContextSubMenu);
            mVarItem.setMenu(variablesContextSubMenu);
        }
    }

    /**
     * 
     * @param parent
     * @return
     */
    private Menu createVariablesMenu(Control parent) {
        Menu variablesMenu = new Menu(parent);
        parent.setMenu(variablesMenu);
        return variablesMenu;
    }

    /**
     * fills in all predefined variables
     * 
     * @param parentItem
     */
    private void createVariableSubmenu(Menu parentItem) {
        String lang = combo_language.getText().trim();

        if (lang.equalsIgnoreCase("simple")) {
            createVariables(parentItem, SIMPLE_VARS, PATTERN_SIMPLE);
        } else if (lang.equalsIgnoreCase("spel")) {
            createVariables(parentItem, SPEL_VARS, PATTERN_SPEL);
        } else if (lang.equalsIgnoreCase("groovy") || lang.equalsIgnoreCase("ruby") || lang.equalsIgnoreCase("php")
                || lang.equalsIgnoreCase("ruby") || lang.equalsIgnoreCase("el") || lang.equalsIgnoreCase("sql")
                || lang.equalsIgnoreCase("jxpath") || lang.equalsIgnoreCase("mvel") || lang.equalsIgnoreCase("ognl")
                || lang.equalsIgnoreCase("python") || lang.equalsIgnoreCase("xpath")
                || lang.equalsIgnoreCase("xquery") || lang.equalsIgnoreCase("javascript")) {
            createVariables(parentItem, SCRIPTING_VARS, PATTERN_SCRIPTING);
        } else {
            // unsupported language
        }
        if (parentItem.getItemCount() == 0) {
            // seems we have no predefined vars yet
            // add a notifier
            MenuItem dummyItem = new MenuItem(parentItem, SWT.PUSH);
            dummyItem.setText("<nothing available>");
            dummyItem.setEnabled(false);
        }
    }

    /**
     * creates variables available in the simple language
     * 
     * @param parentItem
     */
    private void createVariables(Menu parentItem, String[] commands, final String pattern) {
        for (String cmd : commands) {
            final String command = cmd;
            MenuItem item = new MenuItem(parentItem, SWT.PUSH);
            item.setText(cmd);
            item.addSelectionListener(new SelectionAdapter() {
                /* (non-Javadoc)
                 * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
                 */
                @Override
                public void widgetSelected(SelectionEvent e) {
                    super.widgetSelected(e);
                    // user wants to embed a selection in a variable
                    if (text_condition.getSelectionText().length() > 0 && command.indexOf("foo") != -1) {
                        // use the selection for the variable insert
                        String selectedText = text_condition.getSelectionText();
                        String newCommand = command.replaceFirst("foo", selectedText);
                        String insertText = String.format(pattern, newCommand);
                        Point p = text_condition.getSelectionRange();
                        text_condition.replaceTextRange(p.x, selectedText.length(), insertText);
                    } else {
                        String insertText = String.format("${%s}", command);
                        text_condition.insert(insertText);
                    }
                }
            });
        }
    }

    /**
     * saves the made changes from the controls to the variables
     */
    private void saveInputs() {
        this.language = combo_language.getText();
        this.condition = text_condition.getText().replaceAll("\n", "").replaceAll("\r", "").trim();
    }

    /**
     * validates the language and the condition and sets or clears 
     * the error messages
     * 
     * @return   true if all is fine
     */
    private boolean validate() {
        if (Strings.isBlank(combo_language.getText())) {
            setErrorMessage("You must select a language from the language combo box.");
            if (getButton(OK) != null)
                getButton(OK).setEnabled(false);
            return false;
        }
        if (Strings.isBlank(text_condition.getText().replaceAll("\n", "").replaceAll("\r", "").trim())) {
            setErrorMessage("You must enter a valid condition using the selected language.");
            if (getButton(OK) != null)
                getButton(OK).setEnabled(false);
            return false;
        }

        String cv = CamelModelFactory.getCamelVersion(node.getCamelFile().getResource().getProject());
        if (cv != null) {
            // not initialized yet
            ICamelManagerService svc = CamelServiceManagerUtil.getManagerService(cv);
            if (svc != null) {
                String ex = svc.testExpression(combo_language.getText().trim(), text_condition.getText());
                if (ex != null && !ex.contains("No language could be found for:")) {
                    setErrorMessage("Condition Error: " + ex);
                    if (getButton(OK) != null)
                        getButton(OK).setEnabled(false);
                    return false;
                }
            }
        }

        if (getButton(OK) != null)
            getButton(OK).setEnabled(true);
        setErrorMessage(null);
        return true;
    }

    /**
     * @return the language
     */
    public String getLanguage() {
        return this.language;
    }

    /**
     * @param language the language to set
     */
    public void setLanguage(String language) {
        this.language = language;
    }

    /**
     * @return the condition
     */
    public String getCondition() {
        return this.condition;
    }

    /**
     * @param condition the condition to set
     */
    public void setCondition(String condition) {
        this.condition = condition;
    }
}