Search in sources :

Example 6 with ResultStatus

use of org.openecard.gui.ResultStatus in project open-ecard by ecsec.

the class ExecutionEngine method process.

/**
 * Processes the user consent associated with this instance. <br>
 * The following algorithm is used to process the dialog.
 * <ol>
 * <li>Display the first step.</li>
 * <li>Evaluate step result. Break execution on CANCEL.</li>
 * <li>Execute step action. Break execution on CANCEL.</li>
 * <li>Display either next previous or current step, or a replacement according to result.</li>
 * <li>Proceed with point 2.</li>
 * </ol>
 *
 * @return Overall result of the execution.
 * @throws ThreadTerminateException Thrown in case the GUI has been closed externally (interrupted).
 */
public ResultStatus process() throws ThreadTerminateException {
    // get first step
    StepResult next = navigator.next();
    // loop over steps. break inside loop
    while (true) {
        ResultStatus result = next.getStatus();
        // close dialog on cancel and interrupt
        if (result == ResultStatus.INTERRUPTED || Thread.currentThread().isInterrupted()) {
            navigator.close();
            throw new ThreadTerminateException("GUI has been interrupted.");
        } else if (result == ResultStatus.CANCEL) {
            navigator.close();
            return result;
        }
        // get result and put it in resultmap
        List<OutputInfoUnit> stepResults = next.getResults();
        Map<String, ExecutionResults> oldResults = Collections.unmodifiableMap(results);
        results.put(next.getStepID(), new ExecutionResults(next.getStepID(), stepResults));
        // replace InfoInputUnit values in live list
        if (!next.getStep().isResetOnLoad()) {
            Step s = next.getStep();
            List<InputInfoUnit> inputInfo = s.getInputInfoUnits();
            Map<String, InputInfoUnit> infoMap = new HashMap<>();
            // create index over infos
            for (InputInfoUnit nextInfo : inputInfo) {
                infoMap.put(nextInfo.getID(), nextInfo);
            }
            for (OutputInfoUnit nextOut : stepResults) {
                InputInfoUnit matchingInfo = infoMap.get(nextOut.getID());
                // an entry must exist, otherwise this is an error in the GUI implementation
                // this type of error should be found in tests
                matchingInfo.copyContentFrom(nextOut);
            }
        }
        // replace step if told by result value
        if (next.getReplacement() != null) {
            switch(next.getStatus()) {
                case BACK:
                    next = navigator.replacePrevious(next.getReplacement());
                    break;
                case OK:
                    if (navigator.hasNext()) {
                        next = navigator.replaceNext(next.getReplacement());
                    } else {
                        navigator.close();
                        return convertStatus(StepActionResultStatus.NEXT);
                    }
                    break;
                case RELOAD:
                    next = navigator.replaceCurrent(next.getReplacement());
                    break;
                default:
                    // fallthrough because CANCEL and INTERRUPTED are already handled
                    break;
            }
        } else {
            // step replacement did not happen, so we can execute the action
            StepAction action = next.getStep().getAction();
            StepActionCallable actionCallable = new StepActionCallable(action, oldResults, next);
            // use separate thread or tasks running outside the JVM context, like PCSC calls, won't stop on cancellation
            ExecutorService execService = Executors.newSingleThreadExecutor();
            Future<StepActionResult> actionFuture = execService.submit(actionCallable);
            navigator.setRunningAction(actionFuture);
            StepActionResult actionResult;
            try {
                actionResult = actionFuture.get();
            } catch (CancellationException ex) {
                LOG.info("StepAction was canceled.", ex);
                navigator.close();
                return ResultStatus.CANCEL;
            } catch (InterruptedException ex) {
                LOG.info("StepAction was interrupted.", ex);
                navigator.close();
                throw new ThreadTerminateException("GUI has been interrupted.");
            } catch (ExecutionException ex) {
                // there are some special kinds we need to handle here
                if (ex.getCause() instanceof InvocationTargetExceptionUnchecked) {
                    InvocationTargetExceptionUnchecked iex = (InvocationTargetExceptionUnchecked) ex.getCause();
                    if (iex.getCause() instanceof ThreadTerminateException) {
                        LOG.info("StepAction was interrupted.", ex);
                        navigator.close();
                        throw new ThreadTerminateException("GUI has been interrupted.");
                    }
                }
                // all other types
                LOG.error("StepAction failed with error.", ex.getCause());
                navigator.close();
                return ResultStatus.CANCEL;
            }
            // break out if cancel was returned
            if (actionResult.getStatus() == StepActionResultStatus.CANCEL) {
                LOG.info("StepAction was canceled.");
                navigator.close();
                return ResultStatus.CANCEL;
            }
            // replace step if told by result value
            if (actionResult.getReplacement() != null) {
                switch(actionResult.getStatus()) {
                    case BACK:
                        next = navigator.replacePrevious(actionResult.getReplacement());
                        break;
                    case NEXT:
                        if (navigator.hasNext()) {
                            next = navigator.replaceNext(actionResult.getReplacement());
                        } else {
                            navigator.close();
                            return convertStatus(StepActionResultStatus.NEXT);
                        }
                        break;
                    case REPEAT:
                        next = navigator.replaceCurrent(actionResult.getReplacement());
                        break;
                    default:
                        // fallthrough because CANCEL is already handled
                        break;
                }
            } else {
                // no replacement just proceed
                switch(actionResult.getStatus()) {
                    case BACK:
                        next = navigator.previous();
                        break;
                    case NEXT:
                        if (navigator.hasNext()) {
                            next = navigator.next();
                        } else {
                            navigator.close();
                            return convertStatus(StepActionResultStatus.NEXT);
                        }
                        break;
                    case REPEAT:
                        next = navigator.current();
                        break;
                    default:
                        // fallthrough because CANCEL is already handled
                        break;
                }
            }
        }
    }
}
Also used : InvocationTargetExceptionUnchecked(org.openecard.common.interfaces.InvocationTargetExceptionUnchecked) ResultStatus(org.openecard.gui.ResultStatus) HashMap(java.util.HashMap) Step(org.openecard.gui.definition.Step) InputInfoUnit(org.openecard.gui.definition.InputInfoUnit) CancellationException(java.util.concurrent.CancellationException) ExecutorService(java.util.concurrent.ExecutorService) OutputInfoUnit(org.openecard.gui.definition.OutputInfoUnit) StepResult(org.openecard.gui.StepResult) ThreadTerminateException(org.openecard.common.ThreadTerminateException) ExecutionException(java.util.concurrent.ExecutionException)

