Package uk.co.nimp.scard

Source Code of uk.co.nimp.scard.Main$StdParams

package uk.co.nimp.scard;

import com.atolsystems.atolutilities.ACommandLineUtilities.ArgProcessor;
import java.net.MalformedURLException;
import uk.co.nimp.scard.log.ScardPrintStreamLogHandler;
import code.from.internet.JarClassLoader;
import com.atolsystems.atolutilities.ACommandLineUtilities;
import com.atolsystems.atolutilities.ACommandLineUtilities.Arg;
import com.atolsystems.atolutilities.AFileChooser;
import com.atolsystems.atolutilities.AFileUtilities;
import com.atolsystems.atolutilities.ATextScreenOutputJFrame;
import com.atolsystems.atolutilities.ATimeUtilities;
import com.atolsystems.atolutilities.ArgSpec;
import com.atolsystems.atolutilities.InvalidCommandLineException;
import com.atolsystems.atolutilities.StopRequestFromUserException;
import java.awt.Color;
import java.awt.Component;
import java.awt.SplashScreen;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PipedOutputStream;
import java.io.PrintStream;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.smartcardio.CardNotPresentException;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.filechooser.FileNameExtensionFilter;
import uk.co.nimp.scard.log.StarScriptLogHandler;
import uk.co.nimp.smartcard.Apdu;

/**
*
* @author sebastien.riou
*/
public class Main implements ACommandLineUtilities.ArgProcessor {

    public static final String NIMP_SMART_CARD_HOME = "NIMP_SMART_CARD_HOME";
    public static final String DEFAULT_CONF_EXTENSION = ".Defaults.conf";
    public static final String DEFAULT_CONF_FILENAME = "NimpSmartCard" + DEFAULT_CONF_EXTENSION;
    //"Standard args"
    static final String ARG_HELP = "-help";
    static final int ARG_HELP_ID = 0x0000EFFF;
    static final String ARG_SET_CONF_FOLDER = "-confFolder:";
    static final int ARG_SET_CONF_FOLDER_ID = 0x0000EFFE;
    static final String ARG_ADD_JAR_FILE = "-addJarFile:";
    static final int ARG_ADD_JAR_FILE_ID = 0x0000EFFD;
    static final String ARG_ADD_TERMINAL_MANAGER = "-addTerminalManager:";
    static final int ARG_ADD_TERMINAL_MANAGER_ID = 0x0000EFFC;
    public static final String ARG_STAR_SCRIPT_FILE = "-starScript:";
    public static final int ARG_STAR_SCRIPT_FILE_ID = 0x0000EFFB | ACommandLineUtilities.ID_NEED_INPUT_FILE;
    static final String ARG_SET_NRUN = "-nRun:";
    static final int ARG_SET_NRUN_ID = 0x0000EFFA;
    public static final String ARG_SET_PRINT_STREAM_LOG = "-printStreamLog:";
    public static final int ARG_SET_PRINT_STREAM_LOG_ID = 0x0000EFF9 | ACommandLineUtilities.ID_NEED_OUTPUT_FILE;
    static final String ARG_TASK = "-task:";
    static final int ARG_TASK_ID = 0x0000EFF8;
    public static final String ARG_SET_STAR_SCRIPT_LOG = "-starScriptLog:";
    public static final int ARG_SET_STAR_SCRIPT_LOG_ID = 0x0000EFF7 | ACommandLineUtilities.ID_NEED_OUTPUT_FILE;
    //args for this app only
    static final String ARG_FIXED_PARALLEL_MODE = "-parallelMode:";
    static final int ARG_FIXED_PARALLEL_MODE_ID = 0x00000000;
    static final String ARG_PARALLEL_MODE = "-parallelMode";
    static final int ARG_PARALLEL_MODE_ID = 0x00000001;
    static final String ARG_CHECK_CARD_CONNECTION = "-checkCardConnection";
    static final int ARG_CHECK_CARD_CONNECTION_ID = 0x00000002;
    static long deadTime = 0;

    public static void speedTest(GenericTerminal terminal) throws ScardException, CardNotPresentException {
        long start = System.nanoTime();
        if (terminal instanceof GenericContactTerminal) {
            GenericContactTerminal contactTerminal = (GenericContactTerminal) terminal;
            contactTerminal.setFrequency(3000000);
            contactTerminal.setVoltage(5000);
        }
        for (int i = 0; i < 10; i++) {
            terminal.coldConnect();
            Apdu apdu = new Apdu(0x00, 0x1A, 0x00, 0x00, 0x04);
            terminal.sendApdu(apdu);
            if (0x9000 != apdu.getSw()) {
                throw new RuntimeException();
            }
            byte data[] = {(byte) 0x12, (byte) 0x34, (byte) 0x56, (byte) 0x78};
            apdu = new Apdu(0x00, 0x1C, 0x00, 0x00, data);
            terminal.sendApdu(apdu);
            if (0x9000 != apdu.getSw()) {
                throw new RuntimeException();
            }
            apdu = new Apdu(0x00, 0x1A, 0x00, 0x00, 0x04);
            terminal.sendApdu(apdu);
            if (0x9000 != apdu.getSw()) {
                throw new RuntimeException();
            }
        }
        terminal.logLine(ScardLogHandler.LOG_INFO, "speedTest duration: " + ATimeUtilities.getUserFriendlyTimeUs(System.nanoTime() - start));
    }

    public static class StdParams {

        int nRun = 1;
        String confFolder;
        LinkedList<GenericTerminalManager> terminalManagers = new LinkedList<GenericTerminalManager>();
        PrintStream ps = System.out;
        ScardPrintStreamLogHandler printStreamLogHandler = new ScardPrintStreamLogHandler(ps);
        String args[];
        ArgSpec argSpecs[];

        public ArgSpec[] getArgSpecs() {
            return argSpecs;
        }

        public String[] getArgs() {
            return args;
        }

        public String getConfFolder() {
            return confFolder;
        }

        public int getnRun() {
            return nRun;
        }

        public ScardPrintStreamLogHandler getPrintStreamLogHandler() {
            return printStreamLogHandler;
        }

        public PrintStream getPs() {
            return ps;
        }

        public void setPs(PrintStream ps) {
            this.ps = ps;
            printStreamLogHandler = new ScardPrintStreamLogHandler(ps);
        }

        public LinkedList<GenericTerminalManager> getTerminalManagers() {
            return terminalManagers;
        }
    }

    static protected Class getPlugInClass(String className) {
        Class plugInClass = null;
        try {
            if (null == className) {
                return null;
            }
            plugInClass = pluginJarClassLoader.loadClass(className);
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }
        return plugInClass;
    }
    static JarClassLoader pluginJarClassLoader;

