/** Creates a Pooled connection and adds it to the connection pool. */
  private void installConnection() throws EmanagerDatabaseException {
    logger.debug("enter");

    PooledConnection connection;

    try {
      connection = poolDataSource.getPooledConnection();
      connection.addConnectionEventListener(this);
      connection.getConnection().setAutoCommit(false);
      synchronized (connectionPool) {
        connectionPool.add(connection);
        logger.debug("Database connection added.");
      }
    } catch (SQLException ex) {
      logger.fatal("exception caught while obtaining database " + "connection: ex = " + ex);
      SQLException ex1 = ex.getNextException();
      while (ex1 != null) {
        logger.fatal("chained sql exception ex1 = " + ex1);
        SQLException nextEx = ex1.getNextException();
        ex1 = nextEx;
      }
      String logString;
      EmanagerDatabaseException ede;

      logString =
          EmanagerDatabaseStatusCode.DatabaseConnectionFailure.getStatusCodeDescription()
              + ex.getMessage();

      logger.fatal(logString);
      ede =
          new EmanagerDatabaseException(
              EmanagerDatabaseStatusCode.DatabaseConnectionFailure, logString);
      throw ede;
    }
  }
  /**
   * Put the JAIN-SIP stack in a state where it cannot receive any data and frees the network ports
   * used. That is to say remove JAIN-SIP <tt>ListeningPoint</tt>s and <tt>SipProvider</tt>s.
   */
  @SuppressWarnings("unchecked") // jain-sip legacy code
  private void stopListening() {
    try {
      this.secureJainSipProvider.removeSipListener(this);
      this.stack.deleteSipProvider(this.secureJainSipProvider);
      this.secureJainSipProvider = null;
      this.clearJainSipProvider.removeSipListener(this);
      this.stack.deleteSipProvider(this.clearJainSipProvider);
      this.clearJainSipProvider = null;

      Iterator<ListeningPoint> it = this.stack.getListeningPoints();
      Vector<ListeningPoint> lpointsToRemove = new Vector<ListeningPoint>();
      while (it.hasNext()) {
        lpointsToRemove.add(it.next());
      }

      it = lpointsToRemove.iterator();
      while (it.hasNext()) {
        this.stack.deleteListeningPoint(it.next());
      }

      this.stack.stop();
      if (logger.isTraceEnabled()) logger.trace("stopped listening");
    } catch (ObjectInUseException ex) {
      logger.fatal("Failed to stop listening", ex);
    }
  }
  /**
   * Takes as input a GnuPlot script file path and executes this script. inside the script the user
   * can plot to screen, pause and then print to a post script file.
   *
   * @param args args[0] should be the path to the GnuPlot script file relative to the Simulator
   *     directory e.g. ./inputFiles/100C_20P_centralised/Gnuplot.gnu
   *     <p>Example Script file GnuPlot.gnu:
   *     <p>set xlabel "Lateral Displacement"; set ylabel "Contra-Lateral Displacement"; set zlabel
   *     "Amplitude" set parametric set isosamples 75,75 set contour base set cntrparam level
   *     incremental -1, 0.2, 10 set clabel '%4.2f' set contour surface set contour base; set
   *     nosurface set surface; set view 20,60 set view 60,30 set hidden3d splot u,v,sin(u)*cos(v)
   *     title "Standing Waves" set size 1.0, 0.6 set terminal postscript portrait enhanced color
   *     dashed lw 1 "Helvetica" 14 set output 'tempoutput/my-plot.ps' replot set terminal x11 set
   *     size 1,1 #pause 5
   */
  public static void gnuplot(String[] args) {

    logger.info("gnuplot called on scriptfile: " + args[0]);
    // get a Runtime object
    Runtime r = Runtime.getRuntime();

    try {
      // start the process: gnuplot
      String exe = "wgnuplot " + args[0];
      // String exe = "C:/Program Files/gnuplot/bin/wgnuplot " + args[0];
      logger.info(exe);
      Process p = r.exec(exe);

      //			any error message?
      StreamGobbler errorGobbler = new StreamGobbler(p.getErrorStream(), "ERR");

      // any output?
      StreamGobbler outputGobbler = new StreamGobbler(p.getInputStream(), "OUT");

      // kick them off
      errorGobbler.start();
      outputGobbler.start();

      // any error???
      int exitVal = p.waitFor();
      logger.error("ExitValue: " + exitVal);

    } catch (Exception e) {
      logger.fatal("Error Executing gnuplot: " + args[0] + " - ", e);
    }
  }
  /**
   * Initializes and binds a socket that on a random port number. The method would try to bind on a
   * random port and retry 5 times until a free port is found.
   *
   * @return the socket that we have initialized on a randomport number.
   */
  private DatagramSocket initRandomPortSocket() {
    DatagramSocket resultSocket = null;
    String bindRetriesStr =
        NetaddrActivator.getConfigurationService().getString(BIND_RETRIES_PROPERTY_NAME);

    int bindRetries = 5;

    if (bindRetriesStr != null) {
      try {
        bindRetries = Integer.parseInt(bindRetriesStr);
      } catch (NumberFormatException ex) {
        logger.error(
            bindRetriesStr
                + " does not appear to be an integer. "
                + "Defaulting port bind retries to "
                + bindRetries,
            ex);
      }
    }

    int currentlyTriedPort = NetworkUtils.getRandomPortNumber();

    // we'll first try to bind to a random port. if this fails we'll try
    // again (bindRetries times in all) until we find a free local port.
    for (int i = 0; i < bindRetries; i++) {
      try {
        resultSocket = new DatagramSocket(currentlyTriedPort);
        // we succeeded - break so that we don't try to bind again
        break;
      } catch (SocketException exc) {
        if (exc.getMessage().indexOf("Address already in use") == -1) {
          logger.fatal(
              "An exception occurred while trying to create" + "a local host discovery socket.",
              exc);
          resultSocket = null;
          return null;
        }
        // port seems to be taken. try another one.
        logger.debug("Port " + currentlyTriedPort + " seems in use.");
        currentlyTriedPort = NetworkUtils.getRandomPortNumber();
        logger.debug("Retrying bind on port " + currentlyTriedPort);
      }
    }

    return resultSocket;
  }
  private void initializeDatabaseContext() throws EmanagerDatabaseException {
    logger.debug("Enter");

    Properties properties;
    SybConnectionPoolDataSource poolDataSource;

    properties = new Properties();
    poolDataSource = new com.sybase.jdbc2.jdbc.SybConnectionPoolDataSource();

    poolDataSource.setUser(userAccount);
    poolDataSource.setPassword(password);
    poolDataSource.setDatabaseName(databaseName);
    poolDataSource.setServerName(databaseHost);
    poolDataSource.setPortNumber(connectionPort);
    poolDataSource.setDescription(connectionPoolDescription);

    properties.put("user", userAccount);
    properties.put("password", password);
    properties.put("APPLICATIONNAME", clientAppName);
    // fix
    // hopefully these have defaults
    // properties.put("USE_METADATA", userMetaData);
    // properties.put("REPEAT_READ", useRepeatRead);
    // properties.put("CHARSET_CONVERTER_CLASS", charsetConverter);

    properties.put("server", "jdbc:sybase:Tds:" + databaseHost + ":" + connectionPort);

    try {
      poolDataSource.setConnectionProperties(properties);
      // jndiContext.bind("jdbc/protoDB", poolDataSource);
      jndiContext.bind(JNDIContextName, poolDataSource);
    } catch (Exception ex) {
      String logString;
      EmanagerDatabaseException ede;

      logString =
          EmanagerDatabaseStatusCode.UnableToBindJNDIContext.getStatusCodeDescription()
              + ex.getMessage();

      logger.fatal(logString);
      ede =
          new EmanagerDatabaseException(
              EmanagerDatabaseStatusCode.UnableToBindJNDIContext, logString);
      throw ede;
    }
  }
  public void run() {
    try {
      PrintWriter pw = null;
      if (os != null) pw = new PrintWriter(os);

      InputStreamReader isr = new InputStreamReader(is);
      BufferedReader br = new BufferedReader(isr);
      String line = null;
      while ((line = br.readLine()) != null) {
        if (pw != null) pw.println(line);
        logger.info(type + ">" + line);
      }
      if (pw != null) pw.flush();
    } catch (IOException ioe) {
      logger.fatal("IOE: ", ioe);
    }
  }
  public static void convertPstoEps(String[] args) {

    logger.info("Converting Postscript file to an Encapsulated Postscript file with Bounding box");

    String directory = args[0];
    String[] cmd = new String[] {"ps2epsi", args[1], args[2]};

    if (cmd.length > 0) {
      String cmdString = "Executing process: \\" + directory + ">" + cmd[0].toString();
      for (int counter = 1; counter < cmd.length; counter++) {
        cmdString += " " + cmd[counter].toString();
      }
      logger.info(cmdString);
    } else {
      logger.error("convertPstoEps ERROR: empty command string! EXITING.....");
      return;
    }

    Runtime r = Runtime.getRuntime();

    try {
      // start the process
      Process p = r.exec(cmd, null, new File(directory));

      // any error message?
      StreamGobbler errorGobbler = new StreamGobbler(p.getErrorStream(), "ERR");

      // any output?
      StreamGobbler outputGobbler = new StreamGobbler(p.getInputStream(), "OUT");

      // kick them off
      errorGobbler.start();
      outputGobbler.start();

      // any error???
      int exitVal = p.waitFor();
      logger.error("ExitValue: " + exitVal);

    } catch (Exception e) {
      logger.fatal("Error Executing convertPstoEps", e);
    }
  }
  /**
   * Constructor for this class. Creates the JAIN-SIP stack.
   *
   * @throws OperationFailedException if creating the stack fails.
   */
  SipStackSharing() throws OperationFailedException {
    // init of the stack
    try {
      SipFactory sipFactory = SipFactory.getInstance();
      sipFactory.setPathName("org.jitsi.gov.nist");

      Properties sipStackProperties = new SipStackProperties();

      // Create SipStack object
      this.stack = sipFactory.createSipStack(sipStackProperties);
      if (logger.isTraceEnabled()) logger.trace("Created stack: " + this.stack);

      // set our custom address resolver managing SRV records
      AddressResolverImpl addressResolver = new AddressResolverImpl();
      ((SIPTransactionStack) this.stack).setAddressResolver(addressResolver);

      SipActivator.getNetworkAddressManagerService().addNetworkConfigurationChangeListener(this);
    } catch (Exception ex) {
      logger.fatal("Failed to get SIP Factory.", ex);
      throw new OperationFailedException(
          "Failed to get SIP Factory", OperationFailedException.INTERNAL_ERROR, ex);
    }
  }
  /**
   * The constructor obtains a ConnectionPoolDataSource reference via JNDI. This datasource is used
   * when new database connections need to be established and maintained in some container (pool).
   */
  public void initializeConnectionPoolConnections() throws EmanagerDatabaseException {
    logger.debug("enter");

    try {
      poolDataSource = (ConnectionPoolDataSource) jndiContext.lookup(JNDIContextName);
    } catch (Exception ex) {
      String logString;
      EmanagerDatabaseException ede;

      logString =
          EmanagerDatabaseStatusCode.DatabaseJNDILookupFailure.getStatusCodeDescription()
              + ex.getMessage();

      logger.fatal(logString);
      ede =
          new EmanagerDatabaseException(
              EmanagerDatabaseStatusCode.DatabaseJNDILookupFailure, logString);
      throw ede;
    }

    for (int i = 0; i < connectionPoolSize; i++) {
      installConnection();
    }
  }
  /**
   * Runs a Windows command line tool e.g. dir etc
   *
   * <p>not for running processes
   *
   * <p>Argument format is "\aboslute path;commandname;arg0;arg1;arg2;.....;argN" OR ".relative
   * path;commandname;arg0;arg1;arg2;.....;argN"
   *
   * <p>you cannot enter ";dir" to indicate current directory as it will use dir as the directory!
   *
   * <p>where arg0, arg1 etc are space separated arguements.
   *
   * <p>so to execute the command dir in the simulator directory the variables should be .;dir to
   * execute dir in a directory tempoutput one level up from simulator .\tempoutput;dir to execute
   * dir in the root directory \;dir
   *
   * @param args
   */
  public static void command(String[] args) {

    logger.info("Shell Command executer for Windows XP called");

    String[] cmd = new String[args.length + 1];
    cmd[0] = "cmd.exe";
    cmd[1] = "/C";

    String directory = "";

    // System.out.println("args[0] = " + args[0]);
    // System.out.println("args[0].charAt(0) = " + args[0].charAt(0));

    try {
      switch ((args[0].charAt(0))) {
        case '.':
          directory = (new File(".")).getCanonicalPath() + args[0].substring(1);
          break;
        case '\\':
          directory = args[0];
          break;
        default:
          directory = (new File(".")).getCanonicalPath() + args[0].substring(1);
      }
    } catch (IOException e) {
      logger.fatal("command: Failed to get the current path", e);
    }

    logger.info("directory =" + directory);

    if (args.length > 1) {
      for (int counter = 1; counter < args.length; counter++) {
        cmd[counter + 1] = args[counter];
      }
    }

    if (cmd.length > 0) {
      String cmdString;

      cmdString = "Executing process: " + directory + ">" + cmd[0].toString();

      for (int counter = 1; counter < cmd.length; counter++) {
        cmdString += " " + cmd[counter].toString();
      }
      logger.info(cmdString);
    } else {
      logger.error("command ERROR: empty command string! EXITING.....");
      return;
    }

    Runtime r = Runtime.getRuntime();

    try {
      // start the process
      Process p = r.exec(cmd, null, new File(directory));

      // any error message?
      StreamGobbler errorGobbler = new StreamGobbler(p.getErrorStream(), "ERR");

      // any output?
      StreamGobbler outputGobbler = new StreamGobbler(p.getInputStream(), "OUT");

      // kick them off
      errorGobbler.start();
      outputGobbler.start();

      // any error???
      int exitVal = p.waitFor();
      logger.error("ExitValue: " + exitVal);

    } catch (Exception e) {
      logger.fatal("Error Executing command", e);
    }
  }