// gracefull shutdown
 public void shutdown() {
   Utils.logMessage(this, Severity.WARN, "system shutdown requested.");
   try {
     connPool.closeAllConnections();
   } catch (SQLException e) {
     Utils.logMessage(this, Severity.ERROR, "sql error returned from pool : " + e.getMessage());
   }
   Utils.logMessage(this, Severity.INFO, "system gracefully shutdown.");
   System.exit(0);
 }
  // private c'tor 'hides' the public default one. CouponSystem is a singleton
  private CouponSystemJFrame() {
    // load sys params from properties file
    Utils.logMessage(this, Severity.INFO, "Coupon system created.");

    // NOT IN USE in a web-coupon system. ( see method doc )
    // Utils.sysparam already set by a LoaderServlet
    //
    // Utils.loadSystemParameters();
    sysParams = Utils.getSystemParameters();
    _systemName = sysParams.get("SYSTEM_NAME");
    _adminHash = sysParams.get("ADMIN_HASH");
    _lookAndFeelTemplate = sysParams.get("LOOK_AND_FEEL_TEMPLATE");
    _threadEnabled = Boolean.parseBoolean(sysParams.get("THREAD_ENABLED"));
    _threadIntervalMinutes = Integer.parseInt(sysParams.get("THREAD_INTERVAL_MINUTES"));
    _loggingEnabled = Boolean.parseBoolean(sysParams.get("LOGGING_ENABLED"));
    Utils.setLoggingEnabled(_loggingEnabled);
    Utils.logMessage(
        this, Severity.DEBUG, "hashmap assigned to local vars, configuration applied.");

    setTitle("Coupon System : " + _systemName);
    setResizable(false);
    try {
      UIManager.setLookAndFeel(_lookAndFeelTemplate);
    } catch (ClassNotFoundException
        | InstantiationException
        | IllegalAccessException
        | UnsupportedLookAndFeelException e) {
      Utils.logMessage(this, Severity.PANIC, "cannot load LookAndFeel template. exiting...");
      e.printStackTrace();
      // System.exit(0);
    }

    // load this JFrame only after initialization from properties file.
    this.setVisible(true);

    // Main app CANNOT be closed with 'x' , must press on the 'shutdown'
    // buttong for gracefull shutdown.
    setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
    setBounds(100, 100, 785, 380);
    contentPane = new JPanel();
    contentPane.setLayout(null);
    setContentPane(contentPane);

    btnLogin = new JButton("Login");
    btnLogin.addActionListener(this);
    btnLogin.setBounds(659, 253, 98, 79);
    contentPane.add(btnLogin);

    listSysParams = new JList<Entry<String, String>>();
    listSysParams.setBorder(new LineBorder(new Color(0, 0, 0)));
    listSysParams.setFont(new Font("Consolas", Font.PLAIN, 14));
    listSysParams.setEnabled(false);
    listSysParams.setBounds(20, 11, 737, 219);
    contentPane.add(listSysParams);

    // a model is needed for JTable
    DefaultListModel<Entry<String, String>> model = new DefaultListModel<Entry<String, String>>();
    listSysParams.setModel(model);

    JPanel panelSystem = new JPanel();
    panelSystem.setBorder(new LineBorder(new Color(0, 0, 0)));
    panelSystem.setLayout(null);
    panelSystem.setBounds(20, 253, 428, 79);
    contentPane.add(panelSystem);

    btnShutdown = new JButton("Shutdown system");
    btnShutdown.setForeground(Color.RED);
    btnShutdown.setBounds(20, 36, 181, 23);
    panelSystem.add(btnShutdown);

    btnThread = new JButton("Stop cleaner thread");
    btnThread.addActionListener(this);
    btnThread.setForeground(Color.RED);
    btnThread.setBounds(224, 36, 181, 23);
    panelSystem.add(btnThread);

    JLabel lblSys =
        new JLabel(
            "Coupon system running on : "
                + System.getProperty("os.name")
                + " / [version-"
                + System.getProperty("os.version")
                + "].");
    lblSys.setBounds(20, 11, 369, 14);
    panelSystem.add(lblSys);
    btnShutdown.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent arg0) {
            // calling for gracefull shutdown
            shutdown();
          }
        });

    // get a Set of Entries from all KVP in Map
    Set<Entry<String, String>> entries = sysParams.entrySet();
    for (Entry<String, String> entry : entries) {
      model.addElement(entry);
    }

    // get/create the connection pool
    connPool = ConnPool.getInstance();

    // pass it to DAO's
    createDAOs(connPool);

    if (_threadEnabled) {
      // start the daily cleaner thread
      startTimer();
    }
  }