    public static String getDefaultConfFolder() {
        //return AFileUtilities.getPackagePath(terminalManagerClass, aResourceInSamePackage)+"TerminalsConf"+System.getProperty("path.separator");
        String pathSeparator = System.getProperty("file.separator");
        String home = System.getenv(NIMP_SMART_CARD_HOME);
        if (null == home) {
            throw new RuntimeException(NIMP_SMART_CARD_HOME + " environment variable is not set.");
        }
        return home + pathSeparator + "TerminalsConf" + pathSeparator;
    }

    static public ArgSpec[] getStdArgSpecs() {
        ArgSpec out[] = {
            new ArgSpec(ARG_HELP, ARG_HELP_ID),
            new ArgSpec(ARG_SET_CONF_FOLDER, ARG_SET_CONF_FOLDER_ID, 0),
            new ArgSpec(ARG_ADD_JAR_FILE, ARG_ADD_JAR_FILE_ID, 0),
            new ArgSpec(ARG_ADD_TERMINAL_MANAGER, ARG_ADD_TERMINAL_MANAGER_ID, ArgSpec.UNLIMITED_OCCURENCE),
            new ArgSpec(ARG_TASK, ARG_TASK_ID, ArgSpec.UNLIMITED_OCCURENCE),
            new ArgSpec(ARG_STAR_SCRIPT_FILE, ARG_STAR_SCRIPT_FILE_ID, ArgSpec.UNLIMITED_OCCURENCE),
            new ArgSpec(ARG_SET_NRUN, ARG_SET_NRUN_ID, ArgSpec.UNLIMITED_OCCURENCE),
            new ArgSpec(ARG_SET_PRINT_STREAM_LOG, ARG_SET_PRINT_STREAM_LOG_ID, ArgSpec.UNLIMITED_OCCURENCE),
            new ArgSpec(ARG_SET_STAR_SCRIPT_LOG, ARG_SET_STAR_SCRIPT_LOG_ID, ArgSpec.UNLIMITED_OCCURENCE)
        };
        return out;
    }

    static public ArgSpec[] addStdArgSpecs(ArgSpec[] argSpecs) {
        ArgSpec stdArgSpecs[] = getStdArgSpecs();
        ArgSpec out[] = new ArgSpec[stdArgSpecs.length + argSpecs.length];
        int n = 0;
        for (int i = 0; i < stdArgSpecs.length; i++) {
            out[n++] = stdArgSpecs[i];
        }
        for (int i = 0; i < argSpecs.length; i++) {
            out[n++] = argSpecs[i];
        }
        return out;
    }

    public static StdParams processStdArgs(String[] args, ArgSpec argSpecs[], Class classInMainPackage, String appName) throws FileNotFoundException, IOException {
        StdParams p = new StdParams();
        ArgSpec internalArgSpecs[] = addStdArgSpecs(argSpecs);
        Set specs = ACommandLineUtilities.addArgFileArgSpecs(internalArgSpecs);
        //internalArgSpecs = ACommandLineUtilities.addArgFileArgSpecs(internalArgSpecs);
        /*ArgSpec argFileArgSpecs[] = ACommandLineUtilities.getArgFileArgSpecs();
        ArgSpec internalArgSpecs[] = new ArgSpec[argSpecs.length + 8 + argFileArgSpecs.length];
        int offset = 0;
        internalArgSpecs[offset++] = new ArgSpec(ARG_HELP, ARG_HELP_ID);
        internalArgSpecs[offset++] = new ArgSpec(ARG_SET_CONF_FOLDER, ARG_SET_CONF_FOLDER_ID, 0);
        internalArgSpecs[offset++] = new ArgSpec(ARG_ADD_JAR_FILE, ARG_ADD_JAR_FILE_ID, 0);
        internalArgSpecs[offset++] = new ArgSpec(ARG_ADD_TERMINAL_MANAGER, ARG_ADD_TERMINAL_MANAGER_ID, ArgSpec.UNLIMITED_OCCURENCE);
        internalArgSpecs[offset++] = new ArgSpec(ARG_TASK, ARG_TASK_ID, ArgSpec.UNLIMITED_OCCURENCE);
        internalArgSpecs[offset++] = new ArgSpec(ARG_STAR_SCRIPT_FILE, ARG_STAR_SCRIPT_FILE_ID, ArgSpec.UNLIMITED_OCCURENCE);
        internalArgSpecs[offset++] = new ArgSpec(ARG_SET_NRUN, ARG_SET_NRUN_ID, ArgSpec.UNLIMITED_OCCURENCE);
        internalArgSpecs[offset++] = new ArgSpec(ARG_SET_PRINT_STREAM_LOG, ARG_SET_PRINT_STREAM_LOG_ID, ArgSpec.UNLIMITED_OCCURENCE);
        for (int i = 0; i < argFileArgSpecs.length; i++) {
        internalArgSpecs[offset++] = argFileArgSpecs[i];
        }
        for (int i = 0; i < argSpecs.length; i++) {
        internalArgSpecs[offset++] = argSpecs[i];
        }*/
        //p.argSpecs = ACommandLineUtilities.addArgFileArgSpecs(internalArgSpecs);
        p.argSpecs = new ArgSpec[specs.size()];
        specs.toArray(p.argSpecs);
        p.args = ACommandLineUtilities.processArgFile(new File("").getAbsoluteFile(), args);
        //ACommandLineUtilities clContext=new ACommandLineUtilities(new File("").getAbsoluteFile(),args,internalArgSpecs,null);
        //clContext.processArgs();
        argSpecs = p.argSpecs;
        args = p.args;
        //ACommandLineUtilities.checkArgs(p.args, p.argSpecs);
        List<Class> registeredTerminalManagers = new LinkedList<Class>();

        boolean nimpHomeNotDefined = false;
        String confFolderName = ACommandLineUtilities.getArgValue(p.args, ARG_SET_CONF_FOLDER, null);
        if (null != confFolderName) {
            //force the path to be absolute
            File f = new File(confFolderName);
            if (false == f.exists()) {
                throw new RuntimeException("Folder specified by \"" + ARG_SET_CONF_FOLDER + "\" argument does not exist:\n" + f.getAbsolutePath());
            }
            confFolderName = f.getAbsolutePath() + System.getProperty("file.separator");
        } else {
            try {
                confFolderName = getDefaultConfFolder();
            } catch (RuntimeException e) {
                Logger.getLogger(classInMainPackage.getName()).log(Level.SEVERE, null, e);
                confFolderName = (new File("")).getAbsolutePath() + System.getProperty("file.separator");
                nimpHomeNotDefined = true;
            }
        }

        try {
            List<String> names = ACommandLineUtilities.getArgValues(p.args, p.argSpecs, ARG_ADD_JAR_FILE, null);
            Set<String> uniqueNames = new HashSet<String>();
            uniqueNames.addAll(names);

            if (uniqueNames.size() >= 1) {
                for (String jarName : uniqueNames) {
                    File jarFile = new File(jarName);
                    if (null == pluginJarClassLoader) {
                        pluginJarClassLoader = new JarClassLoader(jarFile.toURI().toURL());
                    } else {
                        pluginJarClassLoader.addJarURL(jarFile.toURI().toURL());
                    }
                }
            } else {
                File appJarFile = new File(AFileUtilities.getPackagePath(classInMainPackage, "packageLocator"));
                pluginJarClassLoader = new JarClassLoader(appJarFile.toURI().toURL());
            }

            names = ACommandLineUtilities.getArgValues(p.args, p.argSpecs, ARG_ADD_TERMINAL_MANAGER, null);
            if (0 == names.size()) {
                //look for app default conf
                File argFile = new File(confFolderName + appName + DEFAULT_CONF_EXTENSION);
                if (false == argFile.exists()) {
                    //look for framework default conf
                    argFile = new File(confFolderName + DEFAULT_CONF_FILENAME);
                }

                ArgSpec confArgSpecs[] = {
                    new ArgSpec(ARG_HELP, ARG_HELP_ID),
                    new ArgSpec(ARG_ADD_TERMINAL_MANAGER, ARG_ADD_TERMINAL_MANAGER_ID, ArgSpec.UNLIMITED_OCCURENCE)
                };
                try {
                    if (argFile.exists()) {
                        List<String> confArgsList = ACommandLineUtilities.processArgFile(argFile);
                        String confArgs[] = new String[confArgsList.size()];
                        confArgsList.toArray(confArgs);
                        ACommandLineUtilities.checkArgs(confArgs, confArgSpecs);
                        names = ACommandLineUtilities.getArgValues(confArgs, confArgSpecs, ARG_ADD_TERMINAL_MANAGER, null);
                    }
                } catch (Throwable e) {
                    Logger.getLogger(classInMainPackage.getName()).log(Level.SEVERE, null, e);
                } finally {
                    if (0 == names.size()) {
                        //complain
                        if (argFile.exists()) {
                            System.out.println("Default configuration file does not register any terminal manager !");
                        } else {
                            System.out.println("Default configuration file does not exist!");
                        }
                        if (!nimpHomeNotDefined) {
                            System.out.println("File: " + argFile.getAbsolutePath());
                        }
                        System.out.println("It should be used to \"register\" one or more terminal managers using the \"" + ARG_ADD_TERMINAL_MANAGER + "\" switch.");
                        System.out.println("Enter in \"limited\" mode: register only PcScTerminalManager with hard coded options\n");
                        //add PcSc terminal manager to enable minimal functionality anyway
                        p.terminalManagers.add(new PcScTerminalManager());
                    }
                }
            }

            uniqueNames.clear();
            uniqueNames.addAll(names);

            for (String className : uniqueNames) {
                Class theClass = getPlugInClass(className);
                if (theClass != null) {
                    registeredTerminalManagers.add(theClass);
                }
            }
        } catch (Throwable e) {
            Logger.getLogger(classInMainPackage.getName()).log(Level.SEVERE, null, e);
        }



        for (Class terminalClass : registeredTerminalManagers) {
            try {
                GenericTerminalManager manager = (GenericTerminalManager) terminalClass.newInstance();
                manager.loadConfiguration(confFolderName, appName);
                if (null != manager) {
                    p.terminalManagers.add(manager);
                }
            } catch (Throwable e) {
                Logger.getLogger(classInMainPackage.getName()).log(Level.SEVERE, null, e);
            }
        }

        return p;
    }

