Package jade.wrapper.gateway

Source Code of jade.wrapper.gateway.DynamicJadeGateway

package jade.wrapper.gateway;

//#J2ME_EXCLUDE_FILE

import java.util.ArrayList;
import java.util.List;

import jade.core.AID;
import jade.core.Agent;
import jade.core.Profile;
import jade.core.ProfileImpl;
import jade.core.Runtime;
import jade.util.Event;
import jade.util.Logger;
import jade.util.leap.Properties;
import jade.wrapper.AgentController;
import jade.wrapper.ContainerController;
import jade.wrapper.ControllerException;
import jade.wrapper.StaleProxyException;

public class DynamicJadeGateway {

  private static final int UNKNOWN = -1;
  private static final int ACTIVE = 1;
  private static final int NOT_ACTIVE = 2;
 
  private ContainerController myContainer = null;
  private AgentController myAgent = null;
  private String agentType = GatewayAgent.class.getName();
  // jade profile properties
  private ProfileImpl profile;
  private Properties jadeProps;
  private Object[] agentArguments;
 
  private int gatewayAgentState = UNKNOWN;
  //#DOTNET_EXCLUDE_BEGIN
  private List<GatewayListener> listeners = new ArrayList<GatewayListener>();
  private volatile GatewayListener[] listenersArray = new GatewayListener[0];
  //#DOTNET_EXCLUDE_END
 
  private static Logger myLogger = Logger.getMyLogger(DynamicJadeGateway.class.getName());
 
 
  /** Searches for the property with the specified key in the JADE Platform Profile.
   *  The method returns the default value argument if the property is not found.
   * @param key - the property key.
   * @param defaultValue - a default value
   * @return the value with the specified key value
   * @see java.util.Properties#getProperty(String, String)
   **/
  public final String getProfileProperty(String key, String defaultValue) {
    return profile.getParameter(key, defaultValue);
  }
 
  /**
   * execute a command.
   * This method first check if the executor Agent is alive (if not it
   * creates container and agent), then it forwards the execution
   * request to the agent, finally it blocks waiting until the command
   * has been executed (i.e. the method <code>releaseCommand</code>
   * is called by the executor agent)
   * @throws StaleProxyException if the method was not able to execute the Command
   * @see jade.wrapper.AgentController#putO2AObject(Object, boolean)
   **/
  public final void execute(Object command) throws StaleProxyException,ControllerException,InterruptedException {
    execute(command, 0);
  }
 
  /**
   * Execute a command specifying a timeout.
   * This method first check if the executor Agent is alive (if not it
   * creates container and agent), then it forwards the execution
   * request to the agent, finally it blocks waiting until the command
   * has been executed. In case the command is a behaviour this method blocks
   * until the behaviour has been completely executed.
   * @throws InterruptedException if the timeout expires or the Thread
   * executing this method is interrupted.
   * @throws StaleProxyException if the method was not able to execute the Command
   * @see jade.wrapper.AgentController#putO2AObject(Object, boolean)
   **/
  public final void execute(Object command, long timeout) throws StaleProxyException,ControllerException,InterruptedException {
    Event e = null;
    synchronized (this) {
      checkJADE();
      // incapsulate the command into an Event
      e = new Event(-1, command);
      try {
        if (myLogger.isLoggable(Logger.INFO))
          myLogger.log(Logger.INFO, "Requesting execution of command "+command);
        myAgent.putO2AObject(e, AgentController.ASYNC);
      } catch (StaleProxyException exc) {
        exc.printStackTrace();
        // in case an exception was thrown, restart JADE
        // and then reexecute the command
        restartJADE();
        myAgent.putO2AObject(e, AgentController.ASYNC);
      }
    }
    // wait until the answer is ready
    e.waitUntilProcessed(timeout);
  }
 
  /**
   * This method checks if both the container, and the agent, are up and running.
   * If not, then the method is responsible for renewing myContainer.
   * Normally programmers do not need to invoke this method explicitly.
   **/
  public final void checkJADE() throws StaleProxyException,ControllerException {
    if (myContainer == null || !myContainer.isJoined()) {
      initProfile();
     
      myContainer = Runtime.instance().createAgentContainer(profile);
      if (myContainer == null) {
        throw new ControllerException("JADE startup failed.");
      }
    }
    if (myAgent == null) {
      try {
        Agent a = (Agent) Class.forName(agentType).newInstance();
        if (a instanceof GatewayAgent) {
          //#DOTNET_EXCLUDE_BEGIN
          ((GatewayAgent) a).setListener(new GatewayListenerImpl());
          //#DOTNET_EXCLUDE_END
         
          // We are able to detect the GatewayAgent state only if the internal agent is a GatewayAgent instance
          gatewayAgentState = NOT_ACTIVE;
        }
        a.setArguments(agentArguments);
        myAgent = myContainer.acceptNewAgent("Control"+myContainer.getContainerName(), a);
       
        if (gatewayAgentState == NOT_ACTIVE) {
          // Set the ACTIVE state synchronously so that when checkJADE() completes isGatewayActive() certainly returns true
          gatewayAgentState = ACTIVE;
        }
        myAgent.start();
      }
      catch (StaleProxyException spe) {
        // Just let it through
        throw spe;
      }
      catch (Exception e) {
        throw new ControllerException("Error creating GatewayAgent [" + e + "]");
      }
    }
  }
 
