From 23ae1caefcf0cc99c2b90327afaff6376ecc552a Mon Sep 17 00:00:00 2001 From: tkellner 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, + "" + b64_data //$NON-NLS-1$ + + ""); //$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