From 23ae1caefcf0cc99c2b90327afaff6376ecc552a Mon Sep 17 00:00:00 2001
From: tkellner <tkellner@174cde9d-5d70-4d2a-aa98-46368bc2aaf7>
Date: Wed, 10 Apr 2013 18:53:41 +0000
Subject: PDF-AS signature working with local BKU

git-svn-id: https://joinup.ec.europa.eu/svn/pdf-over/trunk@26 174cde9d-5d70-4d2a-aa98-46368bc2aaf7
---
 .../gui/composites/BKUSelectionComposite.java      |   8 +-
 .../pdfover/gui/composites/ErrorComposite.java     | 123 ++++++++++++
 .../pdfover/gui/composites/OutputComposite.java    | 221 +++++++++++++++++++++
 .../pdfover/gui/workflow/StateMachineImpl.java     |  15 +-
 .../java/at/asit/pdfover/gui/workflow/Status.java  |  26 +++
 .../at/asit/pdfover/gui/workflow/StatusImpl.java   |  43 +++-
 .../pdfover/gui/workflow/states/ErrorState.java    | 116 +++++++++++
 .../pdfover/gui/workflow/states/LocalBKUState.java | 155 ++++++++++++++-
 .../pdfover/gui/workflow/states/OutputState.java   |  40 +++-
 .../gui/workflow/states/PrepareSigningState.java   |  83 ++++----
 .../pdfover/gui/workflow/states/SigningState.java  |  55 ++++-
 11 files changed, 820 insertions(+), 65 deletions(-)
 create mode 100644 pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/ErrorComposite.java
 create mode 100644 pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/OutputComposite.java
 create mode 100644 pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/ErrorState.java

(limited to 'pdf-over-gui/src/main/java')

diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/BKUSelectionComposite.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/BKUSelectionComposite.java
index 24be2c5a..893b0e87 100644
--- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/BKUSelectionComposite.java
+++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/BKUSelectionComposite.java
@@ -27,8 +27,6 @@ import org.eclipse.swt.widgets.Composite;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import at.asit.pdfover.gui.workflow.StateMachine;
-import at.asit.pdfover.gui.workflow.states.BKUSelectionState;
 import at.asit.pdfover.gui.workflow.states.BKUSelectionState.BKUs;
 import at.asit.pdfover.gui.workflow.states.State;
 
