⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 startitprocess.java

📁 SRI international 发布的OAA框架软件
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/**
 * The contents of this file are subject to the OAA  Community Research
 * License Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License
 * at http://www.ai.sri.com/~oaa/.  Software distributed under the License
 * is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
 * express or implied. See the License for the specific language governing
 * rights and limitations under the License.  Portions of the software are
 * Copyright (c) SRI International, 1999-2003.  All rights reserved.
 * "OAA" is a registered trademark, and "Open Agent Architecture" is a
 * trademark, of SRI International, a California nonprofit public benefit
 * corporation.
*/

package com.sri.oaa2.agt.startit;

import java.io.*;
import java.util.*;
import java.util.regex.*;
import java.lang.String;

import java.awt.Color; // to report status light colors
// NOTE: even if there's no gui, this module needs to be able to report
//       info about what color a light should be, in case another agent
//       wishes to show its own version of startit lights (the old ptt
//       agent did this)

public class StartitProcess {
  // AppStates
  public static final int NOT_RUNNING      = 401;
  public static final int INITIALIZING     = 402;
  public static final int READY            = 403;
  public static final int KILLING          = 404;
  public static final int DIED             = 405;
  public static final int WAITING_TO_START = 406;
  public static final int WAITING_ON_READY_TO_KILL = 407;
  public static final int WAITING_TO_KILL          = 408;

  public static final int NONAGENT_RUNNING = 421;
  public static final int NONAGENT_KILLING = 422;
  public static final int NONAGENT_DIED    = 423;
  public static final int NONAGENT_WAITING = 424;
  public static final int NONAGENT_WAITING_TO_KILL = 425;

  private AppInfo appinfo;
  private String oaaID;
  private OaaConnection oaa; // will stay NULL if my AppInfo is NOT an agent

  private final Hashtable/*OutputFlag, Boolean*/ outputSeen = new Hashtable();

  private ThreadForExec mExec = null;
  private int mState = NOT_RUNNING; // ALWAYS use changeState() to change this field!

  private LoginInfo mLoginInfo;
  private Vector/*String*/ mEnvironment;
  private String mDirectory;
  private String mCommand;

  private Vector/*StatusChangeListener*/ listeners = new Vector();

  private static javax.swing.Timer startDelayTimer;
  private static int timerDelay = 0;

  public StartitProcess(AppInfo a) {
    appinfo = a;
  }

  public static void setStartTimerDelay(int ms) {
    timerDelay = ms;
  }

  protected void setOaaConnection(OaaConnection o) {
    if (oaa != null) return; // only can set it once
    oaa = o;
    oaa.addStatusListener(new OaaConnection.StatusListener() {
      public void agentStatusChanged(String agentName, String status, String oaaID) {
	setReady(oaaID);
      }
    }, appinfo.oaaname);
  }

  public OaaConnection getOaaConnection() {
    return oaa;
  }

  public void setLoginInfo(LoginInfo l) {
    if (!isStarted()) mLoginInfo = l;
  }
  public void setEnvironment(Vector/*String*/ v) {
    if (!isStarted()) mEnvironment = v;
  }
  public void setDirectory(String d) {
    if (!isStarted()) mDirectory = d;
  }
  public void setCommand(String c) {
    if (!isStarted()) mCommand = c;
  }

  /** Gives information about the state of the monitored process
      @return one of the AppState ints, e.g. StartitProcess.READY
  */
  public int getState() {
    return mState;
  }

  private void setReady(String id) {
    oaaID = id;
    if (mState == INITIALIZING) {
      changeState(READY);
    }
    else if (mState == WAITING_ON_READY_TO_KILL) {
      mState = READY; // NOTE: change state WITHOUT informing anyone!
      kill();
    }
    else {
      System.err.println("WARNING: agent reported ready, but wasn't initializing");
    }
  }

  /** Groups the many getState() outputs into a boolean: busy or not.
    @return True if it's running, waiting, dying, etc.  False if it's dead or otherwise not running.
   */
  public boolean isBusy() {
    return isBusy(mState);
  }

  public boolean isStarted() {
    return isStarted(mState);
  }

  public boolean isWaiting() {
    return (mState == WAITING_TO_START || mState == NONAGENT_WAITING);
  }

  public boolean isWaitingToBeKilled() {
    // This method is only for apps waiting for the death of other apps
    // (so do *NOT* return true for WAITING_ON_READY_TO_KILL!)
    return (mState == WAITING_TO_KILL || mState == NONAGENT_WAITING_TO_KILL);
  }

  public static boolean isBusy(int state) {
    switch (state) {
    case NOT_RUNNING:
    case DIED:
    case NONAGENT_DIED:
      return false;
    default:
      return true;
    }
  }

  public static boolean isStarted(int state) {
    switch (state) {
    case INITIALIZING:
    case READY:
    case KILLING:
    case WAITING_ON_READY_TO_KILL:
    case WAITING_TO_KILL:
    case NONAGENT_RUNNING:
    case NONAGENT_KILLING:
    case NONAGENT_WAITING_TO_KILL:
      return true;
    default:
      return false;
    }
  }

  public boolean isAgentProcess() {
    //    return appinfo.isAgent() && (oaa != null);
    return appinfo.isAgent();
  }