    public static void getAvailableTerminals(List<GenericTerminalManager> terminalManagers, List<GenericTerminal> availableTerminals) throws ScardException {
        for (GenericTerminalManager terminalManager : terminalManagers) {
            List<GenericTerminal> trial = terminalManager.list();
            if (null != trial) {
                availableTerminals.addAll(trial);
            }
        }
    }

    public static void printNoTerminalMessage(List<GenericTerminalManager> terminalManagers) {
        System.out.println("Could not find any terminal to connect.");
        if (terminalManagers.isEmpty()) {
            System.out.println("No terminal manager registered: please check command line and \".conf\" files.");
        } else {
            System.out.println("Registered terminal managers:");
            for (GenericTerminalManager terminalManager : terminalManagers) {
                System.out.println("\t" + terminalManager.getClass().getSimpleName());
            }
        }
    }

    class ConfigArgProcessor implements ACommandLineUtilities.ArgProcessor {

        boolean nimpHomeNotDefined = false;
        String confFolderName;
        StdParams stdParams;
        Set<String> loadedJarNames = new HashSet<String>();
        Set<String> loadedTerminalManagers = new HashSet<String>();
        String appName;
        File confArgFile;

        public StdParams getStdParams() throws FileNotFoundException, IOException, Throwable {
            stdParams.confFolder = confFolderName;
            if (loadedTerminalManagers.isEmpty()) {
                getDefaultConfig();
            }
            return stdParams;
        }

        public ConfigArgProcessor(Class classInMainPackage, String appName) {
            stdParams = new StdParams();
            try {
                confFolderName = getDefaultConfFolder();
            } catch (RuntimeException e) {
                Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, e);
                confFolderName = (new File("")).getAbsolutePath() + System.getProperty("file.separator");
                nimpHomeNotDefined = true;
            }
            File appJarFile = new File(AFileUtilities.getPackagePath(classInMainPackage, "packageLocator"));
            try {
                pluginJarClassLoader = new JarClassLoader(appJarFile.toURI().toURL());
            } catch (MalformedURLException ex) {
                Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
            }
            this.appName = appName;
        }

        private void getDefaultConfig() throws FileNotFoundException, IOException, Throwable {
            //look for app default conf
            confArgFile = new File(confFolderName + appName + DEFAULT_CONF_EXTENSION);
            if (false == confArgFile.exists()) {
                //look for framework default conf
                confArgFile = new File(confFolderName + DEFAULT_CONF_FILENAME);
            }
            if (confArgFile.exists()) {
                //List<String> confArgsList = ACommandLineUtilities.processArgFile(confArgFile);
                //String confArgs[] = new String[confArgsList.size()];
                //confArgsList.toArray(confArgs);
                ACommandLineUtilities clUtil=new ACommandLineUtilities(confArgFile, getStdArgSpecs(), this);
                //clUtil.checkArgs();
                clUtil.processArgs();
                clUtil.throwIfError();
            } else {
                System.out.println("Default configuration file does not exist!");
                if (nimpHomeNotDefined) {
                    System.out.println("Environment variable \"" + NIMP_SMART_CARD_HOME + "\" is not defined !");
                } else {
                    System.out.println("File: " + confArgFile.getAbsolutePath());
                }
            }
        }