  /** Restart JADE.
   * The method tries to kill both the agent and the container,
   * then it puts to null the values of their controllers,
   * and finally calls checkJADE
   **/
  final void restartJADE() throws StaleProxyException,ControllerException {
    shutdown();
    checkJADE();
  }
 
  /**
   * Initialize this gateway by passing the proper configuration parameters
   * @param agentClassName is the fully-qualified class name of the JadeGateway internal agent. If null is passed
   * the default class will be used.
   * @param agentArgs is the list of agent arguments
   * @param jadeProfile the properties that contain all parameters for running JADE (see jade.core.Profile).
   * Typically these properties will have to be read from a JADE configuration file.
   * If jadeProfile is null, then a JADE container attaching to a main on the local host is launched
   **/
  public final void init(String agentClassName, Object[] agentArgs, Properties jadeProfile) {
    if (agentClassName != null) {
      agentType = agentClassName;
    } else {
      agentType = GatewayAgent.class.getName();
    }
   
    jadeProps = jadeProfile;
    if (jadeProps != null) {
      // Since we will create a non-main container --> force the "main" property to be false
      jadeProps.setProperty(Profile.MAIN, "false");
    }
   
    agentArguments = agentArgs;
  }

  public final void init(String agentClassName, Properties jadeProfile) {
    init(agentClassName, null, jadeProfile);
  }
 
  final void initProfile() {
    // to initialize the profile every restart, otherwise an exception would be thrown by JADE
    profile = (jadeProps == null ? new ProfileImpl(false) : new ProfileImpl(jadeProps));
  }
 
  /**
   * Kill the JADE Container in case it is running.
   */
  public final void shutdown() {
    try { // try to kill, but neglect any exception thrown
      if (myAgent != null)
        myAgent.kill();
    } catch (Exception e) {
    }
    try { // try to kill, but neglect any exception thrown
      if (myContainer != null)
        myContainer.kill();
    } catch (Exception e) {
    }
    myAgent = null;
    myContainer = null;
  }
 
  /**
   * Return the state of JadeGateway
   * @return true if the container and the gateway agent are active, false otherwise
   */
  public final boolean isGatewayActive() {
    if (gatewayAgentState != UNKNOWN) {
      return gatewayAgentState == ACTIVE;
    }
    else {
      // If we are not able to monitor the actual gatewayAgentState, just check if myContainer and myAgent are not null
      return myContainer != null && myAgent != null;
    }
  }
 
  public AID createAID(String localName) {
    return new AID(localName+'@'+myContainer.getPlatformName(), AID.ISGUID);
  }
 
  //#DOTNET_EXCLUDE_BEGIN
  public void addListener(GatewayListener l) {
    listeners.add(l);
    listenersArray = listeners.toArray(new GatewayListener[0]);
  }
 
  public void removeListener(GatewayListener l) {
    if (listeners.remove(l)) {
      listenersArray = listeners.toArray(new GatewayListener[0]);
    }
  }
 
  /**
   * Inner class GatewayListenerImpl
   */
  private class GatewayListenerImpl implements GatewayListener {
    public void handleGatewayConnected() {
      // This is executed by the GatewayAgent Thread --> Notify listeners by means of an ad-hoc
      // Thread to avoid deadlocks with other threads waiting for the execute() method to complete
      Thread t = new Thread() {
        public void run() {
          for (GatewayListener listener : listenersArray) {
            try {
              listener.handleGatewayConnected();
            }
            catch (Exception e) {
              e.printStackTrace();
            }
          }
        }
      };
      t.start();
    }
   
    public void handleGatewayDisconnected() {
      gatewayAgentState = NOT_ACTIVE;
      myAgent = null;
     
      // This is executed by the GatewayAgent Thread --> Notify listeners by means of an ad-hoc
      // Thread to avoid deadlocks with other threads waiting for the execute() method to complete
      Thread t = new Thread() {
        public void run() {
          for (GatewayListener listener : listenersArray) {
            try {
              listener.handleGatewayDisconnected();
            }
            catch (Exception e) {
              e.printStackTrace();
            }
          }
        }
      };
      t.start();
    }
  } // END of inner class GatewayListenerImpl
  //#DOTNET_EXCLUDE_END
}
TOP

Related Classes of jade.wrapper.gateway.DynamicJadeGateway

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.