All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.bidib.wizard.mvc.stepcontrol.view.ScriptPanel Maven / Gradle / Ivy

There is a newer version: 2.0.29
Show newest version
package org.bidib.wizard.mvc.stepcontrol.view;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;
import java.util.concurrent.atomic.AtomicBoolean;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.filechooser.FileFilter;
import javax.swing.filechooser.FileNameExtensionFilter;

import org.apache.commons.lang3.StringUtils;
import org.bidib.wizard.api.locale.Resources;
import org.bidib.wizard.api.script.ScriptCommand;
import org.bidib.wizard.api.script.ScriptEngineListener;
import org.bidib.wizard.api.script.ScriptStatus;
import org.bidib.wizard.client.common.text.WizardComponentFactory;
import org.bidib.wizard.common.model.settings.WizardSettingsInterface;
import org.bidib.wizard.common.script.DefaultScriptContext;
import org.bidib.wizard.common.script.engine.ScriptEngine;
import org.bidib.wizard.common.script.switching.AccessoryScripting;
import org.bidib.wizard.common.service.SettingsService;
import org.bidib.wizard.core.dialog.FileDialog;
import org.bidib.wizard.nodescript.script.stepcontrol.StepControlScriptCommandFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.jgoodies.binding.value.ValueHolder;
import com.jgoodies.binding.value.ValueModel;
import com.jgoodies.forms.builder.FormBuilder;

public class ScriptPanel implements ScriptEngineListener {
    private static final Logger LOGGER = LoggerFactory.getLogger(ScriptPanel.class);

    // description, suffix for script files
    private static String scriptDescription;

    private static final String WORKING_DIR_STEP_CONTROL_KEY = "stepControl";

    private static final String SCRIPT_EXTENSION = "bidibt";

    private static FileFilter scriptFilter;

    private ValueModel selectedScriptModel = new ValueHolder();

    private ValueModel currentCommandModel = new ValueHolder();

    private JButton startScript;

    private JButton stopScript;

    private AccessoryScripting scripting;

    private ScriptEngine scriptEngine;

    private ValueModel checkRepeatingModel = new ValueHolder();

    private AtomicBoolean scriptRepeating = new AtomicBoolean(false);

    private JPanel contentPanel;

    private final SettingsService settingsService;

    public ScriptPanel(AccessoryScripting scripting, final SettingsService settingsService) {
        this.scripting = scripting;
        this.settingsService = settingsService;

        scriptDescription = Resources.getString(ScriptPanel.class, "scriptDescription");
        scriptFilter = new FileNameExtensionFilter(scriptDescription, SCRIPT_EXTENSION);
    }