        public boolean processArg(ACommandLineUtilities argContext) {
            try {
                Arg curArg = argContext.getCurArg();
                switch (curArg.id) {
                    case ARG_SET_CONF_FOLDER_ID: {
                        argContext.consumeCurArg();
                        //if(null!=confArgFile)
                        //    throw new RuntimeException("Command line argument \""+ARG_SET_CONF_FOLDER+"\" must appear before any occurence of \""+ARG_ADD_TERMINAL_MANAGER+"\"");
                        File f = argContext.getFileFromCurArgValue();
                        if (false == f.exists()) {
                            throw new InvalidCommandLineException(new FileNotFoundException("Folder specified by \"" + ARG_SET_CONF_FOLDER + "\" argument does not exist:\n" + f.getCanonicalPath()));
                        }
                        confFolderName = f.getAbsolutePath() + System.getProperty("file.separator");
                        break;
                    }
                    case ARG_ADD_JAR_FILE_ID: {
                        argContext.consumeCurArg();
                        File jarFile = argContext.getFileFromCurArgValue();
                        if (false == jarFile.exists()) {
                            throw new InvalidCommandLineException(new FileNotFoundException("File specified by \"" + ARG_ADD_JAR_FILE + "\" argument does not exist:\n" + jarFile.getCanonicalPath()));
                        }
                        String jarCanonicalName = jarFile.getCanonicalPath();
                        if (loadedJarNames.contains(jarCanonicalName)) {
                            break;
                        }
                        loadedJarNames.add(jarCanonicalName);
                        pluginJarClassLoader.addJarURL(jarFile.toURI().toURL());
                        break;
                    }
                    case ARG_ADD_TERMINAL_MANAGER_ID: {
                        argContext.consumeCurArg();
                        String className = curArg.value;
                        if (loadedTerminalManagers.contains(className)) {
                            break;
                        }
                        loadedTerminalManagers.add(className);
                        Class theClass = getPlugInClass(className);
                        if (theClass != null) {
                            GenericTerminalManager manager = (GenericTerminalManager) theClass.newInstance();
                            manager.loadConfiguration(confFolderName, appName);
                            if (null != manager) {
                                stdParams.terminalManagers.add(manager);
                            }
                        }
                        break;
                    }
                    default:
                    /*//restore the unknown arg
                    ArrayList<String> args=argContext.getArgs();
                    int curArgIndex=argContext.getCurArgIndex();
                    args.set(curArgIndex, curArg.mark+curArg.value);

                    if(curArg.needInputFile())
                    argContext.setInputFile(null);
                    if(curArg.needOutputFile())
                    argContext.setOutputFile(null);*/

                }
            } catch (Throwable ex) {
                argContext.setThrowable(ex);
                return false;
            }
            return true;
        }

        public File getFileFromUser(int argId, boolean isOutputFile) throws IOException{
            return askForFile();
        }

        public File getOutputFileFromInputFile(int argId, File inputFilethrows IOException{
            return null;
        }
    }

    public static void main(String[] args) throws FileNotFoundException, IOException, InterruptedException, ScardException, ClassNotFoundException, InstantiationException, IllegalAccessException, UnsupportedLookAndFeelException {

        Main shell = new Main();
        shell.nimpSmartCardShell(args);
    }
    Throwable errorHappened = null;
    boolean logOutputSet = false;
    Throwable error = null;
    List<GenericTerminal> selectedTerminals = null;
    List<ScriptPlayer> players = null;
    List<Boolean> errors = null;
    List<File> logFiles = null;
    StdParams params;