Example 7 with ResultStatus

use of org.openecard.gui.ResultStatus in project open-ecard by ecsec.

the class TCTokenRequest method findCard.

/**
 * Finds a card which matches one of the give types.
 *
 * @param types String array containing valid card types.
 * @param disp Dispatcher used to query cards and terminals.
 * @param gui User consent to display messages to the user.
 * @return ConnectionHandleType object of the chosen card.
 */
private static ConnectionHandleType findCard(@Nonnull String[] types, @Nonnull Context ctx) throws MissingActivationParameterException, UserCancellationException {
    CardRecognition rec = ctx.getRecognition();
    Map<String, String> namesAndType = new HashMap<>();
    for (String type : types) {
        namesAndType.put(rec.getTranslatedCardName(type), type);
    }
    InsertCardDialog insCardDiag = new InsertCardDialog(ctx.getUserConsent(), ctx.getCardStates(), namesAndType, ctx.getEventDispatcher());
    List<ConnectionHandleType> usableCards = insCardDiag.show();
    if (usableCards == null) {
        // user aborted the card insertion dialog
        throw new UserCancellationException(null, LANG.translationForKey(CARD_INSERTION_ABORT));
    }
    ConnectionHandleType handle;
    if (usableCards.size() > 1) {
        UserConsentDescription ucd = new UserConsentDescription(LANG.translationForKey("card.selection.heading.uc", AppVersion.getName()));
        String stepTitle = LANG.translationForKey("card.selection.heading.step");
        CardSelectionStep step = new CardSelectionStep(stepTitle, usableCards, ctx.getRecognition());
        ArrayList<String> types2 = new ArrayList<>();
        types2.addAll(namesAndType.values());
        CardMonitorTask task = new CardMonitorTask(types2, step);
        ctx.getEventDispatcher().add(task, EventType.CARD_REMOVED, EventType.CARD_RECOGNIZED);
        step.setBackgroundTask(task);
        CardSelectionAction action = new CardSelectionAction(step, usableCards, types2, ctx);
        step.setAction(action);
        ucd.getSteps().add(step);
        UserConsent uc = ctx.getUserConsent();
        UserConsentNavigator ucNav = uc.obtainNavigator(ucd);
        ExecutionEngine exec = new ExecutionEngine(ucNav);
        ResultStatus resStatus = exec.process();
        if (resStatus != ResultStatus.OK) {
            throw new MissingActivationParameterException(CARD_SELECTION_ABORT);
        }
        handle = action.getResult();
        ctx.getEventDispatcher().del(task);
    } else {
        handle = usableCards.get(0);
    }
    return handle;
}
Also used : ConnectionHandleType(iso.std.iso_iec._24727.tech.schema.ConnectionHandleType) HashMap(java.util.HashMap) ResultStatus(org.openecard.gui.ResultStatus) ArrayList(java.util.ArrayList) MissingActivationParameterException(org.openecard.binding.tctoken.ex.MissingActivationParameterException) CardMonitorTask(org.openecard.addons.tr03124.gui.CardMonitorTask) CardSelectionStep(org.openecard.addons.tr03124.gui.CardSelectionStep) UserConsent(org.openecard.gui.UserConsent) UserConsentNavigator(org.openecard.gui.UserConsentNavigator) ExecutionEngine(org.openecard.gui.executor.ExecutionEngine) UserCancellationException(org.openecard.binding.tctoken.ex.UserCancellationException) UserConsentDescription(org.openecard.gui.definition.UserConsentDescription) CardRecognition(org.openecard.common.interfaces.CardRecognition) InsertCardDialog(org.openecard.common.sal.util.InsertCardDialog) CardSelectionAction(org.openecard.addons.tr03124.gui.CardSelectionAction)