@@ -52,7 +50,7 @@ public class BKUSelectionComposite extends StateComposite {
 
 		@Override
 		public void widgetSelected(SelectionEvent e) {
-			log.debug("Setting BKU to LOCAL");
+			log.debug("Setting BKU to LOCAL"); //$NON-NLS-1$
 			setSelected(BKUs.LOCAL);
 		}
 
@@ -76,7 +74,7 @@ public class BKUSelectionComposite extends StateComposite {
 
 		@Override
 		public void widgetSelected(SelectionEvent e) {
-			log.debug("Setting BKU to MOBILE");
+			log.debug("Setting BKU to MOBILE"); //$NON-NLS-1$
 			setSelected(BKUs.MOBILE);
 		}
 
@@ -89,7 +87,7 @@ public class BKUSelectionComposite extends StateComposite {
 	/**
 	 * SLF4J Logger instance
 	 **/
-	private static final Logger log = LoggerFactory
+	static final Logger log = LoggerFactory
 			.getLogger(BKUSelectionComposite.class);
 
 	private BKUs selected = BKUs.NONE;
diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/ErrorComposite.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/ErrorComposite.java
new file mode 100644
index 00000000..6963c6f6
--- /dev/null
+++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/ErrorComposite.java
@@ -0,0 +1,123 @@
+/*
+ * 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.composites;
+
+// Imports
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.layout.FormLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import at.asit.pdfover.gui.workflow.states.State;
+
+/**
+ * 
+ */
+public class ErrorComposite extends StateComposite {
+	/**
+	 * 
+	 */
+	private final class OkSelectionListener implements SelectionListener {
+		@Override
+		public void widgetSelected(SelectionEvent e) {
+			ErrorComposite.this.userOk = true;
+			ErrorComposite.this.state.updateStateMachine();
+		}
+
+		@Override
+		public void widgetDefaultSelected(SelectionEvent e) {
+			// Nothing to do
+		}
+	}
+
+	/**
+	 * SLF4J Logger instance
+	 **/
+	private static final Logger log = LoggerFactory
+			.getLogger(ErrorComposite.class);
+
+	boolean userOk = false;
+	
+	/**
+	 * Checks if the user has clicked OK
+	 * @return
+	 */
+	public boolean isUserOk() {
+		return userOk;
+	}
+
+	private Exception exception;
+	
+	
+	/**
+	 * Sets the Exception to present
+	 * @param exception the exception
+	 */
+	public void setException(Exception exception) {
+		this.exception = exception;
+	}
+
+	/**
+	 * Create the composite.
+	 * @param parent
+	 * @param style
+	 */
+	public ErrorComposite(Composite parent, int style, State state) {
+		super(parent, style, state);
+
+		this.setLayout(new FormLayout());
+
+		Label lbl_message = new Label(this, SWT.NATIVE | SWT.RESIZE);
+		FormData fd_lbl_message = new FormData();
+		fd_lbl_message.left = new FormAttachment(10, 0);
+		fd_lbl_message.right = new FormAttachment(90, 0);
+		fd_lbl_message.top = new FormAttachment(40, 0);
+		fd_lbl_message.bottom = new FormAttachment(50, 0);
+		lbl_message.setLayoutData(fd_lbl_message);
+		lbl_message.setText(this.exception.getMessage());
+		
+		Button btn_ok = new Button(this, SWT.NATIVE | SWT.RESIZE);
+		btn_ok.setText("OK");
+		// Point mobile_size = btn_mobile.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+		FormData fd_btn_ok = new FormData();
+		fd_btn_ok.left = new FormAttachment(45, 0);
+		fd_btn_ok.right = new FormAttachment(55, 0);
+		fd_btn_ok.top = new FormAttachment(70, 0);
+		fd_btn_ok.bottom = new FormAttachment(75, 0);
+		btn_ok.setLayoutData(fd_btn_ok);
+		btn_ok.addSelectionListener(new OkSelectionListener());
+	}
+
+	@Override
+	protected void checkSubclass() {
+		// Disable the check that prevents subclassing of SWT components
+	}
+
+	/* (non-Javadoc)
+	 * @see at.asit.pdfover.gui.composites.StateComposite#doLayout()
+	 */
+	@Override
+	public void doLayout() {
+		// TODO Auto-generated method stub
+	}
+
+}
diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/OutputComposite.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/OutputComposite.java
new file mode 100644
index 00000000..860cd095
--- /dev/null
+++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/OutputComposite.java
@@ -0,0 +1,221 @@
+/*
+ * 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.composites;
+
+// Imports
+import java.awt.Desktop;
+import org.eclipse.swt.widgets.FileDialog;
+import java.io.File;
+import java.io.FileOutputStream;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.layout.FormLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.asit.pdfover.gui.workflow.states.State;
+import at.asit.pdfover.signator.DocumentSource;
+
+/**
+ * GUI component for Output State
+ */
+public class OutputComposite extends StateComposite {
+	
+	/**
+	 * Selection Listner for save button
+	 */
+	private final class SaveSelectionListener implements SelectionListener {
+		
+		/**
+		 * Default constructor 
+		 */
+		public SaveSelectionListener() {
+			// Nothing to do
+		}
+
+		@Override
+		public void widgetSelected(SelectionEvent e) {
+			try {
+				FileDialog save = new FileDialog(OutputComposite.this.getShell(), SWT.SAVE | SWT.NATIVE);
+				save.setFilterExtensions(new String[] {"*.pdf"});
+				save.setFilterNames(new String[] {"PDF Dateien"});
+				
+				String target = save.open();
+				
+				File targetFile = new File(target);
+				
+				DocumentSource source = OutputComposite.this
+						.getSignedDocument();
+				
+				FileOutputStream outstream = new FileOutputStream(targetFile);
+				outstream.write(source.getByteArray(), 0,
+						source.getByteArray().length);
+				outstream.close();
+				
+				OutputComposite.this.savedFile = targetFile;
+				
+			} catch (Exception ex) {
+				log.error("SaveSelectionListener: ", ex); //$NON-NLS-1$
+			}
+		}
+
+		@Override
+		public void widgetDefaultSelected(SelectionEvent e) {
+			// Nothing todo
+		}
+	}
+
+	/**
+	 * Selection Listner for open button
+	 */
+	private final class OpenSelectionListener implements SelectionListener {
+		
+		/**
+		 * Default constructor
+		 */
+		public OpenSelectionListener() {
+			// Nothing to do
+		}
+
+		@Override
+		public void widgetSelected(SelectionEvent e) {
+			try {
+				DocumentSource source = OutputComposite.this
+						.getSignedDocument();
+
+				if (source != null) {
+					File open = OutputComposite.this.savedFile;
+					if (open == null) {
+						// Save as temp file ...
+						open = new File("tmp_signed.pdf");
+						FileOutputStream outstream = new FileOutputStream(open);
+						outstream.write(source.getByteArray(), 0,
+								source.getByteArray().length);
+						outstream.close();
+					}
+
+					if (open.exists()) {
+						// Desktop supported check allready done in constructor
+						Desktop.getDesktop().open(open);
+						return;
+					}
+				} else {
+					// TODO: Handle exception ...
+				}
+			} catch (Exception ex) {
+				log.error("OpenSelectionListener: ", ex); //$NON-NLS-1$
+			}
+		}
+
+		@Override
+		public void widgetDefaultSelected(SelectionEvent e) {
+			// Nothing todo
+		}
+	}
+
+	/**
+	 * SLF4J Logger instance
+	 **/
+	private static final Logger log = LoggerFactory
+			.getLogger(OutputComposite.class);
+
+	File savedFile = null;
+
+	private DocumentSource signedDocument;
+
+	/**
+	 * Create the composite.
+	 * 
+	 * @param parent
+	 *            The parent composite
+	 * @param style
+	 *            The swt style
+	 * @param state
+	 *            The owning state
+	 */
+	public OutputComposite(Composite parent, int style, State state) {
+		super(parent, style, state);
+
+		this.setLayout(new FormLayout());
+
+		Button btn_open = new Button(this, SWT.NATIVE | SWT.RESIZE);
+		btn_open.setText("OPEN");
+		// Point mobile_size = btn_mobile.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+		FormData fd_btn_open = new FormData();
+		fd_btn_open.left = new FormAttachment(40, 0);
+		fd_btn_open.right = new FormAttachment(50, 0);
+		fd_btn_open.top = new FormAttachment(45, 0);
+		fd_btn_open.bottom = new FormAttachment(55, 0);
+		btn_open.setLayoutData(fd_btn_open);
+		btn_open.addSelectionListener(new OpenSelectionListener());
+
+		if (!Desktop.isDesktopSupported()) {
+			btn_open.setEnabled(false);
+		}
+
+		Button btn_save = new Button(this, SWT.NATIVE | SWT.RESIZE);
+		btn_save.setText("SAVE");
+		// Point card_size = btn_card.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+		FormData fd_btn_save = new FormData();
+		fd_btn_save.left = new FormAttachment(50, 0);
+		fd_btn_save.right = new FormAttachment(60, 0);
+		fd_btn_save.top = new FormAttachment(45, 0);
+		fd_btn_save.bottom = new FormAttachment(55, 0);
+		btn_save.setLayoutData(fd_btn_save);
+		btn_save.addSelectionListener(new SaveSelectionListener());
+
+		this.pack();
+	}
+
+	/**
+	 * Gets the signed document
+	 * @return the signed document
+	 */
+	public DocumentSource getSignedDocument() {
+		return this.signedDocument;
+	}
+
+	/**
+	 * Sets the signed document
+	 * @param signedDocument the signed document
+	 */
+	public void setSignedDocument(final DocumentSource signedDocument) {
+		this.signedDocument = signedDocument;
+	}
+
+	@Override
+	protected void checkSubclass() {
+		// Disable the check that prevents subclassing of SWT components
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see at.asit.pdfover.gui.composites.StateComposite#doLayout()
+	 */
+	@Override
+	public void doLayout() {
+		// TODO Auto-generated method stub
+
+	}
+
+}
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
index 5ad800e9..cf764a73 100644
--- 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
@@ -80,7 +80,14 @@ public class StateMachineImpl implements StateMachine, GUIProvider {
 		State next = null;
 		while (this.status.getCurrentState() != null) {
 			State current = this.status.getCurrentState();
-			current.run();
+			try
+			{
+				current.run();
+			}
+			catch(Exception e) {
+				log.error("StateMachine update: ", e); //$NON-NLS-1$
+				// TODO: GOTO generic error state!
+			}
 			if (this.mainWindow != null
 					&& !this.mainWindow.getShell().isDisposed()) {
 				log.debug("Allowing MainWindow to update its state for " //$NON-NLS-1$
@@ -98,11 +105,13 @@ public class StateMachineImpl implements StateMachine, GUIProvider {
 					+ next.toString());
 			this.status.setCurrentState(next);
 		}
+		
+		// TODO: Remove following line when releasing ...
 		if (this.status.getCurrentState() != null) {
 			this.setCurrentStateMessage(this.status.getCurrentState()
 					.toString());
 		} else {
-			this.setCurrentStateMessage("");
+			this.setCurrentStateMessage(""); //$NON-NLS-1$
 		}
 	}
 
@@ -197,7 +206,7 @@ public class StateMachineImpl implements StateMachine, GUIProvider {
 			composite = constructor.newInstance(getComposite(), style, state);
 		} catch (Exception e) {
 			log.error(
-					"Could not create Composite for Class "
+					"Could not create Composite for Class " //$NON-NLS-1$
 							+ compositeClass.getName(), e);
 		}
 		return composite;
diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/Status.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/Status.java
index e0a7b0d4..ba3c210b 100644
--- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/Status.java
+++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/Status.java
@@ -20,7 +20,9 @@ import java.io.File;
 import at.asit.pdfover.gui.MainWindowBehavior;
 import at.asit.pdfover.gui.workflow.states.BKUSelectionState;
 import at.asit.pdfover.gui.workflow.states.State;
+import at.asit.pdfover.signator.SignResult;
 import at.asit.pdfover.signator.SignaturePosition;
+import at.asit.pdfover.signator.SigningState;
 
 /**
  * Interface for persistent status of state machine
@@ -79,4 +81,28 @@ public interface Status {
 	 * @return the previous State
 	 */
 	public State getPreviousState();
+	
+	/**
+	 * Gets the signing state
+	 * @return the signing state
+	 */
+	public SigningState getSigningState();
+	
+	/**
+	 * Sets the signing state
+	 * @param state the signing state
+	 */
+	public void setSigningState(SigningState state);
+	
+	/**
+	 * Sets the sign result
+	 * @param signResult
+	 */
+	public void setSignResult(SignResult signResult);
+	
+	/**
+	 * Gets the sign Result
+	 * @return the sign result
+	 */
+	public SignResult getSignResult();
 }
diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/StatusImpl.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/StatusImpl.java
index c8d74161..5f0f53b7 100644
--- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/StatusImpl.java
+++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/StatusImpl.java
@@ -24,7 +24,9 @@ import org.slf4j.LoggerFactory;
 import at.asit.pdfover.gui.MainWindowBehavior;
 import at.asit.pdfover.gui.workflow.states.State;
 import at.asit.pdfover.gui.workflow.states.BKUSelectionState.BKUs;
+import at.asit.pdfover.signator.SignResult;
 import at.asit.pdfover.signator.SignaturePosition;
+import at.asit.pdfover.signator.SigningState;
 
 /**
  * 
@@ -33,7 +35,6 @@ public class StatusImpl implements Status {
 	/**
 	 * SLF4J Logger instance
 	 **/
-	@SuppressWarnings("unused")
 	private static final Logger log = LoggerFactory.getLogger(StatusImpl.class);
 
 	private File document = null;
@@ -46,6 +47,10 @@ public class StatusImpl implements Status {
 
 	private State previousState = null;
 
+	private SigningState signingState = null;
+	
+	private SignResult signResult = null;
+	
 	private MainWindowBehavior behavior;
 
 
@@ -67,12 +72,12 @@ public class StatusImpl implements Status {
 	 */
 	public void setCurrentState(State currentState) {
 		if (this.previousState == this.currentState)
-			log.error("Changing to same state? " + this.currentState);
+			log.error("Changing to same state? " + this.currentState); //$NON-NLS-1$
 
 		if (this.previousState != null && this.previousState != currentState)
 		{
 			//Reference to previous state will be lost - perform cleanup
-			log.debug("Cleaning up " + this.previousState);
+			log.debug("Cleaning up " + this.previousState); //$NON-NLS-1$
 			this.previousState.cleanUp();
 		}
 			
@@ -143,4 +148,36 @@ public class StatusImpl implements Status {
 	public MainWindowBehavior getBehavior() {
 		return this.behavior;
 	}
+
+	/* (non-Javadoc)
+	 * @see at.asit.pdfover.gui.workflow.Status#getSigningState()
+	 */
+	@Override
+	public SigningState getSigningState() {
+		return this.signingState;
+	}
+
+	/* (non-Javadoc)
+	 * @see at.asit.pdfover.gui.workflow.Status#setSigningState(at.asit.pdfover.signator.SigningState)
+	 */
+	@Override
+	public void setSigningState(SigningState state) {
+		this.signingState = state;
+	}
+
+	/* (non-Javadoc)
+	 * @see at.asit.pdfover.gui.workflow.Status#setSignResult(at.asit.pdfover.signator.SignResult)
+	 */
+	@Override
+	public void setSignResult(SignResult signResult) {
+		this.signResult = signResult;
+	}
+
+	/* (non-Javadoc)
+	 * @see at.asit.pdfover.gui.workflow.Status#getSignResult()
+	 */
+	@Override
+	public SignResult getSignResult() {
+		return this.signResult;
+	}
 }
diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/ErrorState.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/ErrorState.java
new file mode 100644
index 00000000..e444fbf9
--- /dev/null
+++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/ErrorState.java
@@ -0,0 +1,116 @@
+/*
+ * 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.states;
+
+// Imports
+import org.eclipse.swt.SWT;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.asit.pdfover.gui.composites.ErrorComposite;
+import at.asit.pdfover.gui.workflow.StateMachine;
+import at.asit.pdfover.gui.workflow.Status;
+
+/**
+ * 
+ */
+public class ErrorState extends State {
+	/**
+	 * @param stateMachine
+	 */
+	public ErrorState(StateMachine stateMachine) {
+		super(stateMachine);
+	}
+
+	private Exception exception;
+	
+	private boolean userInformed = false;
+	
+	/**
+	 * SLF4J Logger instance
+	 **/
+	static final Logger log = LoggerFactory.getLogger(ErrorState.class);
+
+	private ErrorComposite errorComposite = null;
+	
+	private ErrorComposite getComposite() {
+		if (this.errorComposite == null) {
+			this.errorComposite =
+					this.stateMachine.getGUIProvider().createComposite(ErrorComposite.class, SWT.RESIZE, this);
+		}
+
+		return this.errorComposite;
+	}
+	
+	/* (non-Javadoc)
+	 * @see at.asit.pdfover.gui.workflow.states.State#run()
+	 */
+	@Override
+	public void run() {
+		Status status = this.stateMachine.getStatus();
+		
+		if(this.errorComposite != null) {
+			this.userInformed = this.errorComposite.isUserOk();
+		}
+		
+		if(this.exception != null && !this.userInformed) {
+			// Display Exception ....
+			ErrorComposite errorComposite = this.getComposite();
+			this.errorComposite.setException(this.exception);
+			
+			this.userInformed = this.errorComposite.isUserOk();
+			
+			this.stateMachine.getGUIProvider().display(errorComposite);
+		}
+		
+		// TODO: Think should we do this? (possible infinity loop with exception ...)
+		this.setNextState(status.getPreviousState());
+	}
+
+	/* (non-Javadoc)
+	 * @see at.asit.pdfover.gui.workflow.states.State#cleanUp()
+	 */
+	@Override
+	public void cleanUp() {
+		// TODO
+	}
+
+	/* (non-Javadoc)
+	 * @see at.asit.pdfover.gui.workflow.states.State#updateMainWindowBehavior()
+	 */
+	@Override
+	public void updateMainWindowBehavior() {
+		// TODO Auto-generated method stub
+		
+	}
+
+	/**
+	 * Gets the Exception
+	 * @return the exception
+	 */
+	public Exception getException() {
+		return this.exception;
+	}
+
+	/**
+	 * Sets the Exception
+	 * @param exception the exception to set
+	 */
+	public void setException(Exception exception) {
+		this.exception = exception;
+	}
+
+}
diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/LocalBKUState.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/LocalBKUState.java
index 795090e7..c9c079a8 100644
--- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/LocalBKUState.java
+++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/LocalBKUState.java
@@ -18,15 +18,116 @@ package at.asit.pdfover.gui.workflow.states;
 // Imports
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.HttpException;
+import org.apache.commons.httpclient.HttpStatus;
+import org.apache.commons.httpclient.methods.PostMethod;
 import at.asit.pdfover.gui.MainWindowBehavior;
 import at.asit.pdfover.gui.MainWindow.Buttons;
 import at.asit.pdfover.gui.workflow.StateMachine;
+import at.asit.pdfover.gui.workflow.Status;
+import at.asit.pdfover.signator.SLRequest;
+import at.asit.pdfover.signator.SLResponse;
 
 /**
  * Logical state for performing the BKU Request to a local BKU
  */
 public class LocalBKUState extends State {
+	
+	/**
+	 * HTTP Response server HEADER
+	 */
+	public final static String BKU_REPSONE_HEADER_SERVER = "server"; //$NON-NLS-1$
+	
+	/**
+	 * HTTP Response user-agent HEADER
+	 */
+	public final static String BKU_REPSONE_HEADER_USERAGENT = "user-agent"; //$NON-NLS-1$
+	
+	/**
+	 * HTTP Response SignatureLayout HEADER
+	 */
+	public final static String BKU_REPSONE_HEADER_SIGNATURE_LAYOUT = "SignatureLayout"; //$NON-NLS-1$
+	
+	
+	/**
+	 * 
+	 */
+	private final class SignLocalBKUThread implements Runnable {
+
+		private LocalBKUState state;
+
+		/**
+		 * @param localBKUState
+		 */
+		public SignLocalBKUThread(LocalBKUState localBKUState) {
+			this.state = localBKUState;
+		}
+
+		@Override
+		public void run() {
+			try {
+				SLRequest request = this.state.signingState
+						.getSignatureRequest();
+
+				String b64_data = new String(Base64.encodeBase64(request
+						.getSignatureData().getByteArray()));
+
+				String sl_request = request.getRequest()
+						.replace(
+								SLRequest.DATAOBJECT_STRING,
+								"<sl:Base64Content>" + b64_data //$NON-NLS-1$
+										+ "</sl:Base64Content>"); //$NON-NLS-1$
+
+				HttpClient client = new HttpClient();
+				client.getParams().setParameter("http.useragent", //$NON-NLS-1$
+						"PDF-Over 4.0"); //$NON-NLS-1$
+
+				PostMethod method = new PostMethod(
+						"http://127.0.0.1:3495/http-security-layer-request"); //$NON-NLS-1$
+				method.addParameter("XMLRequest", sl_request); //$NON-NLS-1$
+
+				int returnCode = client.executeMethod(method);
+				
+				if(returnCode == HttpStatus.SC_OK)
+				{
+					String server = ""; //$NON-NLS-1$
+					String userAgent = ""; //$NON-NLS-1$
+					String signatureLayout = ""; //$NON-NLS-1$
+					
+					if(method.getResponseHeader(BKU_REPSONE_HEADER_SERVER) != null)
+					{
+						server = method.getResponseHeader(BKU_REPSONE_HEADER_SERVER).getValue();
+					}
+					
+					if(method.getResponseHeader(BKU_REPSONE_HEADER_USERAGENT) != null)
+					{
+						userAgent = method.getResponseHeader(BKU_REPSONE_HEADER_USERAGENT).getValue();
+					}
+					
+					if(method.getResponseHeader(BKU_REPSONE_HEADER_SIGNATURE_LAYOUT) != null)
+					{
+						signatureLayout = method.getResponseHeader(BKU_REPSONE_HEADER_SIGNATURE_LAYOUT).getValue();
+					}
+					
+					String response = method.getResponseBodyAsString();
+					log.debug("SL Response: " + response); //$NON-NLS-1$
+					SLResponse slResponse = new SLResponse(response, server, userAgent, signatureLayout);
+					this.state.signingState.setSignatureResponse(slResponse);
+				} else {
+					// TODO: Create HTTP exception
+					this.state.threadException = new HttpException(method.getResponseBodyAsString());
+				}
+
+			} catch (Exception e) {
+				log.error("SignLocalBKUThread: ", e); //$NON-NLS-1$
+			} finally {
+				this.state.stateMachine.invokeUpdate();
+			}
+		}
+	}
+
 	/**
 	 * @param stateMachine
 	 */
@@ -37,34 +138,66 @@ public class LocalBKUState extends State {
 	/**
 	 * SLF4J Logger instance
 	 **/
-	@SuppressWarnings("unused")
-	private static final Logger log = LoggerFactory
+	static final Logger log = LoggerFactory
 			.getLogger(LocalBKUState.class);
 
-	/* (non-Javadoc)
-	 * @see at.asit.pdfover.gui.workflow.WorkflowState#update(at.asit.pdfover.gui.workflow.Workflow)
+	at.asit.pdfover.signator.SigningState signingState;
+
+	Exception threadException = null;
+	
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * at.asit.pdfover.gui.workflow.WorkflowState#update(at.asit.pdfover.gui
+	 * .workflow.Workflow)
 	 */
 	@Override
 	public void run() {
-		// TODO Process SL Request and set SL Response
+		Status status = this.stateMachine.getStatus();
+
+		this.signingState = status.getSigningState();
+
+		if (!this.signingState.hasSignatureResponse() && 
+			this.threadException == null
+			) {
+			Thread t = new Thread(new SignLocalBKUThread(this));
+			t.start();
+			return;
+		}
+
+		if(this.threadException != null) {
+			// TODO: Jump to error state!
+		}
+		
+		if(!this.signingState.hasSignatureResponse()) {
+			// The thread should set the response or the thread exception!!!
+			// TODO: Jump to error state!
+		}
 		
+		// OK
 		this.setNextState(new SigningState(this.stateMachine));
 	}
 
-	/* (non-Javadoc)
+	/*
+	 * (non-Javadoc)
+	 * 
 	 * @see at.asit.pdfover.gui.workflow.states.State#cleanUp()
 	 */
 	@Override
 	public void cleanUp() {
 		// No composite - no cleanup necessary
 	}
-	
-	/* (non-Javadoc)
+
+	/*
+	 * (non-Javadoc)
+	 * 
 	 * @see at.asit.pdfover.gui.workflow.states.State#setMainWindowBehavior()
 	 */
 	@Override
 	public void updateMainWindowBehavior() {
-		MainWindowBehavior behavior = this.stateMachine.getStatus().getBehavior();
+		MainWindowBehavior behavior = this.stateMachine.getStatus()
+				.getBehavior();
 		behavior.reset();
 		behavior.setActive(Buttons.OPEN, true);
 		behavior.setActive(Buttons.POSITION, true);
@@ -72,7 +205,7 @@ public class LocalBKUState extends State {
 	}
 
 	@Override
-	public String toString()  {
+	public String toString() {
 		return this.getClass().getName();
 	}
 }
diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/OutputState.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/OutputState.java
index 7c16d559..50aee387 100644
--- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/OutputState.java
+++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/OutputState.java
@@ -16,12 +16,15 @@
 package at.asit.pdfover.gui.workflow.states;
 
 //Imports
+import org.eclipse.swt.SWT;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import at.asit.pdfover.gui.MainWindow.Buttons;
 import at.asit.pdfover.gui.MainWindowBehavior;
+import at.asit.pdfover.gui.composites.OutputComposite;
 import at.asit.pdfover.gui.workflow.StateMachine;
+import at.asit.pdfover.gui.workflow.Status;
 
 /**
  * Procduces the output of the signature process. (save file, open file)
@@ -41,11 +44,43 @@ public class OutputState extends State {
 	@SuppressWarnings("unused")
 	private static final Logger log = LoggerFactory.getLogger(OutputState.class);
 	
+	private OutputComposite outputComposite = null;
+
+	private OutputComposite getSelectionComposite() {
+		if (this.outputComposite == null) {
+			this.outputComposite =
+					this.stateMachine.getGUIProvider().createComposite(OutputComposite.class, SWT.RESIZE, this);
+		}
+
+		return this.outputComposite;
+	}
+	
 	@Override
 	public void run() {
 		// TODO Preform output operations ... end workflow
 		
-		this.stateMachine.exit();
+		Status status = this.stateMachine.getStatus();
+		
+		if(status.getSignResult() != null)
+		{
+			OutputComposite outputComposite = this.getSelectionComposite();
+			outputComposite.setSignedDocument(status.getSignResult().getSignedDocument());
+			this.stateMachine.getGUIProvider().display(outputComposite);
+			
+			/*DocumentSource signedDocument = status.getSignResult().getSignedDocument();			
+			
+			FileOutputStream output;
+			try {
+				output = new FileOutputStream(new File("/tmp/test.pdf"));
+				output.write(signedDocument.getByteArray(), 0, signedDocument.getByteArray().length);
+				output.close();
+			} catch (IOException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}*/
+		}
+		
+		//this.stateMachine.exit();
 	}
 
 	/* (non-Javadoc)
@@ -53,7 +88,8 @@ public class OutputState extends State {
 	 */
 	@Override
 	public void cleanUp() {
-		// TODO
+		if (this.outputComposite != null)
+			this.outputComposite.dispose();
 	}
 
 	/* (non-Javadoc)
diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/PrepareSigningState.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/PrepareSigningState.java
index db251ee6..9fc86f3b 100644
--- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/PrepareSigningState.java
+++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/PrepareSigningState.java
@@ -24,7 +24,9 @@ import at.asit.pdfover.gui.MainWindow.Buttons;
 import at.asit.pdfover.gui.MainWindowBehavior;
 import at.asit.pdfover.gui.composites.WaitingComposite;
 import at.asit.pdfover.gui.workflow.StateMachine;
+import at.asit.pdfover.gui.workflow.Status;
 import at.asit.pdfover.gui.workflow.states.BKUSelectionState.BKUs;
+import at.asit.pdfover.signator.PDFFileDocumentSource;
 import at.asit.pdfover.signator.SignatureParameter;
 import at.asit.pdfover.signator.Signer;
 
@@ -40,33 +42,6 @@ public class PrepareSigningState extends State {
 		super(stateMachine);
 	}
 
-	/**
-	 * Debug background thread
-	 */
-	private final class DebugSleeperThread implements Runnable {
-		
-		private StateMachine workflow;
-		
-		/**
-		 * Default constructor
-		 * @param work
-		 */
-		public DebugSleeperThread(final StateMachine work) {
-			this.workflow = work;
-		}
-		
-		@Override
-		public void run() {
-			try {
-				Thread.sleep(5000);
-			} catch (InterruptedException e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			}
-			this.workflow.invokeUpdate();
-		}
-	}
-
 	private final class PrepareDocumentThread implements Runnable {
 		
 		private PrepareSigningState state;
@@ -82,10 +57,26 @@ public class PrepareSigningState extends State {
 		@Override
 		public void run() {
 			try {
+				if(this.state.signer == null) {
+					this.state.signer = this.state.stateMachine.getPDFSigner().getPDFSigner();
+				}
+				
+				if(this.state.signatureParameter == null) {
+					this.state.signatureParameter = this.state.signer.newParameter();
+				}
+				
+				this.state.signatureParameter.setInputDocument(new PDFFileDocumentSource(this.state.stateMachine.getStatus().getDocument()));
 				
+				this.state.signatureParameter.setSignaturePosition(this.state.stateMachine.getStatus().getSignaturePosition());
+				
+				// TODO: Fill library specific signature Parameters ...
+				// TODO: setEmblem etc.
+				
+				this.state.signingState = this.state.signer.prepare(this.state.signatureParameter);
 				
 			} catch (Exception e) {
-				log.error("PrepareDocumentThread: ", e);
+				log.error("PrepareDocumentThread: ", e); //$NON-NLS-1$
+				this.state.threadException = e;
 			}
 			finally {
 				this.state.stateMachine.invokeUpdate();
@@ -96,9 +87,9 @@ public class PrepareSigningState extends State {
 	/**
 	 * SFL4J Logger instance
 	 **/
-	private static final Logger log = LoggerFactory.getLogger(PrepareSigningState.class);
+	static final Logger log = LoggerFactory.getLogger(PrepareSigningState.class);
 	
-	private SignatureParameter signatureParameter;
+	SignatureParameter signatureParameter;
 	
 	private WaitingComposite waitingComposite = null;
 
@@ -111,29 +102,45 @@ public class PrepareSigningState extends State {
 		return this.waitingComposite;
 	}
 	
-	private boolean run = false;
+	at.asit.pdfover.signator.SigningState signingState  = null;
+
+	Signer signer;
+	
+	Exception threadException = null;
 	
 	@Override
 	public void run() {
-		// TODO SHOW BACKGROUND ACTIVITY ....
 		WaitingComposite waiting = this.getSelectionComposite();
 
 		this.stateMachine.getGUIProvider().display(waiting);
 		
-		Signer signer = this.stateMachine.getPDFSigner().getPDFSigner();
+		this.signer = this.stateMachine.getPDFSigner().getPDFSigner();
+		
+		Status status = this.stateMachine.getStatus();
 		
-		if(signatureParameter == null) {
-//			signatureParameter = 
+		if(this.signatureParameter == null) {
+			this.signatureParameter = this.signer.newParameter(); 
 		}
 		
-		if(!this.run) {
+		if(this.signingState == null && this.threadException == null) {
 			Thread t = new Thread(new PrepareDocumentThread(this));
-			this.run = true;
 			t.start();
 			return;
+		} 
+		
+		if(this.threadException != null) {
+			// TODO: Jump to error state!
 		}
 		
-		// WAIT FOR SLREQUEST and dispatch according to BKU selection
+		if(this.signingState == null || this.signingState.getSignatureRequest() == null) {
+			// This shouldnot happen!! PrepareDocumentThread allready performed, either we have a valid signingState or an exception!!
+			// TODO: Jump to error state!
+		}
+		
+		// We got the Request set it into status and move on to next state ...
+		status.setSigningState(this.signingState);
+		
+		log.debug("SL REQUEST: " + this.signingState.getSignatureRequest().getRequest()); //$NON-NLS-1$
 		
 		if(this.stateMachine.getStatus().getBKU() == BKUs.LOCAL) {
 			this.setNextState(new LocalBKUState(this.stateMachine));
diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/SigningState.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/SigningState.java
index 6b453d33..524fc868 100644
--- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/SigningState.java
+++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/SigningState.java
@@ -20,12 +20,44 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import at.asit.pdfover.gui.workflow.StateMachine;
+import at.asit.pdfover.gui.workflow.Status;
+import at.asit.pdfover.signator.Signer;
 
 /**
  * Logical state for signing process, usually show BKU Dialog during this state.
  */
 public class SigningState extends State {
 
+	/**
+	 * 
+	 */
+	private final class FinishSignThread implements Runnable {
+		
+		private SigningState state;
+		
+		/**
+		 * @param signingState
+		 */
+		public FinishSignThread(SigningState signingState) {
+			this.state = signingState;
+		}
+
+		@Override
+		public void run() {
+			try {
+				Signer signer = this.state.stateMachine.getPDFSigner().getPDFSigner();
+				Status status = this.state.stateMachine.getStatus();
+				
+				status.setSignResult(signer.sign(status.getSigningState()));
+			} catch(Exception e) {
+				log.error("FinishSignThread: ", e); //$NON-NLS-1$
+				this.state.threadException = e;
+			} finally {
+				this.state.stateMachine.invokeUpdate();
+			}
+		}
+	}
+
 	/**
 	 * @param stateMachine
 	 */
@@ -36,12 +68,29 @@ public class SigningState extends State {
 	/**
 	 * SFL4J Logger instance
 	 **/
-	@SuppressWarnings("unused")
-	private static final Logger log = LoggerFactory.getLogger(SigningState.class);
+	static final Logger log = LoggerFactory.getLogger(SigningState.class);
+	
+	Exception threadException = null;
 	
 	@Override
 	public void run() {
-		// TODO Wait until output ready and set output
+		Status status = this.stateMachine.getStatus();
+		
+		if(status.getSignResult() == null && 
+			this.threadException == null) {
+			Thread t = new Thread(new FinishSignThread(this));
+			t.start();
+			return;
+		}
+		
+		if(this.threadException != null) {
+			// TODO: Jump to error state
+		}
+		
+		if(status.getSignResult() == null) {
+			// The thread should set the threadException or create a valid signResult
+			// TODO: Jump to error state
+		}
 		
 		this.setNextState(new OutputState(this.stateMachine));
 	}
-- 
cgit v1.2.3