CorbaSender.java

package gov.usgs.earthquake.eidsutil;

import com.isti.quakewatch.server.qw_feeder.QWFeeder;
import com.isti.quakewatch.server.qw_feeder.QWFeederHelper;

import org.omg.CORBA.ORB;
//import org.omg.CORBA.Object;
import org.omg.CORBA.ORBPackage.InvalidName;
import org.omg.PortableServer.POA;
import org.omg.PortableServer.POAHelper;
import org.omg.PortableServer.POAManager;
import org.omg.PortableServer.POAManagerPackage.AdapterInactive;

/**
 * A <code>CorbaSender</code> is essentially a client-side wrapper for the
 * <code>QWFeeder</code> IDL file specified by ISTI. This class is designed to
 * provide simplified CORBA interaction with a QWServer (EIDS) machine. All the
 * varied methods of sending messages are provided, however they are wrapped
 * into a single method, namely, <code>sendMessage</code>. See the method
 * documentation for details.
 *
 * @since 0.0.1
 * @author <a href="mailto:emartinez@usgs.gov">Eric Martinez</a>
 */
public class CorbaSender {

  // ---------------------------------------------------------------------------
  // Member Variables
  // ---------------------------------------------------------------------------

  /** This is the URL used to obtain the underlying QWFeeder object. */
  private String url = null;

  /**
   * This is the underlying <code>QWFeeder</code> used to send the messages to the
   * server. The interface specification can be found in the
   * <code>QWFeeder.idl</code> file from ISTI.
   */
  private QWFeeder feeder = null;

  private ORB orb = null;
  private POA poa = null;
  private POAManager poaManager = null;
  private org.omg.CORBA.Object object = null;

  // ---------------------------------------------------------------------------
  // Constructors
  // ---------------------------------------------------------------------------

  /**
   * Initializes the <code>CorbaSender</code> such that it is ready to send a
   * message to the specified <code>host</code> over the specified
   * <code>port</code>. This uses the <code>QWFeeder</code> idl specified by ISTI
   * as the underlying feeder. After instantiating a <code>CorbaSender</code>
   * through this constructor, the instance is 100% ready to use. One downside is
   * one cannot reuse that instance to send messages to another host; for such a
   * feature one must instantiate a new object.
   *
   * @param host The host machine (ip or cname) to which you want to send the
   *             messages using this <code>CorbaSender</code>.
   * @param port The port number to send messages to on the host.
   *
   * @throws InvalidName     If the RootPOA is not aware of the type of object we
   *                         request from it.
   * @throws AdapterInactive If the poaManager is not active.
   */
  public CorbaSender(String host, String port) throws InvalidName, AdapterInactive {

    // Create the corbaloc url
    url = "corbaloc:iiop:1.2@" + host + ":" + port + "/QWFeeder";

    // Initialize the ORB
    orb = ORB.init((new String[0]), null);

    // Get the Root POA
    poa = POAHelper.narrow(orb.resolve_initial_references("RootPOA"));

    // Activate the POAManager
    poaManager = poa.the_POAManager();
    poaManager.activate();

    // Get the generic object reference from the orb
    object = orb.string_to_object(url);

    // Narrow the generic object down to our a QWFeeder
    feeder = QWFeederHelper.narrow(object);

  } // END: constructor CorbaSender

  /** Cleanup */
  public void destroy() {
    try {
      feeder._release();
    } catch (Exception ex) {
      /* ignore */ }
    try {
      object._release();
    } catch (Exception ex) {
      /* ignore */ }
    try {
      orb.shutdown(true);
    } catch (Exception ex) {
      /* ignore */ }
    try {
      orb.destroy();
    } catch (Exception ex) {
      /* ignore */ }

    feeder = null;
    object = null;
    poaManager = null;
    poa = null;
    orb = null;
  }

  /**
   * Retrieve a QWFeeder object associated with this CorbaSender.
   *
   * First checks if the object is "non_existent", and if so re-narrows the
   * object.
   *
   * @return QWFeeder object, or null if unable to narrow.
   */
  protected QWFeeder getFeeder() {
    if (feeder != null) {
      try {
        if (feeder._non_existent()) {
          feeder = null;
          object = null;
        }
      } catch (org.omg.CORBA.OBJECT_NOT_EXIST e) {
        // feeder._non_existent throws the OBJECT_NOT_EXIST exception
        // instead of returning true...
        feeder = null;
        object = null;
      }
    }

    if (feeder == null) {
      // recreate the object, must string_to_object AND narrow
      object = orb.string_to_object(url);
      feeder = QWFeederHelper.narrow(object);
    }

    return feeder;
  }

  // ---------------------------------------------------------------------------
  // Static Methods
  // ---------------------------------------------------------------------------

  /* None at this time. */

  // ---------------------------------------------------------------------------
  // Public Methods
  // ---------------------------------------------------------------------------

  /**
   * Sends a data event message. If the event data does not begin with a
   * &ldquo;DataMessage&rdquo; XML element then the data will be surrounded with
   * one. The &ldquo;sendSourced...&rdquo; methods are preferred because the
   * feeder-source host name and message number are used for improved message
   * tracking.
   *
   * @param message The data event message string.
   * @return <code>true</code> after the message has been successfully stored and
   *         processed; <code>false</code> if an error occurred.
   */
  public boolean sendMessage(String message) {
    return getFeeder().sendMessage(message);
  }

  /**
   * Sends a data event message. If the event data does not begin with a
   * &ldquo;DataMessage&rdquo; XML element then the data will be surrounded with
   * one. The &ldquo;sendSourced...&rdquo; methods are preferred because the
   * feeder-source host name and message number are used for improved message
   * tracking.
   *
   * @param domain  The domain name to use.
   * @param type    The type name to use.
   * @param message The data event message string.
   *
   * @return <code>true</code> after the message has been successfully stored and
   *         processed; <code>false</code> if an error occurred.
   */
  public boolean sendMessage(String domain, String type, String message) {
    return getFeeder().sendDomainTypeMessage(domain, type, message);
  }

  /**
   * Sends a data event message. If the event data does not begin with a
   * &ldquo;DataMessage&rdquo; XML element then the data will be surrounded with
   * one. The &ldquo;sendSourced...&rdquo; methods are preferred because the
   * feeder-source host name and message number are used for improved message
   * tracking.
   *
   * @param domain  The domain name to use.
   * @param type    The type name to use.
   * @param name    The event name to use.
   * @param message The data event message string.
   *
   * @return <code>true</code> after the message has been successfully stored and
   *         processed; <code>false</code> if an error occurred.
   */
  public boolean sendMessage(String domain, String type, String name, String message) {
    return getFeeder().sendDomainTypeNameMessage(domain, type, name, message);
  }

  /**
   * Sends a data event message. If the event data does not begin with a
   * &ldquo;DataMessage&rdquo; XML element then the data will be surrounded with
   * one. The &ldquo;sendSourced...&rdquo; methods are preferred because the
   * feeder-source host name and message number are used for improved message
   * tracking.
   *
   * @param message            The data event message string.
   * @param feederSourceHost   The data-source host string for the message.
   * @param feederSrcHostMsgId the message-ID number from the data source
   *                           (positive value incremented after each message).
   *
   * @return <code>true</code> after the message has been successfully stored and
   *         processed; <code>false</code> if an error occurred.
   */
  public boolean sendMessage(String message, String feederSourceHost, long feederSrcHostMsgId) {
    return getFeeder().sendSourcedMsg(message, feederSourceHost, feederSrcHostMsgId);
  }

  /**
   * Sends a data event message. If the event data does not begin with a
   * &ldquo;DataMessage&rdquo; XML element then the data will be surrounded with
   * one. The &ldquo;sendSourced...&rdquo; methods are preferred because the
   * feeder-source host name and message number are used for improved message
   * tracking.
   *
   * @param domain             The domain name to use.
   * @param type               The type name to use.
   * @param message            The data event message string.
   * @param feederSourceHost   The data-source host string for the message.
   * @param feederSrcHostMsgId The message-ID number from the data source
   *                           (positive value incremented after each message).
   *
   * @return <code>true</code> after the message has been successfully stored and
   *         processed; <code>false</code> if an error occurred.
   */
  public boolean sendMessage(String domain, String type, String message, String feederSourceHost,
      long feederSrcHostMsgId) {
    return getFeeder().sendSourcedDomainTypeMsg(domain, type, message, feederSourceHost, feederSrcHostMsgId);
  }

  /**
   * Sends a data event message. If the event data does not begin with a
   * &ldquo;DataMessage&rdquo; XML element then the data will be surrounded with
   * one. The &ldquo;sendSourced...&rdquo; methods are preferred because the
   * feeder-source host name and message number are used for improved message
   * tracking.
   *
   * @param domain             The domain name to use.
   * @param type               The type name to use.
   * @param name               The event name to use.
   * @param message            The data event message string.
   * @param feederSourceHost   The data-source host string for the message.
   * @param feederSrcHostMsgId The message-ID number from the data source
   *                           (positive value incremented after each message).
   *
   * @return <code>true</code> after the message has been successfully stored and
   *         processed; <code>false</code> if an error occurred.
   */
  public boolean sendMessage(String domain, String type, String name, String message, String feederSourceHost,
      long feederSrcHostMsgId) {
    return getFeeder().sendSourcedDomainTypeNameMsg(domain, type, name, message, feederSourceHost, feederSrcHostMsgId);
  }

  // ---------------------------------------------------------------------------
  // Private Methods
  // ---------------------------------------------------------------------------

  /* None at this time. */

} // END: class CorbaSender