summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Heher <jakob.heher@iaik.tugraz.at>2022-07-06 14:22:19 +0200
committerJakob Heher <jakob.heher@iaik.tugraz.at>2022-07-06 14:22:19 +0200
commit7ed30d78c576e5c6f7193ee917309bafb0eb35ea (patch)
treefbe976b1a6688f628390c0fcdc943cf2ba7da4bc
parent18b4c5edd2a2d88d5efa69a1023a13926c53e8fd (diff)
downloadpdf-over-7ed30d78c576e5c6f7193ee917309bafb0eb35ea.tar.gz
pdf-over-7ed30d78c576e5c6f7193ee917309bafb0eb35ea.tar.bz2
pdf-over-7ed30d78c576e5c6f7193ee917309bafb0eb35ea.zip
YAGNI: StateMachine interface
-rw-r--r--pdf-over-gui/src/main/java/at/asit/pdfover/gui/Main.java9
-rw-r--r--pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/StateMachine.java308
-rw-r--r--pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/StateMachineImpl.java388
3 files changed, 261 insertions, 444 deletions
diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/Main.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/Main.java
index e603cd5b..c41b59de 100644
--- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/Main.java
+++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/Main.java
@@ -22,10 +22,11 @@ import java.io.IOException;
import javax.swing.JOptionPane;
import at.asit.pdfover.commons.Constants;
+import at.asit.pdfover.gui.workflow.StateMachine;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import at.asit.pdfover.gui.workflow.StateMachineImpl;
import iaik.security.provider.IAIK;
/**
@@ -61,12 +62,8 @@ public class Main {
// force keystore type (Adoptium JRE 17 still ships with JKS)
System.setProperty("javax.net.ssl.trustStoreType", "jks");
- StateMachineImpl stateMachine = new StateMachineImpl(args);
-
log.debug("Starting stateMachine ...");
- stateMachine.start();
-
-
+ (new StateMachine(args)).start();
log.debug("Ended stateMachine ...");
}
catch (Throwable e) {
diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/StateMachine.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/StateMachine.java
index 85539eb5..9a71bde2 100644
--- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/StateMachine.java
+++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/StateMachine.java
@@ -15,93 +15,301 @@
*/
package at.asit.pdfover.gui.workflow;
+//Imports
+import java.lang.reflect.Constructor;
+
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.asit.pdfover.gui.MainWindow;
+import at.asit.pdfover.gui.controls.Dialog.BUTTONS;
+import at.asit.pdfover.gui.controls.ErrorDialog;
+import at.asit.pdfover.commons.Messages;
import at.asit.pdfover.gui.workflow.config.ConfigManipulator;
import at.asit.pdfover.gui.workflow.config.ConfigOverlayManipulator;
import at.asit.pdfover.gui.workflow.config.ConfigProvider;
+import at.asit.pdfover.gui.workflow.config.ConfigProviderImpl;
import at.asit.pdfover.gui.workflow.config.PersistentConfigProvider;
+import at.asit.pdfover.gui.workflow.states.PrepareConfigurationState;
import at.asit.pdfover.gui.workflow.states.State;
/**
- *
+ * Workflow holds logical state of signing process and updates the current
+ * logical state
*/
-public interface StateMachine {
- /**
- * Get the ConfigProvider
- * @return the ConfigProvider
- */
- public ConfigProvider getConfigProvider();
+public class StateMachine implements GUIProvider {
- /**
- * Get the PersistentConfigProvider
- * @return the PersistentConfigProvider
- */
- public PersistentConfigProvider getPersistentConfigProvider();
+ private static final Logger log = LoggerFactory.getLogger(StateMachine.class);
+
+ private Status status;
+
+ private PDFSignerImpl pdfSigner;
+
+ private ConfigProviderImpl configProvider;
/**
- * Gets the Config Manipulator
- * @return the config manipulator
+ * Default constructor
+ *
+ * @param cmdLineArgs
*/
- public ConfigManipulator getConfigManipulator();
+ public StateMachine(String[] cmdLineArgs) {
+ this.status = new Status();
+ this.status.setCurrentState(new PrepareConfigurationState(this));
+ this.pdfSigner = new PDFSignerImpl();
+ this.configProvider = new ConfigProviderImpl();
+ setCmdLineArgs(cmdLineArgs);
+ }
/**
- * Gets the Config Overlay Manipulator
- * @return the config overlay manipulator
+ * Sets the workflow state
+ * This method should be used to let the user jump
+ * around between states. This Method also resets certain properties defined
+ * by later states then state
+ *
+ * @param state
*/
- public ConfigOverlayManipulator getConfigOverlayManipulator();
+ public void jumpToState(State state) {
+ this.status.setCurrentState(state);
+ this.invokeUpdate();
+ }
/**
- * Get the PDF Signer
- * @return the PDF Signer
+ * Update workflow logic and let state machine do its job...
*/
- public PDFSigner getPDFSigner();
+ public synchronized void update() {
+ State next = null;
+ while (this.status.getCurrentState() != null) {
+ State current = this.status.getCurrentState();
+ try {
+ current.run();
+ } catch (Exception e) {
+ log.error("StateMachine update: ", e);
+ ErrorDialog errorState = new ErrorDialog(this.getMainShell(),
+ Messages.getString("error.Unexpected"), BUTTONS.OK);
+ //errorState.setException(e);
+ //jumpToState(errorState);
+ errorState.open();
+ this.exit();
+ }
+
+ if (this.exit) {
+ // exit request ignore
+ next = null;
+ this.status.setCurrentState(next);
+ } else {
+
+ if (this.mainWindow != null
+ && !this.mainWindow.getShell().isDisposed()) {
+ log.debug("Allowing MainWindow to update its state for "
+ + current);
+ current.updateMainWindowBehavior();
+ this.mainWindow.applyBehavior();
+ this.mainWindow.doLayout();
+ }
+ next = current.nextState();
+ if (next == current) {
+ break;
+ }
+
+ if (next == null) {
+ log.info("Next state is null -> exit");
+ this.status.setCurrentState(next);
+ break;
+ }
+
+ log.debug("Changing state from: "
+ + current + " to "
+ + next.toString());
+ this.status.setCurrentState(next);
+ }
+ }
+ }
/**
- * Get the Status
- * @return the Status
+ * Invoke Update in UI (Main) Thread
*/
- public Status getStatus();
+ public void invokeUpdate() {
+ if (this.display != null) {
+ this.display.asyncExec(() -> {
+ this.update();
+ });
+ }
+ }
- /**
- * Gets the GUI provider
- * @return the GUI provider
+ private Display display = null;
+
+ private Shell shell = null;
+
+ private Composite container = null;
+
+ private MainWindow mainWindow = null;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * at.asit.pdfover.gui.workflow.StateMachine#display(org.eclipse.swt.widgets
+ * .Composite)
*/
- public GUIProvider getGUIProvider();
+ public void display(Composite composite) {
+ this.mainWindow.setTopControl(composite);
+ }
+
+ private void createMainWindow() {
+ try {
+
+ this.display = Display.getDefault();
+
+ this.mainWindow = new MainWindow(this);
+ this.mainWindow.open();
+
+ this.shell = this.mainWindow.getShell();
+
+ this.container = this.mainWindow.getContainer();
+
+ this.shell.open();
+ this.shell.layout();
+ } catch (Exception e) {
+ log.warn("Main-Window creation FAILED. Reason: " + e.getMessage());
+ this.display = null;
+ this.mainWindow = null;
+ this.shell = null;
+ this.container = null;
+ throw e;
+ }
+ }
/**
- * Jump to specific state
- *
- * Sets the state machine state this method should be used to let the user jump
- * around between states. This Method also resets certain properties defined
- * by later states then the target state.
- *
- * Example: Usually the MainWindow allows the user to jump to the states:
- * DataSourceSelectionState, PositioningState and BKUSelectionState
+ * Gets the Shell for drawing the ui
*
- * @param state the state to jump to
+ * @return Composite
*/
- public void jumpToState(State state);
+ public synchronized Composite getComposite() {
+ // Main window will be built on first call
+ // returns SWT Composite container for states to draw their GUI
+
+ if (this.container == null) {
+ this.createMainWindow();
+ }
+
+ return this.container;
+ }
+
+ public <T> T createComposite(Class<T> compositeClass, int style, State state) {
+ T composite = null;
+ try {
+ Constructor<T> constructor = compositeClass.getDeclaredConstructor(
+ Composite.class, int.class, State.class);
+ composite = constructor.newInstance(getComposite(), style, state);
+ } catch (Exception e) {
+ log.error("Could not create Composite for Class "
+ + compositeClass.getName(), e);
+ }
+ return composite;
+ }
/**
- * Update state machine
- * Calls the next state.
+ * Only returns a shell if one was already created ...
+ *
+ * @return
*/
- public void update();
+ private Shell nonCreatingGetShell() {
+ return this.shell;
+ }
+
+ private boolean exit = false;
/**
- * Update state machine from other thread
- * Calls the next state within the main thread
+ * Exists the Workflow
*/
- public void invokeUpdate();
+ public void exit() {
+ this.exit = true;
+ if (this.shell != null) {
+ this.shell.dispose();
+ }
+ }
/**
- * Exit state machine execution
+ * Only returns a shell if one was already created ...
+ *
+ * @return
*/
- public void exit();
+ private Display nonCreatingGetDisplay() {
+ return this.display;
+ }
/**
- * Gets the command line arguments
- *
- * @return the command line arguments
+ * Workflow main entrance point
*/
- public String[] getCmdArgs();
+ public void start() {
+
+ // Call update to start processing ...
+ update();
+
+ // if a user interaction is required we have a shell ...
+ Shell shell = nonCreatingGetShell();
+ Display display = nonCreatingGetDisplay();
+
+ if (this.status.getCurrentState() == null) {
+ if (shell != null) {
+ this.shell.dispose();
+ }
+ }
+
+ if (shell != null && display != null) {
+ while (!shell.isDisposed()) {
+ if (!display.readAndDispatch()) {
+ display.sleep();
+ }
+ }
+ display.dispose();
+ }
+ }
+ public ConfigProvider getConfigProvider() {
+ return this.configProvider;
+ }
+ public PersistentConfigProvider getPersistentConfigProvider() {
+ return this.configProvider;
+ }
+ public ConfigManipulator getConfigManipulator() {
+ return this.configProvider;
+ }
+ public ConfigOverlayManipulator getConfigOverlayManipulator() {
+ return this.configProvider;
+ }
+ public Status getStatus() {
+ return this.status;
+ }
+
+ public PDFSigner getPDFSigner() {
+ return this.pdfSigner;
+ }
+
+ public GUIProvider getGUIProvider() {
+ return this;
+ }
+
+ private String[] cmdLineArgs = new String[] {};
+ private void setCmdLineArgs(String[] cmdLineArgs) {
+ this.cmdLineArgs = cmdLineArgs;
+ }
+ public String[] getCmdArgs() {
+ return this.cmdLineArgs;
+ }
+
+
+ public synchronized Shell getMainShell() {
+ if(this.shell == null) {
+ this.createMainWindow();
+ }
+
+ return this.shell;
+ }
+
+ public void reloadResources() {
+ this.mainWindow.reloadLocalization();
+ }
}
diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/StateMachineImpl.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/StateMachineImpl.java
deleted file mode 100644
index 640d42bc..00000000
--- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/StateMachineImpl.java
+++ /dev/null
@@ -1,388 +0,0 @@
-/*
- * Copyright 2012 by A-SIT, Secure Information Technology Center Austria
- *
- * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- * http://joinup.ec.europa.eu/software/page/eupl
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- */
-package at.asit.pdfover.gui.workflow;
-
-//Imports
-import java.lang.reflect.Constructor;
-
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Shell;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import at.asit.pdfover.gui.MainWindow;
-import at.asit.pdfover.gui.controls.Dialog.BUTTONS;
-import at.asit.pdfover.gui.controls.ErrorDialog;
-import at.asit.pdfover.commons.Messages;
-import at.asit.pdfover.gui.workflow.config.ConfigManipulator;
-import at.asit.pdfover.gui.workflow.config.ConfigOverlayManipulator;
-import at.asit.pdfover.gui.workflow.config.ConfigProvider;
-import at.asit.pdfover.gui.workflow.config.ConfigProviderImpl;
-import at.asit.pdfover.gui.workflow.config.PersistentConfigProvider;
-import at.asit.pdfover.gui.workflow.states.PrepareConfigurationState;
-import at.asit.pdfover.gui.workflow.states.State;
-
-/**
- * Workflow holds logical state of signing process and updates the current
- * logical state
- */
-public class StateMachineImpl implements StateMachine, GUIProvider {
-
- /**
- * SLF4J Logger instance
- **/
- private static final Logger log = LoggerFactory
- .getLogger(StateMachineImpl.class);
-
- private StatusImpl status;
-
- private PDFSignerImpl pdfSigner;
-
- private ConfigProviderImpl configProvider;
-
- /**
- * Default constructor
- *
- * @param cmdLineArgs
- */
- public StateMachineImpl(String[] cmdLineArgs) {
- this.status = new StatusImpl();
- this.status.setCurrentState(new PrepareConfigurationState(this));
- this.pdfSigner = new PDFSignerImpl();
- this.configProvider = new ConfigProviderImpl();
- setCmdLineArgs(cmdLineArgs);
- }
-
- /**
- * Sets the workflow state
- * This method should be used to let the user jump
- * around between states. This Method also resets certain properties defined
- * by later states then state
- *
- * @param state
- */
- @Override
- public void jumpToState(State state) {
- this.status.setCurrentState(state);
- this.invokeUpdate();
- }
-
- /**
- * Update workflow logic and let state machine do its job...
- */
- @Override
- public synchronized void update() {
- State next = null;
- while (this.status.getCurrentState() != null) {
- State current = this.status.getCurrentState();
- try {
- current.run();
- } catch (Exception e) {
- log.error("StateMachine update: ", e);
- ErrorDialog errorState = new ErrorDialog(this.getMainShell(),
- Messages.getString("error.Unexpected"), BUTTONS.OK);
- //errorState.setException(e);
- //jumpToState(errorState);
- errorState.open();
- this.exit();
- }
-
- if (this.exit) {
- // exit request ignore
- next = null;
- this.status.setCurrentState(next);
- } else {
-
- if (this.mainWindow != null
- && !this.mainWindow.getShell().isDisposed()) {
- log.debug("Allowing MainWindow to update its state for "
- + current);
- current.updateMainWindowBehavior();
- this.mainWindow.applyBehavior();
- this.mainWindow.doLayout();
- }
- next = current.nextState();
- if (next == current) {
- break;
- }
-
- if (next == null) {
- log.info("Next state is null -> exit");
- this.status.setCurrentState(next);
- break;
- }
-
- log.debug("Changing state from: "
- + current + " to "
- + next.toString());
- this.status.setCurrentState(next);
- }
- }
- }
-
- /**
- * Invoke Update in UI (Main) Thread
- */
- @Override
- public void invokeUpdate() {
- if (this.display != null) {
- this.display.asyncExec(() -> {
- StateMachineImpl.this.update();
- });
- }
- }
-
- private Display display = null;
-
- private Shell shell = null;
-
- private Composite container = null;
-
- private MainWindow mainWindow = null;
-
- /*
- * (non-Javadoc)
- *
- * @see
- * at.asit.pdfover.gui.workflow.StateMachine#display(org.eclipse.swt.widgets
- * .Composite)
- */
- @Override
- public void display(Composite composite) {
- this.mainWindow.setTopControl(composite);
- }
-
- private void createMainWindow() {
- try {
-
- this.display = Display.getDefault();
-
- this.mainWindow = new MainWindow(this);
- this.mainWindow.open();
-
- this.shell = this.mainWindow.getShell();
-
- this.container = this.mainWindow.getContainer();
-
- this.shell.open();
- this.shell.layout();
- } catch (Exception e) {
- log.warn("Main-Window creation FAILED. Reason: " + e.getMessage());
- this.display = null;
- this.mainWindow = null;
- this.shell = null;
- this.container = null;
- throw e;
- }
- }
-
- /**
- * Gets the Shell for drawing the ui
- *
- * @return Composite
- */
- public synchronized Composite getComposite() {
- // Main window will be built on first call
- // returns SWT Composite container for states to draw their GUI
-
- if (this.container == null) {
- this.createMainWindow();
- }
-
- return this.container;
- }
-
- @Override
- public <T> T createComposite(Class<T> compositeClass, int style, State state) {
- T composite = null;
- try {
- Constructor<T> constructor = compositeClass.getDeclaredConstructor(
- Composite.class, int.class, State.class);
- composite = constructor.newInstance(getComposite(), style, state);
- } catch (Exception e) {
- log.error("Could not create Composite for Class "
- + compositeClass.getName(), e);
- }
- return composite;
- }
-
- /**
- * Only returns a shell if one was already created ...
- *
- * @return
- */
- private Shell nonCreatingGetShell() {
- return this.shell;
- }
-
- private boolean exit = false;
-
- /**
- * Exists the Workflow
- */
- @Override
- public void exit() {
- this.exit = true;
- if (this.shell != null) {
- this.shell.dispose();
- }
- }
-
- /**
- * Only returns a shell if one was already created ...
- *
- * @return
- */
- private Display nonCreatingGetDisplay() {
- return this.display;
- }
-
- /**
- * Workflow main entrance point
- */
- public void start() {
-
- // Call update to start processing ...
- update();
-
- // if a user interaction is required we have a shell ...
- Shell shell = nonCreatingGetShell();
- Display display = nonCreatingGetDisplay();
-
- if (this.status.getCurrentState() == null) {
- if (shell != null) {
- this.shell.dispose();
- }
- }
-
- if (shell != null && display != null) {
- while (!shell.isDisposed()) {
- if (!display.readAndDispatch()) {
- display.sleep();
- }
- }
- display.dispose();
- }
- }
-
- /*
- * (non-Javadoc)
- * @see at.asit.pdfover.gui.workflow.StateMachine#getConfigProvider()
- */
- @Override
- public ConfigProvider getConfigProvider() {
- return this.configProvider;
- }
-
- /*
- * (non-Javadoc)
- * @see at.asit.pdfover.gui.workflow.StateMachine#getConfigProvider()
- */
- @Override
- public PersistentConfigProvider getPersistentConfigProvider() {
- return this.configProvider;
- }
-
- /* (non-Javadoc)
- * @see at.asit.pdfover.gui.workflow.StateMachine#getConfigManipulator()
- */
- @Override
- public ConfigManipulator getConfigManipulator() {
- return this.configProvider;
- }
-
- /* (non-Javadoc)
- * @see at.asit.pdfover.gui.workflow.StateMachine#getConfigOverlayManipulator()
- */
- @Override
- public ConfigOverlayManipulator getConfigOverlayManipulator() {
- return this.configProvider;
- }
-
- /*
- * (non-Javadoc)
- * @see at.asit.pdfover.gui.workflow.StateMachine#getStatus()
- */
- @Override
- public Status getStatus() {
- return this.status;
- }
-
- /*
- * (non-Javadoc)
- * @see at.asit.pdfover.gui.workflow.StateMachine#getPDFSigner()
- */
- @Override
- public PDFSigner getPDFSigner() {
- return this.pdfSigner;
- }
-
- /*
- * (non-Javadoc)
- * @see at.asit.pdfover.gui.workflow.StateMachine#getGUIProvider()
- */
- @Override
- public GUIProvider getGUIProvider() {
- return this;
- }
-
- // Data Section
- // =============================================================================
-
- // Command Line Arguments
- // -------------------------------------------------------
- private String[] cmdLineArgs = new String[] {};
-
- /**
- * sets the command line arguments
- *
- * @param cmdLineArgs
- */
- private void setCmdLineArgs(String[] cmdLineArgs) {
- this.cmdLineArgs = cmdLineArgs;
- }
-
- /**
- * Gets the command line arguments
- *
- * @return the command line arguments
- */
- @Override
- public String[] getCmdArgs() {
- return this.cmdLineArgs;
- }
-
- /* (non-Javadoc)
- * @see at.asit.pdfover.gui.workflow.GUIProvider#getMainShell()
- */
- @Override
- public synchronized Shell getMainShell() {
- if(this.shell == null) {
- this.createMainWindow();
- }
-
- return this.shell;
- }
-
- /* (non-Javadoc)
- * @see at.asit.pdfover.gui.workflow.GUIProvider#reloadResources()
- */
- @Override
- public void reloadResources() {
- this.mainWindow.reloadLocalization();
- }
-}