/** Prints the current state of the remote experiment. */
  protected void printCurrentState() {
    if (isRemExpConnected) Debg.print(NanoComm.strInfo(NanoComm.INFO_REMEXP_CONNECTED));
    else Debg.print(NanoComm.strInfo(NanoComm.INFO_REMEXP_DISCONNECTED));
    Debg.print(NanoComm.strState(currentState));
    Debg.print(NanoComm.strParam(NanoComm.PARAM_SAMPLESCLEAR + " value=all"));
    for (Sample s : allSamples) {
      Debg.print(
          NanoComm.strParam(
              NanoComm.PARAM_SAMPLEINFO
                  + " value="
                  + s.getSampleID()
                  + " name="
                  + s.getSampleName()
                  + " command="
                  + s.getLockCommand()));
    }
    Debg.print(NanoComm.strParam(NanoComm.PARAM_SCANRANGE + " value=" + scanRange));
    int smpl;
    if (currentSample == null) smpl = -1;
    else smpl = currentSample.getSampleID();

    Debg.print(NanoComm.strParam(NanoComm.PARAM_STAGEPOSITION + " value=" + smpl));
    Debg.print(NanoComm.strParam(NanoComm.PARAM_SCANSTART + " value=" + scanStart));
    Debg.print(NanoComm.strParam(NanoComm.PARAM_REMEXPNAME + " value=" + remExpName));
  }
 /** Checks the lockHolder for timeout on the lock. */
 @Override
 public void doTask() {
   if (lockHolder != null) {
     long now = new Date().getTime();
     if (lockStarted + lockHolder.getLockTimeoutInSeconds() * 1000 < now) {
       setLock(lockHolder.takeAbortActions("Lock timed out"));
       Debg.print("Lock timed out, took abort actions");
       lockStarted = 0;
     }
   }
   processNextClientRequest();
   try {
     Thread.sleep(500);
   } catch (InterruptedException e) {
     Debg.err("Failed sleeping");
   }
 }
 private void processNextClientRequest() {
   QueueEntry qe = (QueueEntry) qClientRequests.poll();
   if (qe != null) {
     EventSocket sock = qe.sock;
     String message = qe.message;
     boolean isAllowed = false;
     LockHolder lock = getLockForCommand(message);
     if (lock != null) {
       // if the lock exists check whether the user is allowed to use this command
       int[] privs = lock.getAllowedPrivileges();
       for (int priv : privs) if (priv == sock.getPrivilege()) isAllowed = true;
       if (isAllowed) {
         if (lockHolder == null) { // if no lock is set we try to execute the command
           setLock(lock.setLockAction(message));
           Debg.print("lock set and executed");
         } else { // if a lock is already set the command might contain an abort message
           String cmd = Parser.getValue(message, NanoComm.COMMAND_CMD);
           String[] abortCmds = lockHolder.getAbortCommands();
           boolean isAbortable = false;
           if (abortCmds != null)
             for (int i = 0; i < abortCmds.length; i++) {
               if (cmd.equals(abortCmds[i])) isAbortable = true;
             }
           if (isAbortable) {
             setLock(lockHolder.takeAbortActions("Overwriting command has been sent"));
           } else sock.sendClientInfo("Please be patient, the remote experiment is still busy");
         }
       } else sock.sendClientInfo("Sorry, you are not allowed to use this command!");
     } else Debg.print("No lock found for: " + message);
   }
   if (qClientRequests.size() > 10) {
     Debg.err(
         "I have been flooded by "
             + qClientRequests.size()
             + " client requests! I dropped everything except for the oldest one");
     qe = (QueueEntry) qClientRequests.poll();
     qClientRequests.clear();
     qClientRequests.add(qe);
   }
 }
 /**
  * The constructor for this command processing class. It links to the FilteringPool instance to
  * pass actions towards the remote experiment server.
  *
  * @param chief The restricted server instance that runs as middleware between the clients and the
  *     remote experiments server.
  */
 public RemoteExperimentMonitor(FilteringPool chief) {
   remExpName = "RemExp";
   pool = chief;
   qClientRequests = new ConcurrentLinkedQueue();
   initParser();
   allSamples = new Vector<Sample>();
   initMonitorVars();
   setLock(null);
   lastStreamData = null;
   scanStart = -1;
   super.start(this.getClass().getSimpleName());
   Debg.print("Remote experiments monitor initialized");
 }
 /**
  * Sets and broadcasts information about the connectivity and state of the remote experiment.
  *
  * @param isConnected true if connected, else false
  */
 protected void setRemExpConnected(boolean isConnected) {
   Debg.print("Remote Experiment connected: " + isConnected);
   isRemExpConnected = isConnected;
   if (isConnected) {
     currentState = NanoComm.STATE_STAGECALIBRATED;
     broadcastToClients(NanoComm.strState(currentState));
     broadcastToClients(NanoComm.strInfo(NanoComm.INFO_REMEXP_CONNECTED));
   } else {
     initMonitorVars();
     currentState = NanoComm.STATE_UNAVAILABLE;
     broadcastToClients(NanoComm.strState(currentState));
   }
 }
 /**
  * This method is used to set and broadcast the actual state of the remote experiment.
  *
  * @param state The state the remote experiment monitor is in now.
  */
 public void setCurrentState(int state) {
   currentState = state;
   broadcastToClients(NanoComm.strState(currentState));
   Debg.print("Setting state " + state);
 }
 /**
  * Passes a message to the pool which will apss it further to the remote experiment.
  *
  * @param msg
  */
 public void sendToRemExp(String msg) {
   Debg.print("sending to remexp: " + msg);
   if (pool != null) {
     pool.sendToRemExp(msg);
   }
 }