Aggregations

ResultStatus (org.openecard.gui.ResultStatus)7 UserConsentNavigator (org.openecard.gui.UserConsentNavigator)6 ExecutionEngine (org.openecard.gui.executor.ExecutionEngine)6 ConnectionHandleType (iso.std.iso_iec._24727.tech.schema.ConnectionHandleType)3 UserConsentDescription (org.openecard.gui.definition.UserConsentDescription)3 InputAPDUInfoType (iso.std.iso_iec._24727.tech.schema.InputAPDUInfoType)2 Transmit (iso.std.iso_iec._24727.tech.schema.Transmit)2 TransmitResponse (iso.std.iso_iec._24727.tech.schema.TransmitResponse)2 HashMap (java.util.HashMap)2 Result (oasis.names.tc.dss._1_0.core.schema.Result)2 CardResponseAPDU (org.openecard.common.apdu.common.CardResponseAPDU)2 AltVUMessagesType (iso.std.iso_iec._24727.tech.schema.AltVUMessagesType)1 DIDAuthenticate (iso.std.iso_iec._24727.tech.schema.DIDAuthenticate)1 DIDAuthenticateResponse (iso.std.iso_iec._24727.tech.schema.DIDAuthenticateResponse)1 DIDAuthenticationDataType (iso.std.iso_iec._24727.tech.schema.DIDAuthenticationDataType)1 InputUnitType (iso.std.iso_iec._24727.tech.schema.InputUnitType)1 PasswordAttributesType (iso.std.iso_iec._24727.tech.schema.PasswordAttributesType)1 PinInputType (iso.std.iso_iec._24727.tech.schema.PinInputType)1 VerifyUserResponse (iso.std.iso_iec._24727.tech.schema.VerifyUserResponse)1 InvocationTargetException (java.lang.reflect.InvocationTargetException)1