    public JPanel createPanel() {

        // create the script engine
        scriptEngine = new ScriptEngine(scripting, new DefaultScriptContext());
        scriptEngine.addScriptEngineListener(this);

        checkRepeatingModel.setValue(scriptRepeating.get());

        final FormBuilder formBuilder =
            FormBuilder.create().columns("60dlu, 3dlu, 60dlu, 3dlu, 0dlu:grow").rows("p, 3dlu, p, 3dlu, p");

        JButton selectScript = new JButton(Resources.getString(ScriptPanel.class, "selectScript"));
        selectScript.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {

                final WizardSettingsInterface wizardSettings = settingsService.getWizardSettings();
                String storedWorkingDirectory = wizardSettings.getWorkingDirectory(WORKING_DIR_STEP_CONTROL_KEY);

                // select the script file
                FileDialog dialog =
                    new FileDialog(contentPanel, FileDialog.OPEN, storedWorkingDirectory, "*." + SCRIPT_EXTENSION,
                        scriptFilter) {

                        @Override
                        public void approve(final String fileName) {
                            LOGGER.info("Load script: {}", fileName);
                            try {
                                File file = new File(fileName);
                                if (file.exists()) {
                                    LOGGER.info("The script file exists: {}", file);
                                    selectedScriptModel.setValue(file.getName());

                                    prepareScript(fileName);

                                    startScript.setEnabled(true);

                                    final String workingDir = Paths.get(fileName).getParent().toString();
                                    LOGGER.info("Save current workingDir: {}", workingDir);

                                    wizardSettings.setWorkingDirectory(WORKING_DIR_STEP_CONTROL_KEY, workingDir);
                                }
                                else {
                                    selectedScriptModel.setValue("no script selected");
                                    startScript.setEnabled(false);
                                }
                            }
                            catch (IOException ex) {
                                LOGGER.info("Load and process script file failed.", ex);
                                startScript.setEnabled(false);
                            }
                            finally {
                            }
                        }
                    };
                dialog.showDialog();
            }
        });
        formBuilder.add(selectScript).xy(1, 1);

        JLabel scriptLabel = WizardComponentFactory.createLabel(selectedScriptModel);
        formBuilder.add(scriptLabel).xyw(3, 1, 3);

        JCheckBox repeatingCheck =
            WizardComponentFactory
                .createCheckBox(checkRepeatingModel, Resources.getString(ScriptPanel.class, "repeating"));
        formBuilder.add(repeatingCheck).xyw(1, 3, 3);

        startScript = new JButton(Resources.getString(ScriptPanel.class, "startScript"));
        startScript.setEnabled(false);
        startScript.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                scriptEngine.startScript();
            }
        });
        formBuilder.add(startScript).xy(1, 5);

        stopScript = new JButton(Resources.getString(ScriptPanel.class, "stopScript"));
        stopScript.setEnabled(false);
        stopScript.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                stopScript();
            }
        });
        formBuilder.add(stopScript).xy(3, 5);

        JLabel currentCommandLabel = WizardComponentFactory.createLabel(currentCommandModel);
        formBuilder.add(currentCommandLabel).xy(5, 5);

        checkRepeatingModel.addValueChangeListener(new PropertyChangeListener() {

            @Override
            public void propertyChange(PropertyChangeEvent evt) {
                LOGGER.info("Repeating has changed: {}", checkRepeatingModel.getValue());
                Boolean repeating = (Boolean) checkRepeatingModel.getValue();

                scriptRepeating.set(repeating);
                scriptEngine.setScriptRepeating(repeating);
            }
        });

        contentPanel = formBuilder.build();
        return contentPanel;
    }

    @Override
    public void currentCommandChanged(final ScriptCommand command) {

        if (SwingUtilities.isEventDispatchThread()) {
            currentCommandModel.setValue((command != null ? command.toString() : null));
        }
        else {
            try {
                SwingUtilities.invokeAndWait(new Runnable() {

                    @Override
                    public void run() {
                        currentCommandModel.setValue((command != null ? command.toString() : null));
                    }
                });
            }
            catch (InvocationTargetException | InterruptedException e) {
                LOGGER.warn("Update current command failed.", e);
            }
        }
    }

    private void stopScript() {
        LOGGER.info("Stop the script.");
        scriptEngine.stopScript();
    }

    @Override
    public void scriptStatusChanged(final ScriptStatus scriptStatus) {
        LOGGER.info("The script status has changed: {}", scriptStatus);
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                switch (scriptStatus) {
                    case RUNNING:
                        startScript.setEnabled(false);
                        stopScript.setEnabled(true);
                        break;
                    case ABORTED:
                    case STOPPED:
                    case FINISHED:
                    case FINISHED_WITH_ERRORS:
                        startScript.setEnabled(true);
                        stopScript.setEnabled(false);
                        break;
                    default:
                        break;
                }
                currentCommandChanged(null);
            }
        });
    }

    private final static Charset ENCODING = StandardCharsets.UTF_8;

    private void prepareScript(String fileName) throws IOException {
        Path fFilePath = Paths.get(fileName);

        StepControlScriptCommandFactory factory = new StepControlScriptCommandFactory();
        factory.registerCommands();
        List> scriptCommands = new LinkedList<>();

        try (Scanner scanner = new Scanner(fFilePath, ENCODING.name())) {
            while (scanner.hasNextLine()) {
                processLine(scanner.nextLine().trim(), factory, scriptCommands);
            }
        }
        finally {

        }

        LOGGER.info("Prepared list of commands: {}", scriptCommands);

        scriptEngine.setScriptCommands(scriptCommands);
    }

    private void processLine(
        String line, StepControlScriptCommandFactory factory, List> scriptCommands) {
        LOGGER.info("Process line: {}", line);

        if (line.startsWith("#") || StringUtils.isBlank(line)) {
            LOGGER.info("Skip comment or empty line.");
        }
        else {
            LOGGER.info("Current line: {}", line);
            ScriptCommand command = factory.parse(line);
            if (command != null) {
                scriptCommands.add(command);
            }
        }
    }

    public void close() {

        if (scriptEngine != null) {
            LOGGER.info("Release the scriptEngine.");

            scriptEngine.removeScriptEngineListener(this);

            scriptEngine = null;
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy