use of org.openecard.gui.definition.OutputInfoUnit in project open-ecard by ecsec.
the class CardSelectionAction method perform.
@Override
public StepActionResult perform(Map<String, ExecutionResults> oldResults, StepResult result) {
if (result.isOK()) {
ExecutionResults results = oldResults.get(getStepID());
OutputInfoUnit out = results.getResult("credentialSelectionBox");
Radiobox rBox = (Radiobox) out;
for (BoxItem item : rBox.getBoxItems()) {
if (item.isChecked()) {
this.resultCardTypetName = item.getName();
break;
}
}
if (resultCardTypetName != null) {
return new StepActionResult(StepActionResultStatus.NEXT);
} else {
return new StepActionResult(StepActionResultStatus.REPEAT);
}
} else {
// user has added or removed a card
if (result.isReload()) {
updateCards();
step.update(avCard);
if (avCard.isEmpty()) {
return new StepActionResult(StepActionResultStatus.CANCEL);
}
return new StepActionResult(StepActionResultStatus.REPEAT);
}
// user has canceled the dialog so return that
return new StepActionResult(StepActionResultStatus.CANCEL);
}
}
use of org.openecard.gui.definition.OutputInfoUnit in project open-ecard by ecsec.
the class EacGuiImpl method getPinResult.
public List<OutputInfoUnit> getPinResult(Step step) throws InterruptedException {
if (step instanceof PINStep) {
PINStep pinStep = (PINStep) step;
switch(pinStep.getStatus()) {
case RC3:
this.pinStatus.deliver(PinStatus.RC3);
break;
case RC2:
this.pinStatus.deliver(PinStatus.RC2);
break;
case RC1:
this.pinStatus.deliver(PinStatus.CAN);
break;
}
// read values
String pinValue = this.userPin.deref();
String canValue = this.userCan.deref();
ArrayList<OutputInfoUnit> result = new ArrayList<>();
for (InputInfoUnit nextIn : pinStep.getInputInfoUnits()) {
if (pinValue != null && nextIn instanceof PasswordField && nextIn.getID().equals("PACE_PIN_FIELD")) {
PasswordField pw = new PasswordField(nextIn.getID());
pw.copyContentFrom(nextIn);
pw.setValue(pinValue.toCharArray());
result.add(pw);
} else if (canValue != null && nextIn instanceof PasswordField && nextIn.getID().equals("PACE_CAN_FIELD")) {
PasswordField pw = new PasswordField(nextIn.getID());
pw.copyContentFrom(nextIn);
pw.setValue(canValue.toCharArray());
result.add(pw);
}
}
return result;
} else {
throw new InterruptedException("The given step is not a PinStep.");
}
}
use of org.openecard.gui.definition.OutputInfoUnit 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;
}
}
}
}
}
use of org.openecard.gui.definition.OutputInfoUnit in project open-ecard by ecsec.
the class EacNavigator method next.
@Override
public StepResult next() {
// if cancel call has been issued, abort the whole process
if (this.guiService.isCancelled()) {
// prevent index out of bounds
int i = idx == -1 ? 0 : idx > steps.size() ? steps.size() - 1 : idx;
return new AndroidResult(steps.get(i), ResultStatus.CANCEL, Collections.EMPTY_LIST);
}
// handle step display
if (idx == -1) {
idx++;
return new AndroidResult(steps.get(idx), ResultStatus.OK, Collections.EMPTY_LIST);
} else if (idx == 0) {
idx++;
Step cvcStep = steps.get(0);
Step chatStep = steps.get(1);
try {
this.guiService.loadValuesFromSteps(cvcStep, chatStep);
List<OutputInfoUnit> outInfo = this.guiService.getSelection();
return new AndroidResult(chatStep, ResultStatus.OK, outInfo);
} catch (InterruptedException ex) {
return new AndroidResult(chatStep, ResultStatus.CANCEL, Collections.EMPTY_LIST);
}
} else if (idx == 1) {
idx++;
Step pinStep = steps.get(2);
if (pinFirstUse) {
pinFirstUse = false;
} else {
this.guiService.setPinCorrect(false);
}
// get blocked status from dynamic context
DynamicContext ctx = DynamicContext.getInstance(TR03112Keys.INSTANCE_KEY);
EacPinStatus blockedStatus = (EacPinStatus) ctx.get(EACProtocol.PIN_STATUS);
if (blockedStatus == EacPinStatus.BLOCKED || blockedStatus == EacPinStatus.DEACTIVATED) {
this.guiService.sendPinStatus(blockedStatus);
return new AndroidResult(pinStep, ResultStatus.CANCEL, Collections.EMPTY_LIST);
}
// ask user for the pin
try {
List<OutputInfoUnit> outInfo = this.guiService.getPinResult(pinStep);
writeBackValues(pinStep.getInputInfoUnits(), outInfo);
return new AndroidResult(pinStep, ResultStatus.OK, outInfo);
} catch (InterruptedException ex) {
return new AndroidResult(pinStep, ResultStatus.CANCEL, Collections.EMPTY_LIST);
}
} else if (idx == 2) {
idx++;
Step s = steps.get(idx);
// get blocked status from dynamic context
DynamicContext ctx = DynamicContext.getInstance(TR03112Keys.INSTANCE_KEY);
EacPinStatus blockedStatus = (EacPinStatus) ctx.get(EACProtocol.PIN_STATUS);
if (blockedStatus == EacPinStatus.BLOCKED || blockedStatus == EacPinStatus.DEACTIVATED) {
this.guiService.setPinCorrect(false);
this.guiService.sendPinStatus(blockedStatus);
return new AndroidResult(s, ResultStatus.CANCEL, Collections.EMPTY_LIST);
}
if ("PROTOCOL_GUI_STEP_PROCESSING".equals(s.getID())) {
this.guiService.setPinCorrect(true);
return new AndroidResult(s, ResultStatus.OK, Collections.EMPTY_LIST);
} else {
this.guiService.setPinCorrect(false);
return new AndroidResult(s, ResultStatus.CANCEL, Collections.EMPTY_LIST);
}
} else {
Step s = steps.get(idx);
idx++;
return new AndroidResult(s, ResultStatus.OK, Collections.EMPTY_LIST);
}
}
Aggregations