    public void nimpSmartCardShell(String[] args) throws FileNotFoundException, IOException, InterruptedException, ScardException, ClassNotFoundException, InstantiationException, IllegalAccessException, UnsupportedLookAndFeelException {
        long start = System.nanoTime();
        ATextScreenOutputJFrame mainWindow;

        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        final SplashScreen splash = SplashScreen.getSplashScreen();

        PipedOutputStream pos = new PipedOutputStream();
        PrintStream outputStream = new PrintStream(pos);
        mainWindow = new ATextScreenOutputJFrame(true);
        mainWindow.monitorStream(pos);
        mainWindow.setTitle(ATimeUtilities.getTimeForUi() + " - Nimp smart card script player");

        System.setOut(outputStream);
        System.setErr(outputStream);

        if (splash != null) {
            splash.close();
        }

        mainWindow.setExtendedState(JFrame.MAXIMIZED_BOTH);
        mainWindow.setBackground(mainWindow.getBackground());//this get the system color for window background and apply it to the log area
        mainWindow.setVisible(true);

        ACommandLineUtilities.dispArgs(args);

        ACommandLineUtilities clUtil = null;
        try {
            List<GenericTerminal> availableTerminals = new LinkedList<GenericTerminal>();
            ArgSpec argSpecs[] = {
                new ArgSpec(ARG_PARALLEL_MODE, ARG_PARALLEL_MODE_ID),
                new ArgSpec(ARG_CHECK_CARD_CONNECTION, ARG_CHECK_CARD_CONNECTION_ID)
            };

            //params = processStdArgs(args, argSpecs, Main.class, "NimpSmartCardScriptPlayer");
            ArgSpec internalArgSpecs[] = addStdArgSpecs(argSpecs);
            //internalArgSpecs = ACommandLineUtilities.addArgFileArgSpecs(internalArgSpecs);
            Set specs = ACommandLineUtilities.addArgFileArgSpecs(internalArgSpecs);
            internalArgSpecs = new ArgSpec[specs.size()];
            specs.toArray(internalArgSpecs);

            ConfigArgProcessor configArgProcessor = new ConfigArgProcessor(Main.class, "NimpSmartCardScriptPlayer");
            clUtil = new ACommandLineUtilities(new File(AFileUtilities.getCurrentDirectory()), args, internalArgSpecs, configArgProcessor, true);
            clUtil.processArgs();
            clUtil.setAllowUnprocessedArgs(false);
            clUtil.throwIfError();

            params = configArgProcessor.getStdParams();
            //params.args = clUtil.getArgsAsArray();
            params.args=null;

            getAvailableTerminals(params.terminalManagers, availableTerminals);

            if (0 == availableTerminals.size()) {
                printNoTerminalMessage(params.terminalManagers);
                //throw new RuntimeException();
                error = new RuntimeException();
                return;
            }

            try {
                long startOfTerminalChooser = System.nanoTime();
                selectedTerminals = new LinkedList<GenericTerminal>();
                players = new LinkedList<ScriptPlayer>();
                errors = new LinkedList<Boolean>();
                logFiles = new LinkedList<File>();
                if (clUtil.hasArg(ARG_PARALLEL_MODE)) {
                    StringBuilder sb = new StringBuilder("Cards detected in following readers:\n");
                    StringBuilder terminalNames = new StringBuilder();
                    for (GenericTerminal terminal : availableTerminals) {
                        if (terminal.isCardPresent()) {
                            selectedTerminals.add(terminal);
                            players.add(new ScriptPlayer());
                            errors.add(Boolean.FALSE);
                            logFiles.add(null);
                            terminalNames.append("\t- ");
                            terminalNames.append(terminal.getName());
                            terminalNames.append("\n");
                        }
                    }
                    if (0 == selectedTerminals.size()) {
                        System.out.println("Could not find any card.");
                        mainWindow.setBackground(Color.red);
                        return;
                    }
                    if (clUtil.hasArg(ARG_FIXED_PARALLEL_MODE)) {

                        String nTerminalsStr = clUtil.getArgValue(ARG_FIXED_PARALLEL_MODE, null);
                        int nTerminals = Integer.decode(nTerminalsStr);
                        if (selectedTerminals.size() != nTerminals) {
                            String msg = "Command line request " + nTerminals + " terminals with card but " + selectedTerminals.size() + " have been detected:";
                            /*System.out.println(msg);
                            System.out.println(terminalNames);
                            mainWindow.setBackground(Color.red);
                            return;*/
                            msg += "\n" + terminalNames;
                            throw new RuntimeException(msg);
                        }
                    } else {
                        clUtil.getArgValue(ARG_PARALLEL_MODE, null);
                        sb.append(terminalNames);
                        sb.append("\nContinue ?\n");
                        int choice = JOptionPane.showConfirmDialog(null, sb.toString(), "Parallel mode", JOptionPane.OK_CANCEL_OPTION);
                        if (JOptionPane.OK_OPTION == choice) {
                            //nothing to do
                        }
                        if (JOptionPane.CANCEL_OPTION == choice) {
                            throw new StopRequestFromUserException("Operation cancelled by user.");
                        }
                    }
                    System.out.println("Launching parallel mode on " + selectedTerminals.size() + " terminals:");
                    System.out.println(terminalNames.toString());
                } else {
                    selectedTerminals.add(Utilities.terminalChooser(availableTerminals));
                    players.add(new ScriptPlayer());
                    errors.add(Boolean.FALSE);
                    logFiles.add(null);
                }
                deadTime += System.nanoTime() - startOfTerminalChooser;
                if (clUtil.hasArg(ARG_CHECK_CARD_CONNECTION, null)) {
                    List<GenericTerminal> unconnectedCardTerminals = new LinkedList<GenericTerminal>();
                    StringBuilder sb = new StringBuilder();
                    StringBuilder terminalNames = new StringBuilder();
                    for (GenericTerminal terminal : selectedTerminals) {
                        boolean connected = false;
                        try {
                            terminal.coldConnect();
                            connected = terminal.isConnected();
                        } catch (Throwable ex) {
                            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                        }
                        if (false == connected) {
                            unconnectedCardTerminals.add(terminal);
                            terminalNames.append("\t- ");
                            terminalNames.append(terminal.getName());
                            terminalNames.append("\n");
                        }
                    }
                    if (unconnectedCardTerminals.size() > 0) {
                        sb.append("Card connection failed on following ");
                        if (unconnectedCardTerminals.size() > 1) {
                            sb.append(unconnectedCardTerminals.size());
                            sb.append(" terminals:\n");
                        } else {
                            sb.append("terminal:\n");
                        }
                        sb.append(terminalNames);
                        //JOptionPane.showMessageDialog(null, sb.toString(), "Card connection check", JOptionPane.ERROR_MESSAGE);
                        //System.out.println(sb.toString());
                        //mainWindow.setBackground(Color.red);
                        //return;
                        throw new RuntimeException(sb.toString());
                    }
                }
            } catch (StopRequestFromUserException ex) {
                /*System.out.println("Operation stopped by user.");
                mainWindow.setBackground(Color.red);
                return;*/
                throw ex;
            }
            if (1 == selectedTerminals.size()) {
                selectedTerminals.get(0).addLogHandler(params.getPrintStreamLogHandler());
                System.out.println("Connected to " + selectedTerminals.get(0).getName());
            }

            //ACommandLineUtilities clUtil = new ACommandLineUtilities(new File(AFileUtilities.getCurrentDirectory()), args, argSpecs, this);
            clUtil.setArgProcessor(this);
            clUtil.reset();

            //ACommandLineUtilities.dispArgs(clUtil.getArgsAsArray());

            //try {
            while (clUtil.processArg()) {
                if (null != errorHappened) {
                    throw errorHappened;
                }
            }
            clUtil.throwIfError();
            System.out.println("No more arguments to process, exit.");
        } catch (StopRequestFromUserException ex) {
            if (ex != errorHappened) {
                error = ex;
            }
        } catch (Throwable ex) {
            if (ex != errorHappened) {
                error = ex;
                Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
            }
        } finally {
            //TODO: parallel mode handling
            //--> log stopped by user in each terminal log
            //--> if a terminal crash (throw something else than StopRequestFromUserException), only this one should be stopped
            long end = System.nanoTime();
            if (null != error) {
                errorHappened = new RuntimeException();
                //Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, error);
                if (error instanceof StopRequestFromUserException) {
                    System.out.println("Operations stopped by user.");
                } else if (null != clUtil) {
                    System.out.println("Current argument index: " + clUtil.getCurArgIndex());
                    System.out.println("Current argument: " + clUtil.getCurArg());
                    ACommandLineUtilities.dispArgs(clUtil.getArgsAsArray());
                }
            }
            long minTime = Long.MAX_VALUE;
            long maxTime = Long.MIN_VALUE;
            GenericTerminal minTimeTerminal = null;
            GenericTerminal maxTimeTerminal = null;
            if (null != selectedTerminals) {
                for (int i = 0; i < selectedTerminals.size(); i++) {
                    long terminalDeadTime = deadTime;
                    GenericTerminal terminal = selectedTerminals.get(i);
                    ScriptPlayer player = players.get(i);
                    boolean errorOnThisTerminal = errors.get(i);
                    File logFile = logFiles.get(i);
                    terminalDeadTime += player.getDeadTime();
                    if (null != terminal) {
                        terminalDeadTime += terminal.getDeadTime();
                    }
                    long terminalExecTime = end - start - terminalDeadTime;
                    if (minTime > terminalExecTime) {
                        minTime = terminalExecTime;
                        minTimeTerminal = terminal;
                    }
                    if (maxTime < terminalExecTime) {
                        maxTime = terminalExecTime;
                        maxTimeTerminal = terminal;
                    }
                    System.out.println("Total exec time on " + terminal + ": " + ATimeUtilities.getUserFriendlyTimeMs(terminalExecTime));

                    if (null != terminal) {
                        if (errorOnThisTerminal && (null != error)) {
                            errorHappened = new RuntimeException();
                            //terminal.logLine(ScardLogHandler.LOG_ERROR, error.getMessage());
                            terminal.log(error);
                            /*if ((null != params.ps) && (false == params.ps.equals(System.out))) {
                            error.printStackTrace(params.ps);
                            }*/
                            //Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, error);
                        }
                        terminal.logLine(ScardLogHandler.LOG_INFO, "Total exec time: " + ATimeUtilities.getUserFriendlyTimeMs(end - start - terminalDeadTime));
                        terminal.closeAllLogs();
                    }
                    if ((errorOnThisTerminal) || (false == player.isCheckOperation()) || (player.isUserCancelled())) {
                        errorHappened = new RuntimeException();
                        if (null != logFile) {
                            String nameOut = logFile.getAbsolutePath() + "_fail" + ATimeUtilities.getTimeTagMillisecond() + ".log";
                            File crashReportFile = new File(nameOut);
                            logFile.renameTo(crashReportFile);
                        }
                    }
                }

                /*Timing stuff broken
                 if (selectedTerminals.size() > 2) {
                    System.out.println("\nMinimum time: " + minTimeTerminal + ", " + ATimeUtilities.getUserFriendlyTimeMs(minTime));
                    System.out.println("Maximum time: " + maxTimeTerminal + ", " + ATimeUtilities.getUserFriendlyTimeMs(maxTime));
                }*/
            }

            if (null != errorHappened) {
                //mainWindow.setBackground(Color.red);
                colorComponent(mainWindow, SmartCardTask.ERROR);
            } else {
                //mainWindow.setBackground(Color.green);
                colorComponent(mainWindow, SmartCardTask.SUCCESS);
            }
        }
    }