  public boolean needToWait() {
    // if we have a running startDelayTimer, then we needToWait
    if (startDelayTimer != null && startDelayTimer.isRunning()) {
      return true;
    }

    // if there are agentsToWaitFor and any of them are not READY, we needToWait
    for(Iterator i = appinfo.agentsToWaitFor.iterator(); i.hasNext(); ) {
      AppInfo app = (AppInfo) i.next();
      if (app.getProcess().getState() != READY) {
	StartitInfo.debugPrint(appinfo, "waiting for " + app.appid);
	return true;
      }
    }

    // if there is output we're waiting for from some app, which hasn't
    // been seen yet, we needToWait
    for(Iterator i = appinfo.waitforoutput.iterator(); i.hasNext(); ) {
      AppInfo.OutputFlag flag = (AppInfo.OutputFlag) i.next();
      if (!flag.hasSeenOutput()) {
	StartitInfo.debugPrint(appinfo, "waiting for output from " + flag.appname);
	return true;
      }
    }

    // otherwise, no needToWait!
    return false;
  }

  public boolean needToWaitToKill() {
    for(Iterator i = appinfo.appsWaitingForMe.iterator(); i.hasNext(); ) {
      AppInfo app = (AppInfo) i.next();
      if (app.getProcess().isBusy()) {
	StartitInfo.debugPrint(appinfo, "waiting for " + app.appid + " to kill");
	return true;
      }
    }
    return false;
  }

  protected void start() { start(false); }

  /** Starts the process to monitor.
      Call getState() after requesting a start to find out if it was started, is waiting, etc.
  */
  protected void start(boolean forceNoWait) {
    if (isStarted()) {return;}
    if (!forceNoWait && needToWait()) {
      changeState(isAgentProcess() ? WAITING_TO_START : NONAGENT_WAITING);
      return;
    }

    // if we've made it here we're ready to start
    // first reset and start the delay timer 
    if (timerDelay > 0) {
      startDelayTimer = new javax.swing.Timer(timerDelay, 
					      new java.awt.event.ActionListener() {
	public void actionPerformed(java.awt.event.ActionEvent e) {
	  startDelayTimer.stop();
	  appinfo.sinfo.startWaitingApps();
	}
      });
      startDelayTimer.start();
    }

    // then start
    appinfo.updateToStart();
    mExec = new ThreadForExec();
    try {
      //System.out.println("Before mExec.start");
      changeState(isAgentProcess() ? INITIALIZING : NONAGENT_RUNNING);

      if (appinfo.isFacilitator() && !oaa.isConnected()) {
	oaa.pollToConnect(appinfo.getHost(), appinfo.port,
			  new OaaConnection.ConnectListener() {
	  public void oaaConnected() {
	    oaaID = "root";
	    changeState(READY);
	  }
	});
      }
      mExec.start();
    }
    catch (IllegalThreadStateException startException) {
      changeState(isAgentProcess() ? DIED : NONAGENT_DIED);
      System.out.println("Start exception " + startException);
    }
  }

  /** Stops the process to monitor
      Call getState() after requesting a stop to find out if it was killed. 
  */
  public void kill() {
    switch(mState) {

    case READY:
    case WAITING_TO_KILL:
      if (needToWaitToKill()) {
	changeState(WAITING_TO_KILL);
	return;
      }
      changeState(KILLING);
      oaa.sendHalt(oaaID);
      return;

    case INITIALIZING:
      // if windows, we can't kill a process, so wait til it connects
      // then tell it to die
	/*
      if (isWindows()) {
	changeState(WAITING_ON_READY_TO_KILL);
	return;
      }
	*/
      // otherwise, fall through to here to kill it:
    case NONAGENT_WAITING_TO_KILL:
    case NONAGENT_RUNNING:
      if (needToWaitToKill()) {
	changeState(isAgentProcess() ? WAITING_TO_KILL : NONAGENT_WAITING_TO_KILL);
	return;
      }
      changeState(isAgentProcess() ? KILLING : NONAGENT_KILLING);
      killProcess();
      return;

    case WAITING_TO_START:
    case NONAGENT_WAITING:
      reportDeath();
    case DIED:
    case NONAGENT_DIED:
      changeState(NOT_RUNNING);
      return;
    }
  }

  private void killProcess() {
    try {
      if ((mExec != null) && (mExec.mProcessToWatch != null)) {
	mExec.mProcessToWatch.destroy();
      }
      mExec = null;
    }
    catch (IllegalThreadStateException stopException) {
      System.out.println("Stop exception " + stopException);
    }
  }

  public void addStatusChangeListener(StatusChangeListener l) {
    listeners.add(l);
  }

  public void removeStatusChangeListener(StatusChangeListener l) {
    listeners.remove(l);
  }

  private synchronized void reportDeath() {
    if (mState == KILLING || mState == NONAGENT_KILLING ||
	mState == WAITING_TO_KILL || mState == NONAGENT_WAITING_TO_KILL ||
	mState == WAITING_ON_READY_TO_KILL) {
      changeState(NOT_RUNNING);
    }
    else {
      changeState(isAgentProcess() ? DIED : NONAGENT_DIED);
    }
    // reset hasSeenOutput for all flags to false
    for (Iterator i = outputSeen.keySet().iterator(); i.hasNext(); ) {
      outputSeen.put(i.next(), Boolean.FALSE);
    }
    if (appinfo.isFacilitator()) {
      // in case we were polling, it was initializing, and it died
      oaa.stopPolling();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -