blob: 02d0d24c117f22037a5e17c47d2214ebe4839621 [file] [log] [blame]
/*
-----------------------------------------------------------------------
-- Copyright (C) 2011-2016 --
-- University of Firenze, Italy --
-- --
-- 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-v20.html --
-- --
-- Contributors: --
-- Leonardo Montecchi lmontecchi@unifi.it --
-----------------------------------------------------------------------
*/
package org.polarsys.chess.statebased;
import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.wizard.ProgressMonitorPart;
import org.eclipse.papyrus.MARTE.MARTE_Foundations.GRM.Scheduler;
import org.eclipse.papyrus.editor.PapyrusMultiDiagramEditor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.events.VerifyListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.DateTime;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.internal.misc.ProgramImageDescriptor;
import org.polarsys.chess.service.gui.utils.CHESSEditorUtils;
import org.polarsys.chess.statebased.daemon.ParameterList;
public class PeriodicExecutionDialog extends Dialog implements Runnable {
private Text txtParams;
private Text txtResults;
private Text txtPeriod;
private String user = "";
private String password = "";
private Button btnParams;
private Button btnResults;
private Button btnPeriodic;
private Button btnCancel;
private Button btnProceed;
private Label lblParams;
private Label lblResults;
private Label lblPeriod;
private Label lblMessage;
private Label lblSeconds;
private Button chkSaveParamsPath;
private Button chkSaveResultsPath;
private Composite container;
private int iInterval = 0;
private boolean bIsPeriodic = false;
private ProgressMonitorPart monitor;
private ScheduledExecutorService executorService;
private Future<?> currentJob;
/* Inner class used to correctly update the lblMessage label in the
* dialog from other threads (avoids InvalidThreadAccess exceptions) */
private class MessageLabelUpdater implements Runnable {
private String m;
public MessageLabelUpdater(String message) {
super();
m = message;
}
@Override
public void run() {
if(!lblMessage.isDisposed())
lblMessage.setText(m);
}
}
/* Inner class used to correctly update the enabled state of controls
* from other threads (avoids InvalidThreadAccess exceptions) */
private class EnabledStateUpdater implements Runnable {
private boolean s;
public EnabledStateUpdater(boolean state) {
super();
s = state;
}
@Override
public void run() {
if(!container.isDisposed()) {
Control[] children = container.getChildren();
for(int i = 0; i < children.length; i++) {
children[i].setEnabled(s);
}
if(s) {
txtPeriod.setEnabled(btnPeriodic.getSelection());
}
lblMessage.setEnabled(true);
btnCancel.setText(IDialogConstants.CANCEL_LABEL);
btnCancel.setEnabled(s);
btnProceed.setEnabled(s);
}
}
}
/* Inner class used to correctly begin a new task in the
* bar (avoids InvalidThreadAccess exceptions) */
private class ProgressTaskBegin implements Runnable {
private String taskName;
private int totalWork;
public ProgressTaskBegin(String name, int work) {
super();
taskName = name;
totalWork = work;
}
@Override
public void run() {
if(!monitor.isDisposed()) {
monitor.setVisible(true);
monitor.beginTask(taskName, totalWork);
}
}
}
public PeriodicExecutionDialog(Shell parentShell) {
super(parentShell);
executorService = Executors.newSingleThreadScheduledExecutor();
}
@Override
protected Control createDialogArea(Composite parent) {
container = (Composite) super.createDialogArea(parent);
GridLayout layout = new GridLayout(3, false);
layout.marginRight = 5;
layout.marginLeft = 10;
container.setLayout(layout);
lblParams = new Label(container, SWT.NONE);
GridData gd_lblParams = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
gd_lblParams.horizontalIndent = 1;
lblParams.setLayoutData(gd_lblParams);
lblParams.setText("Parameters File:");
txtParams = new Text(container, SWT.BORDER);
txtParams.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
txtParams.setText(Activator.getDefault().getPreferenceStore().getString("PARAMFILE"));
btnParams = new Button(container, SWT.NONE);
btnParams.setText("Browse");
btnParams.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
FileDialog fd = new FileDialog(PeriodicExecutionDialog.this.getParentShell());
fd.setText("Select Parameters File");
fd.setFileName(txtParams.getText());
txtParams.setText(fd.open());
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
// TODO Auto-generated method stub
}
});
chkSaveParamsPath = new Button(container, SWT.CHECK);
chkSaveParamsPath.setText("Save as default");
chkSaveParamsPath.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, false, 3, 1));
lblResults = new Label(container, SWT.NONE);
GridData gd_lblPassword = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
gd_lblPassword.horizontalIndent = 1;
lblResults.setLayoutData(gd_lblPassword);
lblResults.setText("Results File:");
txtResults = new Text(container, SWT.BORDER);
txtResults.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
txtResults.setText(Activator.getDefault().getPreferenceStore().getString("RESULTFILE"));
btnResults = new Button(container, SWT.NONE);
btnResults.setText("Browse");
btnResults.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
FileDialog fd = new FileDialog(PeriodicExecutionDialog.this.getParentShell());
fd.setText("Select Results File");
fd.setFileName(txtResults.getText());
fd.setOverwrite(true);
txtResults.setText(fd.open());
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
// TODO Auto-generated method stub
}
});
chkSaveResultsPath = new Button(container, SWT.CHECK);
chkSaveResultsPath.setText("Save as default");
chkSaveResultsPath.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, false, 3, 1));
Label lblPeriodic = new Label(container, SWT.NONE);
GridData gd_lblPeriodic = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
gd_lblPeriodic.horizontalIndent = 1;
lblPeriodic.setLayoutData(gd_lblPeriodic);
lblPeriodic.setText("Periodic:");
btnPeriodic = new Button(container, SWT.CHECK);
btnPeriodic.setSelection(Activator.getDefault().getPreferenceStore().getBoolean("RUNPERIODIC"));
btnPeriodic.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 2, 1));
btnPeriodic.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
txtPeriod.setEnabled(btnPeriodic.getSelection());
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
// TODO Auto-generated method stub
}
});
lblPeriod = new Label(container, SWT.NONE);
GridData gd_lblPeriod = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
gd_lblPeriod.horizontalIndent = 1;
lblPeriod.setLayoutData(gd_lblPeriod);
lblPeriod.setText("Period:");
txtPeriod = new Text(container, SWT.BORDER);
iInterval = Activator.getDefault().getPreferenceStore().getInt("EXECPERIOD");
txtPeriod.setText(Integer.toString(iInterval));
txtPeriod.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
txtPeriod.addVerifyListener(new VerifyListener() {
@Override
public void verifyText(VerifyEvent e) {
String string = e.text;
char[] chars = new char[string.length()];
string.getChars(0, chars.length, chars, 0);
for (int i = 0; i < chars.length; i++) {
if (!('0' <= chars[i] && chars[i] <= '9')) {
e.doit = false;
return;
}
}
}
});
txtPeriod.addModifyListener(new ModifyListener() {
@Override
public void modifyText(ModifyEvent e) {
setMessage("");
if(btnPeriodic.getSelection()) {
try {
iInterval = Integer.parseInt(txtPeriod.getText());
}catch(NumberFormatException ex) {
setMessage("Period is invalid");
}
if(iInterval < 60) {
setMessage("A period of at least 60 seconds is strongly recommended");
}
}
}
});
lblSeconds = new Label(container, SWT.NONE);
lblSeconds.setText("seconds");
lblMessage = new Label(container, SWT.NONE);
lblMessage.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 3, 1));
monitor = new ProgressMonitorPart(container, new GridLayout());
monitor.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 3, 1));
setControlsEnabledState(true);
return container;
}
private void setMessage(String m) {
// Avoids InvalidThreadAccess exceptions when called from another thread
Display.getDefault().asyncExec(new MessageLabelUpdater(m));
}
private void setControlsEnabledState(boolean enabled) {
// Avoids InvalidThreadAccess exceptions when called from another thread
Display.getDefault().asyncExec(new EnabledStateUpdater(enabled));
}
private void beginTask(String name, int totalWork) {
// Avoids InvalidThreadAccess exceptions when called from another thread
Display.getDefault().asyncExec(new ProgressTaskBegin(name, totalWork));
}
private void resetControls() {
setMessage("");
setControlsEnabledState(true);
}
// override method to use "Login" as label for the OK button
@Override
protected void createButtonsForButtonBar(Composite parent) {
btnProceed = createButton(parent, IDialogConstants.PROCEED_ID, IDialogConstants.PROCEED_LABEL, true);
btnCancel = createButton(parent, IDialogConstants.STOP_ID, IDialogConstants.CANCEL_LABEL, false);
btnProceed.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
setControlsEnabledState(false);
setMessage("Waiting...");
if(chkSaveParamsPath.getSelection()) {
Activator.getDefault().getPreferenceStore().setValue("PARAMFILE", txtParams.getText());
}
if(chkSaveResultsPath.getSelection()) {
Activator.getDefault().getPreferenceStore().setValue("RESULTFILE", txtResults.getText());
}
bIsPeriodic = btnPeriodic.getSelection();
StateBasedWithParametersCommand.acquireModel();
StateBasedWithParametersCommand.setParamsFilePath(txtParams.getText());
StateBasedWithParametersCommand.setResultsFilePath(txtResults.getText());
btnCancel.setText(IDialogConstants.STOP_LABEL);
btnCancel.setEnabled(true);
btnProceed.setEnabled(false);
if(bIsPeriodic) {
currentJob = executorService.scheduleAtFixedRate(PeriodicExecutionDialog.this, 0, iInterval, TimeUnit.SECONDS);
}else{
currentJob = executorService.submit(PeriodicExecutionDialog.this);
}
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
// TODO Auto-generated method stub
}
});
btnCancel.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
cancelPressed();
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
// TODO Auto-generated method stub
}
});
}
protected IProgressMonitor getMonitor() {
return monitor;
}
@Override
protected Point getInitialSize() {
return new Point(650, 390);
}
@Override
protected void okPressed() {
super.okPressed();
}
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public void run() {
Date nextRun = new Date(new Date().getTime() + iInterval*1000);
setMessage("Running...");
beginTask("Analysis", 100);
StateBasedWithParametersCommand.runStateBased();
if(bIsPeriodic) {
setMessage("Waiting until... " + nextRun + " (estimated)");
}else{
setMessage("Done.");
setControlsEnabledState(true);
}
}
@Override
protected void cancelPressed() {
if(currentJob != null)
currentJob.cancel(true);
resetControls();
if(btnCancel.getText() == IDialogConstants.STOP_LABEL) {
btnCancel.setText(IDialogConstants.CANCEL_LABEL);
btnProceed.setEnabled(true);
setControlsEnabledState(true);
}else{
executorService.shutdownNow();
super.cancelPressed();
}
};
@Override
protected boolean isResizable() {
return true;
}
protected void progress(final int work) {
if(monitor != null) {
Display.getDefault().asyncExec(new Runnable() {
@Override
public void run() {
if(!monitor.isDisposed())
monitor.worked(work);
}
});
}
}
protected void subTask(final String name) {
if(monitor != null) {
Display.getDefault().asyncExec(new Runnable() {
@Override
public void run() {
if(!monitor.isDisposed())
monitor.subTask(name);
}
});
}
}
protected void stopMonitor() {
if(monitor != null) {
Display.getDefault().asyncExec(new Runnable() {
@Override
public void run() {
if(!monitor.isDisposed())
monitor.setVisible(false);
}
});
}
}
}