    public boolean processArg(ACommandLineUtilities argContext) {
        try {
            Arg curArg = argContext.getCurArg();
            //File inputFile = argContext.getInputFile();
            //File outputFile = argContext.getOutputFile();
            //int curArgIndex = argContext.getCurArgIndex();
            switch (curArg.id) {
                case ARG_SET_PRINT_STREAM_LOG_ID:
                    argContext.consumeCurArg(); /*if(1==selectedTerminals.size()){
                selectedTerminals.get(0).removeLog(params.printStreamLogHandler);
                params.ps = new PrintStream(outputFile);
                params.printStreamLogHandler=new ScardPrintStreamLogHandler(params.ps);
                selectedTerminals.get(0).addLogHandler(params.printStreamLogHandler);
                logFiles.set(0, outputFile);
                }else*/ {
                    logOutputSet = true;
                    File outputFile = argContext.consumeOutputFile();
                    for (int i = 0; i < selectedTerminals.size(); i++) {
                        GenericTerminal terminal = selectedTerminals.get(i);
                        //terminal.closeAllLogs();//this close System.out !
                        for (ScardLogHandler logHandler : terminal.getLogs()) {
                            if (logHandler instanceof ScardPrintStreamLogHandler) {
                                ScardPrintStreamLogHandler printStreamLogHandler = (ScardPrintStreamLogHandler) logHandler;
                                if (printStreamLogHandler.getPrintStream() == System.out) {
                                    terminal.removeLog(logHandler);
                                } else {
                                    terminal.closeLog(logHandler);
                                }

                            } else {
                                terminal.closeLog(logHandler);
                            }
                        }
                        String baseName = outputFile.getAbsolutePath();
                        String ext = AFileUtilities.extractFileExtension(baseName);

                        String name =  terminal.getName() ;
                        //TODO: make sure that name don't contain forbiden characters like ":" and so on...
                        name=name.replace(':', '_');
                        name=name.replace('\\', '_');
                        name=name.replace('/', '_');
                        name=name.replace('*', '_');
                        name=baseName.substring(0, baseName.length() - ext.length()) +name+ "." + ext;
                        File logFile = new File(name);
                        logFiles.set(i, logFile);
                        PrintStream ps = new PrintStream(logFile);
                        ScardPrintStreamLogHandler printStreamLogHandler = new ScardPrintStreamLogHandler(ps);
                        terminal.addLogHandler(printStreamLogHandler);
                    }
                    System.out.println("Logging to " + outputFile.getCanonicalPath());
                    //outputFile = null;
                    //argContext.setOutputFile(null);
                    break;
                }
                case ARG_SET_STAR_SCRIPT_LOG_ID:
                    argContext.consumeCurArg(){
                    File outputFile = argContext.consumeOutputFile();
                    for (int i = 0; i < selectedTerminals.size(); i++) {
                        GenericTerminal terminal = selectedTerminals.get(i);

                        String baseName = outputFile.getAbsolutePath();
                        String ext = AFileUtilities.extractFileExtension(baseName);

                        String name = baseName.substring(0, baseName.length() - ext.length()) + terminal.getName() + "." + ext;
                        //TODO: make sure that name don't contain forbiden characters like ":" and so on...
                        File logFile = new File(name);
                        logFiles.set(i, logFile);
                        PrintStream ps = new PrintStream(logFile);
                        StarScriptLogHandler starScriptLogHandler = new StarScriptLogHandler(ps);
                        terminal.addLogHandler(starScriptLogHandler);
                    }
                    System.out.println("Logging to " + outputFile.getCanonicalPath());
                    break;
                }
                case ARG_SET_NRUN_ID:
                    argContext.consumeCurArg();
                    params.nRun = Integer.decode(curArg.value);
                    break;
                case ARG_TASK_ID:{
                    argContext.consumeCurArg();
                    int nArgs = 0;
                    int curArgIndex=argContext.getCurArgIndex();
                    try{
                        String className = curArg.value;
                        int comma = className.indexOf(',');
                        if (-1 != comma) {
                            String nArgString=className.substring(comma + 1);
                            if(nArgString.equals("..."))
                                nArgs = argContext.getArgs().size()-curArgIndex;
                            else
                                nArgs = Integer.decode(nArgString);
                            className = className.substring(0, comma);
                        }
                        Class theClass = getPlugInClass(className);
                        SmartCardTask task = null;
                        if (null != theClass) {
                            Object o = theClass.newInstance();
                            if (false == (o instanceof SmartCardTask)) {
                                throw new RuntimeException(ARG_TASK + " argument error: \"" + className + "\" is not an instance of " + SmartCardTask.class.getCanonicalName());
                            }
                            task = (SmartCardTask) o;
                            Initializable oldStyleTask=(Initializable) task;
                            //curArgIndex += task.initInstance(params.args, curArgIndex);
                            nArgs=oldStyleTask.initInstance(argContext, nArgs);

                            /*argContext.setArgSpecs();
                            argContext.checkArgs(nArgs);
                            argContext.setArgProcessor((ArgProcessor) task);
                            argContext.processArgs(nArgs);*/



                        } else {
                            throw new RuntimeException(ARG_TASK + " argument error: \"" + className + "\" could not be found.\n"
                                    + "Check the name and make sure this class is in the class path.\n"
                                    + "Jar file can be added to the class path using the argument \"" + ARG_ADD_JAR_FILE + "\"");
                        }

                        if (1 == selectedTerminals.size()) {
                            //this is kept for Micropross Dlls: calls fail when we use thread but works here :-S
                            //logLine(params, selectedTerminals.get(0), "Launching task: " + task.getAboutMsg() +"("+ curArg.value+")");
                            logLine(logOutputSet, selectedTerminals.get(0), "Launching task: " + task.getAboutMsg() + " (" + className + ")");
                            System.out.println("\t" + ATimeUtilities.getTimeForUi() + ": Waiting task completion");
                            //System.out.flush();
                            boolean old = errors.get(0);
                            errors.set(0, Boolean.TRUE);
                            try {
                                int status=SmartCardTask.ERROR;
                                for(int i=0;i<params.nRun;i++){
                                    Main.checkTaskPreferences(selectedTerminals.get(0), task);
                                    status = task.execute(selectedTerminals.get(0));
                                    if (SmartCardTask.SUCCESS != status) break;
                                }
                                if (SmartCardTask.SUCCESS == status) {
                                    errors.set(0, Boolean.FALSE);
                                }
                            } catch (Throwable ex) {
                                selectedTerminals.get(0).log(ex);
                                Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                            }
                            //System.out.flush();
                            //mainWindow.flush();
                            System.out.println("\t" + ATimeUtilities.getTimeForUi() + ": " + "task thread for " + selectedTerminals.get(0).getName() + " terminated");
                            //logLine(params, selectedTerminals.get(0), "\t"+ATimeUtilities.getTimeForUi()+": "+"starScript thread for "+selectedTerminals.get(0).getName()+" terminated");
                            System.out.println("\tAll tasks completed.");
                            if (errors.get(0)) {
                                System.out.println("\t" + selectedTerminals.get(0).getName() + " terminated with error.");
                                errorHappened = new RuntimeException();
                            } else {
                                errors.set(0, errors.get(0) | old);
                            }

                        } else {
                            System.out.println("Launching task: " + task.getAboutMsg() + " (" + className + ")");
                            TaskStarter starters[] = new TaskStarter[selectedTerminals.size()];
                            /*if (task instanceof MultiTerminalSmartCardTask) {
                                MultiTerminalSmartCardTask multiTerminalTask = (MultiTerminalSmartCardTask) task;
                                GenericTerminal[] terminals = new GenericTerminal[selectedTerminals.size()];
                                selectedTerminals.toArray(terminals);
                                //multiTerminalTask.execute(terminals);
                                MultiTerminalSmartCardTask.ParallelTask[] tasks = multiTerminalTask.getParallelTasks(terminals);
                                for (int i = 0; i < starters.length; i++) {
                                    starters[i] = new TaskStarter(selectedTerminals.get(i), task, tasks[i], params.nRun);
                                }
                            } else */{
                                for (int i = 0; i < starters.length; i++) {
                                    starters[i] = new TaskStarter(selectedTerminals.get(i), task.clone(), params.nRun);
                                }
                            }
                            Thread threads[] = new Thread[starters.length];
                            for (int i = 0; i < threads.length; i++) {
                                starters[i].terminal.logLine(ScardLogHandler.LOG_INFO, "Launching task: " + task.getAboutMsg() + " (" + className + ")");
                                threads[i] = new Thread(starters[i]);
                                threads[i].setName("starScript thread for " + starters[i].terminal.getName());
                                threads[i].start();
                            }
                            System.out.println("\t" + ATimeUtilities.getTimeForUi() + ": Waiting task completion");
                            for (int i = 0; i < starters.length; i++) {
                                try {
                                    threads[i].join();
                                } catch (InterruptedException ex) {
                                    //Logger.getLogger(CardReaderManagerView.class.getName()).log(Level.SEVERE, null, ex);
                                }
                            }
                            //mainWindow.flush();
                            System.out.println("\tAll tasks completed.");
                            for (int i = 0; i < threads.length; i++) {
                                if (false == starters[i].isErrorFree()) {
                                    System.out.println("\t" + threads[i].getName() + " terminated with error.");
                                    errors.set(i, Boolean.TRUE);

                                    errorHappened = new RuntimeException();
                                }
                            }

                        }
                    }finally{
                        argContext.setArgProcessor(this);
                        argContext.setCurArgIndex(curArgIndex+nArgs);
                    }
                    break;
                }
                case ARG_STAR_SCRIPT_FILE_ID:
                    argContext.consumeCurArg();
                    File inputFile = argContext.consumeInputFile();
                    if (1 == selectedTerminals.size()) {
                        //this is kept for Micropross Dlls: calls fail when we use thread but works here :-S
                        //logLine(params, selectedTerminals.get(0), "Launching star script: " + inputFile.getAbsolutePath());
                        logLine(logOutputSet, selectedTerminals.get(0), "Launching star script: " + inputFile.getAbsolutePath());
                        System.out.println("\t" + ATimeUtilities.getTimeForUi() + ": Waiting script completion");
                        //System.out.flush();

                        StarScriptReader script = new StarScriptReader(inputFile);
                        List<? extends Object> cmds = script.getCmds();
                        players.get(0).setnRun(params.nRun);
                        boolean old = errors.get(0);
                        errors.set(0, Boolean.TRUE);
                        try {
                            players.get(0).play(selectedTerminals.get(0), cmds);
                            if (players.get(0).isCheckOperation() && (false == players.get(0).isErrorOccured())) {
                                errors.set(0, Boolean.FALSE);
                            }
                        } catch (Throwable ex) {
                            selectedTerminals.get(0).log(ex);
                            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                        }
                        //System.out.flush();
                        //mainWindow.flush();
                        System.out.println("\t" + ATimeUtilities.getTimeForUi() + ": " + "starScript thread for " + selectedTerminals.get(0).getName() + " terminated");
                        //logLine(params, selectedTerminals.get(0), "\t"+ATimeUtilities.getTimeForUi()+": "+"starScript thread for "+selectedTerminals.get(0).getName()+" terminated");
                        System.out.println("\tAll scripts completed.");
                        if (errors.get(0)) {
                            System.out.println("\t" + selectedTerminals.get(0).getName() + " terminated with error.");
                            errorHappened = new RuntimeException();
                        } else {
                            errors.set(0, errors.get(0) | old);
                        }

                    } else {
                        System.out.println("Launching star script: " + inputFile.getAbsolutePath());
                        ScriptStarter starters[] = new ScriptStarter[selectedTerminals.size()];
                        for (int i = 0; i < starters.length; i++) {
                            starters[i] = new ScriptStarter(selectedTerminals.get(i), players.get(i), inputFile, params.nRun);
                        }
                        Thread startScriptThread[] = new Thread[starters.length];
                        for (int i = 0; i < starters.length; i++) {
                            starters[i].terminal.logLine(ScardLogHandler.LOG_INFO, "Launching star script: " + inputFile.getAbsolutePath());

                            startScriptThread[i] = new Thread(starters[i]);
                            startScriptThread[i].setName("starScript thread for " + starters[i].terminal.getName());
                            startScriptThread[i].start();
                        }
                        System.out.println("\t" + ATimeUtilities.getTimeForUi() + ": Waiting script completion");
                        for (int i = 0; i < starters.length; i++) {
                            try {
                                startScriptThread[i].join();
                            } catch (InterruptedException ex) {
                                //Logger.getLogger(CardReaderManagerView.class.getName()).log(Level.SEVERE, null, ex);
                            }
                        }
                        System.out.println("\tAll scripts completed.");
                        for (int i = 0; i < starters.length; i++) {
                            if (false == starters[i].isErrorFree()) {
                                System.out.println("\t" + startScriptThread[i].getName() + " terminated with error.");
                                errors.set(i, Boolean.TRUE);

                                errorHappened = new RuntimeException();
                            }
                        }
                    }
                    //inputFile = null;
                    //argContext.setInputFile(null);
                    break;
                default:
                    return false;
            }
        } catch (StopRequestFromUserException ex) {
            if (ex != errorHappened) {
                error = ex;
            }
            throw ex;
        } catch (Throwable ex) {
            if (ex != errorHappened) {
                error = ex;
                Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        return true;
    }

    public File getFileFromUser(int argId, boolean isOutputFile) {
        return askForFile();
    }

    public File getOutputFileFromInputFile(int argId, File inputFilethrows IOException{
        return null;
    }

    static public void colorComponent(Component c, int smartCardTaskRetCode) {
        switch (smartCardTaskRetCode) {
            case SmartCardTask.SUCCESS:
                c.setBackground(new Color(128, 255, 128));
                break;
            case SmartCardTask.WARNING:
                c.setBackground(Color.orange);
                break;
            case SmartCardTask.ERROR:
                c.setBackground(new Color(255, 80, 80));
                break;
            case SmartCardTask.SYSTEM_ERROR:
                c.setBackground(Color.magenta);
                break;
            default:
                c.setBackground(Color.magenta);
                throw new RuntimeException("SmartCardTask returned an unknown code: " + smartCardTaskRetCode);
        }
    }

    static public void checkTaskPreferences(GenericTerminal terminal, SmartCardTask task) throws ScardException, CardNotPresentException{
        if(SmartCardTask.FLAG_REQUIRE_RESET==task.getResetPreference()){
            terminal.connect(task.getProtocolPreference(), GenericTerminal.ACTIVATION_FORCE_COLD);
        }else{
            if(SmartCardTask.FLAG_ALLOW_RESET==task.getResetPreference()){
                if((GenericTerminal.PROTOCOL_ANY!=task.getProtocolPreference())&&(terminal.getProtocol()!=task.getProtocolPreference()))
                    terminal.connect(task.getProtocolPreference(), GenericTerminal.ACTIVATION_FORCE_COLD);
                if(false==terminal.isConnected())
                    terminal.connect(task.getProtocolPreference(), GenericTerminal.ACTIVATION_FORCE_COLD);

            }
        }
    }

    static public class ScriptStarter implements Runnable {

        final File in;
        final long nRun;
        final GenericTerminal terminal;
        final ScriptPlayer player;
        boolean errorFree;

        ScriptStarter(GenericTerminal terminal, ScriptPlayer player, File in, long nRun) {
            this.terminal = terminal;
            this.player = player;
            this.in = in;
            this.nRun = nRun;
        }

        public void run() {
            errorFree = false;
            try {
                List<? extends Object> cmds;
                StarScriptReader script = new StarScriptReader(in);
                cmds = script.getCmds();
                try {
                    player.setnRun(nRun);
                    player.play(terminal, cmds);
                    if (player.isCheckOperation() && (false == player.isErrorOccured())) {
                        errorFree = true;
                    }
                } catch (StopRequestFromUserException ex) {
                    //do nothing
                } catch (Throwable ex) {
                    terminal.log(ex);
                    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                }
            } catch (IOException ex) {
                terminal.log(ex);
                Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
            }
            System.out.println("\t" + ATimeUtilities.getTimeForUi() + ": " + Thread.currentThread().getName() + " terminated");
        }

        public boolean isErrorFree() {
            return errorFree;
        }
    }

    static public class TaskStarter implements Runnable {

        final long nRun;
        final GenericTerminal terminal;
        final SmartCardTask smartCardTask;
        //final MultiTerminalSmartCardTask.ParallelTask parallelTask;
        boolean errorFree;
        //MultiTerminalSmartCardTask parallelTask2;

        TaskStarter(GenericTerminal terminal, SmartCardTask task, long nRun) {
            this.terminal = terminal;
            this.smartCardTask = task;
            //this.parallelTask = null;
            this.nRun = nRun;
        }

        /*TaskStarter(GenericTerminal terminal, SmartCardTask rootTask, MultiTerminalSmartCardTask.ParallelTask task, long nRun) {
            this.terminal = terminal;
            this.smartCardTask = rootTask;
            this.parallelTask = task;
            this.nRun = nRun;
        }*/

        public void run() {
            errorFree = false;
            boolean errorHappened = false;
            try {
                for (int i = 0; i < nRun; i++) {
                    Main.checkTaskPreferences(terminal, smartCardTask);
                    int status;
                    //if (null == parallelTask) {
                        status = smartCardTask.execute(terminal);
                    /*} else {
                        parallelTask.run();
                        ScardException e = parallelTask.getScardException();
                        if (null != e) {
                            throw e;
                        }
                        status = parallelTask.getResult();
                    }*/
                    if (SmartCardTask.SUCCESS != status) {
                        errorHappened = true;
                    }
                }
                errorFree = !errorHappened;
            } catch (StopRequestFromUserException ex) {
                //do nothing
            } catch (Throwable ex) {
                terminal.log(ex);
                Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
            }
            System.out.println("\t" + ATimeUtilities.getTimeForUi() + ": " + Thread.currentThread().getName() + " terminated");
        }

        public boolean isErrorFree() {
            return errorFree;
        }
    }

    /*static void logLine(StdParams params, GenericTerminal terminal, String msg) {
    if (null != params.ps) {
    terminal.logLine(ScardLogHandler.LOG_INFO, msg);
    }
    if (System.out != params.ps) {
    System.out.println(msg);
    }
    }*/
    static void logLine(boolean logOutputSet, GenericTerminal terminal, String msg) {
        terminal.logLine(ScardLogHandler.LOG_INFO, msg);
        if (logOutputSet) {
            System.out.println(msg);
        }
    }

    static AFileChooser buildFileChooser() {
        AFileChooser fileChooser;
        fileChooser = new AFileChooser();
        FileNameExtensionFilter filter = new FileNameExtensionFilter("arg files", "arg");
        fileChooser.addChoosableFileFilter(filter);
        filter = new FileNameExtensionFilter("txt & cmd files", "txt", "cmd");
        fileChooser.addChoosableFileFilter(filter);
        fileChooser.setAcceptAllFileFilterUsed(true);
        return fileChooser;
    }

    protected static File askForFile() throws StopRequestFromUserException {
        File out;
        //if(null==fileChooser)
        //    buildFileChooser();
        AFileChooser fileChooser = buildFileChooser();
        long start = System.nanoTime();
        //fileChooser.setModalityType(ModalityType.TOOLKIT_MODAL);
        int option = fileChooser.showOpenDialog(null);
        fileChooser.saveCurrentPath();
        out = fileChooser.getSelectedFile();
        long end = System.nanoTime();
        fileChooser.dispose();
        deadTime += end - start;
        if (option != JFileChooser.APPROVE_OPTION) {
            throw new StopRequestFromUserException();
        }
        return out;
    }
}
TOP

Related Classes of uk.co.nimp.scard.Main$StdParams

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.