Skip Navigation Links
Exit Print View
| Oracle Solaris Cluster Data Services Developer's Guide Oracle Solaris Cluster 4.1

Search Scope:

- This Document
- Entire Library

## Contents of `CrnpClient.java`

    /*
     * CrnpClient.java
     * ================
     *
     * Note regarding XML parsing:
     *
     * This program uses the Sun Java Architecture for XML Processing (JAXP) API.
     * See http://java.sun.com/webservices/jaxp/ for API documentation and
     * availability information.
     *
     * This program was written for Java 1.3.1 or higher.
     *
     * Program overview:
     *
     * The main thread of the program creates a CrnpClient object, waits for the
     * user to terminate the demo, then calls shutdown on the CrnpClient object
     * and exits the program.
     *
     * The CrnpClient constructor creates an EventReceptionThread object,
     * opens a connection to the CRNP server (using the host and port specified
     * on the command line), constructs a registration message (based on the
     * command-line specifications), sends the registartion message, and reads
     * and parses the reply.
     *
     * The EventReceptionThread creates a listening socket bound to
     * the hostname of the machine on which this program runs, and the port
     * specified on the command line. It waits for an incoming event callback,
     * at which point it constructs an XML Document from the incoming socket
     * stream, which is then passed back to the CrnpClient object to process.
     *
     * The shutdown method in the CrnpClient just sends an unregistration
     * (REMOVE_CLIENT) SC_CALLBACK_REG message to the crnp server.
     *
     * Note regarding error handling: for the sake of brevity, this program just
     * exits on most errors.  Obviously, a real application would attempt to handle
     * some errors in various ways, such as retrying when appropriate.
     */

    // JAXP packages
    import javax.xml.parsers.*;
    import javax.xml.transform.*;
    import javax.xml.transform.dom.*;
    import javax.xml.transform.stream.*;
    import org.xml.sax.*;
    import org.xml.sax.helpers.*;
    import org.w3c.dom.*;

    // standard packages
    import java.net.*;
    import java.io.*;
    import java.util.*;

    /*
     * class CrnpClient
     * -----------------
     * See file header comments above.
     */
    class CrnpClient
    {
     /*
      * main
      * ----
      * The entry point of the execution, main simply verifies the
      * number of command-line arguments, and constructs an instance
      * of a CrnpClient to do all the work.
      */
     public static void main(String []args)
     {
       InetAddress regIp = null;
       int regPort = 0, localPort = 0;

       /* Verify the number of command-line arguments */
       if (args.length < 4) {
          System.out.println(
             "Usage: java CrnpClient crnpHost crnpPort "
             + "localPort (-ac | -ae | -re) "
             + "[(M | A | RG=name | R=name) [...]]");
          System.exit(1);
       }

       /*
        * We expect the command line to contain the ip/port of the
        * crnp server, the local port on which we should listen, and
        * arguments specifying the type of registration.
        */
       try {
          regIp = InetAddress.getByName(args[0]);
          regPort = (new Integer(args[1])).intValue();
          localPort = (new Integer(args[2])).intValue();
       } catch (UnknownHostException e) {
          System.out.println(e);
          System.exit(1);
       }

       // Create the CrnpClient
       CrnpClient client = new CrnpClient(regIp, regPort, localPort,
          args);

       // Now wait until the user wants to end the program
       System.out.println("Hit return to terminate demo...");

       // read will block until the user enters something
       try {
          System.in.read();
       } catch (IOException e) {
          System.out.println(e.toString());
       }

       // shutdown the client
       client.shutdown();
       System.exit(0);
    }

    /*
     * ======================
     * public methods
     * ======================
     */

     /*
      * CrnpClient constructor
      * -----------------------
      * Parses the command line arguments so we know how to contact
      * the crnp server, creates the event reception thread, and starts it
      * running, creates the XML DocumentBuilderFactory obect, and, finally,
      * registers for callbacks with the crnp server.
      */
     public CrnpClient(InetAddress regIpIn, int regPortIn, int localPortIn,
          String []clArgs)
    {
       try {

       regIp = regIpIn;
          regPort = regPortIn;
          localPort = localPortIn;
          regs = clArgs;

         /*
          * Setup the document builder factory for
          * xml processing.
          */
          setupXmlProcessing();

         /*
          * Create the EventReceptionThread, which creates a
          * ServerSocket and binds it to a local ip and port.
          */
          createEvtRecepThr();

         /*
          * Register with the crnp server.
          */
          registerCallbacks();

        } catch (Exception e) {
          System.out.println(e.toString());
          System.exit(1);
        }
     }

    /*
     * processEvent
     * ---------------
     * Callback into the CrnpClient, used by the EventReceptionThread
     * when it receives event callbacks.
     */
     public void processEvent(Event event)
     {
      /*
       * For demonstration purposes, simply print the event
       * to System.out.  A real application would obviously make
       * use of the event in some way.
       */
      event.print(System.out);
     }

     /*
      * shutdown
      * -------------
      * Unregister from the CRNP server.
      */
     public void shutdown()
     {
      try {
       /* send an unregistration message to the server */
       unregister();
      } catch (Exception e) {
       System.out.println(e);
       System.exit(1);
      }
     }

     /*
      * ======================
      * private helper methods
      * ======================
      */

     /*
      * setupXmlProcessing
      * --------------------
      * Create the document builder factory for
      * parsing the xml replies and events.
      */
     private void setupXmlProcessing() throws Exception
     {
      dbf = DocumentBuilderFactory.newInstance();

      // We don't need to bother validating
      dbf.setValidating(false);
      dbf.setExpandEntityReferences(false);

      // We want to ignore comments and whitespace
      dbf.setIgnoringComments(true);
      dbf.setIgnoringElementContentWhitespace(true);

      // Coalesce CDATA sections into TEXT nodes.
      dbf.setCoalescing(true);
     }

     /*
      * createEvtRecepThr
      * -------------------
      * Creates a new EventReceptionThread object, saves the ip
      * and port to which its listening socket is bound, and
      * starts the thread running.
      */
     private void createEvtRecepThr() throws Exception
     {
      /* create the thread object */
      evtThr = new EventReceptionThread(this);

      /*
       * Now start the thread running to begin listening
       * for event delivery callbacks.
       */
      evtThr.start();
     }

     /*
      * registerCallbacks
      * ------------------
      * Creates a socket connection to the crnp server and sends
      * an event registration message.
      */
     private void registerCallbacks() throws Exception
     {
      System.out.println("About to register");

      /*
       * Create a socket connected to the registration ip/port
       * of the crnp server and send the registration information.
       */
      Socket sock = new Socket(regIp, regPort);
      String xmlStr = createRegistrationString();
      PrintStream ps = new PrintStream(sock.getOutputStream());
      ps.print(xmlStr);

      /*
       * Read the reply
       */
      readRegistrationReply(sock.getInputStream());

      /*
       * Close the socket connection.
       */
      sock.close();
     }

     /*
      * unregister
      * ----------
      * As in registerCallbacks, we create a socket connection to
      * the crnp server, send the unregistration message, wait for
      * the reply from the server, then close the socket.
      */
     private void unregister() throws Exception
     {
      System.out.println("About to unregister");

      /*
       * Create a socket connected to the registration ip/port
       * of the crnp server and send the unregistration information.
       */
      Socket sock = new Socket(regIp, regPort);
      String xmlStr = createUnregistrationString();
      PrintStream ps = new PrintStream(sock.getOutputStream());
      ps.print(xmlStr);

      /*
       * Read the reply
       */
      readRegistrationReply(sock.getInputStream());

      /*
       * Close the socket connection.
       */
      sock.close();
     }

     /*
      * createRegistrationString
      * ------------------
      * Constructs a CallbackReg object based on the command line arguments
      * to this program, then retrieves the XML string from the CallbackReg
      * object.
      */
     private String createRegistrationString() throws Exception
     {
      /*
       * create the actual CallbackReg class and set the port.
       */
      CallbackReg cbReg = new CallbackReg();
      cbReg.setPort("" + localPort);

      // set the registration type
      if (regs[3].equals("-ac")) {
       cbReg.setRegType(CallbackReg.ADD_CLIENT);
      } else if (regs[3].equals("-ae")) {
       cbReg.setRegType(CallbackReg.ADD_EVENTS);
      } else if (regs[3].equals("-re")) {
       cbReg.setRegType(CallbackReg.REMOVE_EVENTS);
      } else {
       System.out.println("Invalid reg type: " + regs[3]);
       System.exit(1);
      }

      // add the events
      for (int i = 4; i < regs.length; i++) {
       if (regs[i].equals("M")) {
        cbReg.addRegEvent(createMembershipEvent());
       } else if (regs[i].equals("A")) {
        cbReg.addRegEvent(createAllEvent());
       } else if (regs[i].substring(0,2).equals("RG")) {
        cbReg.addRegEvent(createRgEvent(regs[i].substring(3)));
       } else if (regs[i].substring(0,1).equals("R")) {
        cbReg.addRegEvent(createREvent(regs[i].substring(2)));
       }
      }

      String xmlStr = cbReg.convertToXml();
      System.out.println(xmlStr);
      return (xmlStr);
     }

     /*
      * createAllEvent
      * ----------------
      * Creates an XML registartion event with class EC_Cluster, and no
      * subclass.
      */
     private Event createAllEvent()
     {
      Event allEvent = new Event();
      allEvent.setClass("EC_Cluster");
      return (allEvent);
     }

     /*
      * createMembershipEvent
      * ----------------------
      * Creates an XML registration event with class EC_Cluster, subclass
      * ESC_cluster_memberhip.
      */
     private Event createMembershipEvent()
     {
      Event membershipEvent = new Event();
      membershipEvent.setClass("EC_Cluster");
      membershipEvent.setSubclass("ESC_cluster_membership");
      return (membershipEvent);
     }

     /*
      * createRgEvent
      * ----------------
      * Creates an XML registration event with class EC_Cluster,
      * subclass ESC_cluster_rg_state, and one "rg_name" nvpair (based
      * on input parameter).
      */
     private Event createRgEvent(String rgname)
     {
      /*
       * Create a Resource Group state change event for the
       * rgname Resource Group.  Note that we supply
       * a name/value pair (nvpair) for this event type, to
       * specify in which Resource Group we are interested.
       */
      /*
       * Construct the event object and set the class and subclass.
       */
      Event rgStateEvent = new Event();
      rgStateEvent.setClass("EC_Cluster");
      rgStateEvent.setSubclass("ESC_cluster_rg_state");

      /*
       * Create the nvpair object and add it to the Event.
       */
      NVPair rgNvpair = new NVPair();
      rgNvpair.setName("rg_name");
      rgNvpair.setValue(rgname);
      rgStateEvent.addNvpair(rgNvpair);

      return (rgStateEvent);
     }

     /*
      * createREvent
      * ----------------
      * Creates an XML registration event with class EC_Cluster,
      * subclass ESC_cluster_r_state, and one "r_name" nvpair (based
      * on input parameter).
      */
     private Event createREvent(String rname)
     {
      /*
       * Create a Resource state change event for the
       * rgname Resource.  Note that we supply
       * a name/value pair (nvpair) for this event type, to
       * specify in which Resource Group we are interested.
       */
      Event rStateEvent = new Event();
      rStateEvent.setClass("EC_Cluster");
      rStateEvent.setSubclass("ESC_cluster_r_state");

      NVPair rNvpair = new NVPair();
      rNvpair.setName("r_name");
      rNvpair.setValue(rname);
      rStateEvent.addNvpair(rNvpair);

      return (rStateEvent);
     }

     /*
      * createUnregistrationString
      * ------------------
      * Constructs a REMOVE_CLIENT CallbackReg object, then retrieves
      * the XML string from the CallbackReg object.
      */
     private String createUnregistrationString() throws Exception
     {
      /*
       * Crate the CallbackReg object.
       */
      CallbackReg cbReg = new CallbackReg();
      cbReg.setPort("" + localPort);
      cbReg.setRegType(CallbackReg.REMOVE_CLIENT);

      /*
       * we marshall the registration to the OutputStream
       */
      String xmlStr = cbReg.convertToXml();

      // Print the string for debugging purposes
      System.out.println(xmlStr);
      return (xmlStr);
     }

     /*
      * readRegistrationReply
      * ------------------------
      * Parse the xml into a Document, construct a RegReply object
      * from the document, and print the RegReply object.  Note that
      * a real application would take action based on the status_code
      * of the RegReply object.
      */
     private void readRegistrationReply(InputStream stream)
         throws Exception
     {
      // Create the document builder
      DocumentBuilder db = dbf.newDocumentBuilder();

      //
      // Set an ErrorHandler before parsing
      // Use the default handler.
      //
      db.setErrorHandler(new DefaultHandler());

      //parse the input file
      Document doc = db.parse(stream);

      RegReply reply = new RegReply(doc);
      reply.print(System.out);
     }

     /* private member variables */
     private InetAddress regIp;
     private int regPort;
     private EventReceptionThread evtThr;
     private String regs[];

     /* public member variables */
     public int localPort;
     public DocumentBuilderFactory dbf;
    }

    /*
     * class EventReceptionThread
     * ----------------------------
     * See file header comments above.
     */
    class EventReceptionThread extends Thread
    {
     /*
      * EventReceptionThread constructor
      * ----------------------------------
      * Creates a new ServerSocket, bound to the local hostname and
      * a wildcard port.
      */
     public EventReceptionThread(CrnpClient clientIn) throws IOException
     {
      /*
       * keep a reference to the client so we can call it back
       * when we get an event.
       */
      client = clientIn;

      /*
       * Specify the IP to which we should bind.  It's
       * simply the local host ip.  If there is more
       * than one public interface configured on this
       * machine, we'll go with whichever one
       * InetAddress.getLocalHost comes up with.
       *
       */
      listeningSock = new ServerSocket(client.localPort, 50,
          InetAddress.getLocalHost());
          System.out.println(listeningSock);
     }

     /*
      * run
      * ---
      * Called by the Thread.Start method.
      *
      * Loops forever, waiting for incoming connections on the ServerSocket.
      *
      * As each incoming connection is accepted, an Event object
      * is created from the xml stream, which is then passed back to
      * the CrnpClient object for processing.
      */
     public void run()
     {
      /*
       * Loop forever.
       */
      try {
       //
       // Create the document builder using the document
       // builder factory in the CrnpClient.
       //
       DocumentBuilder db = client.dbf.newDocumentBuilder();

       //
       // Set an ErrorHandler before parsing
       // Use the default handler.
       //
       db.setErrorHandler(new DefaultHandler());

       while(true) {
        /* wait for a callback from the server */
        Socket sock = listeningSock.accept();

        // parse the input file
        Document doc = db.parse(sock.getInputStream());

        Event event = new Event(doc);
        client.processEvent(event);

        /* close the socket */
        sock.close();
       }
       // UNREACHABLE

      } catch (Exception e) {
       System.out.println(e);
       System.exit(1);
      }
     }

     /* private member variables */
     private ServerSocket listeningSock;
     private CrnpClient client;
    }

    /*
     * class NVPair
     * -----------
     * This class stores a name/value pair (both Strings).  It knows how to
     * construct an NVPAIR XML message from its members, and how to parse
     * an NVPAIR XML Element into its members.
     *
     * Note that the formal specification of an NVPAIR allows for multiple values.
     * We make the simplifying assumption of only one value.
     */
    class NVPair
    {
     /*
      * Two constructors: the first creates an empty NVPair, the second
      * creates an NVPair from an NVPAIR XML Element.
      */
     public NVPair()
     {
      name = value = null;
     }

     public NVPair(Element elem)
     {
      retrieveValues(elem);
     }

     /*
      * Public setters.
      */
     public void setName(String nameIn)
     {
      name = nameIn;
     }

     public void setValue(String valueIn)
     {
      value = valueIn;
     }

     /*
      * Prints the name and value on a single line.
      */
     public void print(PrintStream out)
     {
      out.println("NAME=" + name + " VALUE=" + value);
     }

     /*
      * createXmlElement
      * ------------------
      * Constructs an NVPAIR XML Element from the member variables.
      * Takes the Document as a parameter so that it can create the
      * Element.
      */
     public Element createXmlElement(Document doc)
     {
      // Create the element.
      Element nvpair = (Element)
          doc.createElement("NVPAIR");
      //
      // Add the name.  Note that the actual name is
      // a separate CDATA section.
      //
      Element eName = doc.createElement("NAME");
      Node nameData = doc.createCDATASection(name);
      eName.appendChild(nameData);
      nvpair.appendChild(eName);
      //
      // Add the value.  Note that the actual value is
      // a separate CDATA section.
      //
      Element eValue = doc.createElement("VALUE");
      Node valueData = doc.createCDATASection(value);
      eValue.appendChild(valueData);
      nvpair.appendChild(eValue);

      return (nvpair);
     }

     /*
      * retrieveValues
      * ----------------
      * Parse the XML Element to retrieve the name and value.
      */
     private void retrieveValues(Element elem)
     {
      Node n;
      NodeList nl;

      //
      // Find the NAME element
      //
      nl = elem.getElementsByTagName("NAME");
      if (nl.getLength() != 1) {
       System.out.println("Error in parsing: can't find "
           + "NAME node.");
       return;
      }

      //
      // Get the TEXT section
      //
      n = nl.item(0).getFirstChild();
      if (n == null || n.getNodeType() != Node.TEXT_NODE) {
       System.out.println("Error in parsing: can't find "
           + "TEXT section.");
       return;
      }

      // Retrieve the value
      name = n.getNodeValue();

      //
      // Now get the value element
      //
      nl = elem.getElementsByTagName("VALUE");
      if (nl.getLength() != 1) {
       System.out.println("Error in parsing: can't find "
           + "VALUE node.");
       return;
      }

      //
      // Get the TEXT section
      //
      n = nl.item(0).getFirstChild();
      if (n == null || n.getNodeType() != Node.TEXT_NODE) {
       System.out.println("Error in parsing: can't find "
           + "TEXT section.");
       return;
      }

      // Retrieve the value
      value = n.getNodeValue();
     }

     /*
      * Public accessors
      */
     public String getName()
     {
      return (name);
     }

     public String getValue()
     {
      return (value);
     }

     // Private member vars
     private String name, value;
    }

    /*
     * class Event
     * -----------
     * This class stores an event, which consists of a class, subclass, vendor,
     * publisher, and list of name/value pairs.  It knows how to
     * construct an SC_EVENT_REG XML Element from its members, and how to parse
     * an SC_EVENT XML Element into its members.  Note that there is an assymetry
     * here: we parse SC_EVENT elements, but construct SC_EVENT_REG elements.
     * That is because SC_EVENT_REG elements are used in registration messages
     * (which we must construct), while SC_EVENT elements are used in event
     * deliveries (which we must parse).  The only difference is that SC_EVENT_REG
     * elements don't have a vendor or publisher.
     */
    class Event
    {

     /*
      * Two constructors: the first creates an empty Event; the second
      * creates an Event from an SC_EVENT XML Document.
      */
     public Event()
     {
      regClass = regSubclass = null;
      nvpairs = new Vector();
     }

     public Event(Document doc)
     {

      nvpairs = new Vector();

      //
      // Convert the document to a string to print for debugging
      // purposes.
      //
      DOMSource domSource = new DOMSource(doc);
      StringWriter strWrite = new StringWriter();
      StreamResult streamResult = new StreamResult(strWrite);
      TransformerFactory tf = TransformerFactory.newInstance();
      try {
       Transformer transformer = tf.newTransformer();
       transformer.transform(domSource, streamResult);
      } catch (TransformerException e) {
       System.out.println(e.toString());
       return;
      }
      System.out.println(strWrite.toString());

      // Do the actual parsing.
      retrieveValues(doc);
     }

     /*
      * Public setters.
      */
     public void setClass(String classIn)
     {
      regClass = classIn;
     }

     public void setSubclass(String subclassIn)
     {
      regSubclass = subclassIn;
     }

     public void addNvpair(NVPair nvpair)
     {
      nvpairs.add(nvpair);
     }

     /*
      * createXmlElement
      * ------------------
      * Constructs an SC_EVENT_REG XML Element from the member variables.
      * Takes the Document as a parameter so that it can create the
      * Element.  Relies on the NVPair createXmlElement ability.
      */
     public Element createXmlElement(Document doc)
     {
      Element event = (Element)
          doc.createElement("SC_EVENT_REG");
      event.setAttribute("CLASS", regClass);
      if (regSubclass != null) {
       event.setAttribute("SUBCLASS", regSubclass);
      }
      for (int i = 0; i < nvpairs.size(); i++) {
       NVPair tempNv = (NVPair)
           (nvpairs.elementAt(i));
       event.appendChild(tempNv.createXmlElement(doc));
      }
      return (event);
     }

     /*
      * Prints the member vars on multiple lines.
      */
     public void print(PrintStream out)
     {
      out.println("\tCLASS=" + regClass);
      out.println("\tSUBCLASS=" + regSubclass);
      out.println("\tVENDOR=" + vendor);
      out.println("\tPUBLISHER=" + publisher);
      for (int i = 0; i < nvpairs.size(); i++) {
       NVPair tempNv = (NVPair)
           (nvpairs.elementAt(i));
       out.print("\t\t");
       tempNv.print(out);
      }
     }

      /*
      * retrieveValues
      * ----------------
      * Parse the XML Document to retrieve the class, subclass, vendor,
      * publisher, and nvpairs.
      */
     private void retrieveValues(Document doc)
     {
      Node n;
      NodeList nl;

      //
      // Find the SC_EVENT element.
      //
      nl = doc.getElementsByTagName("SC_EVENT");
      if (nl.getLength() != 1) {
       System.out.println("Error in parsing: can't find "
           + "SC_EVENT node.");
       return;
      }

      n = nl.item(0);

      //
      // Retrieve the values of the CLASS, SUBCLASS,
      // VENDOR and PUBLISHER attributes.
      //
      regClass = ((Element)n).getAttribute("CLASS");
      regSubclass = ((Element)n).getAttribute("SUBCLASS");
      publisher = ((Element)n).getAttribute("PUBLISHER");
      vendor = ((Element)n).getAttribute("VENDOR");

      //
      // Retrieve all the nv pairs
      //
      for (Node child = n.getFirstChild(); child != null;
           child = child.getNextSibling())
      {
       nvpairs.add(new NVPair((Element)child));
      }
     }

     /*
      * Public accessor methods.
      */
     public String getRegClass()
     {
      return (regClass);
     }

     public String getSubclass()
     {
      return (regSubclass);
     }

     public String getVendor()
     {
      return (vendor);
     }

     public String getPublisher()
     {
      return (publisher);
     }

     public Vector getNvpairs()
     {
      return (nvpairs);
     }

     // Private member vars.
     private String regClass, regSubclass;
     private Vector nvpairs;
     private String vendor, publisher;
    }

    /*
     * class CallbackReg
     * -----------
     * This class stores a port and regType (both Strings), and a list of Events.
     * It knows how to construct an SC_CALLBACK_REG XML message from its members.
     *
     * Note that this class does not need to be able to parse SC_CALLBACK_REG
     * messages, because only the CRNP server must parse SC_CALLBACK_REG
     * messages.
     */
    class CallbackReg
    {
     // Useful defines for the setRegType method
     public static final int ADD_CLIENT = 0;
     public static final int ADD_EVENTS = 1;
     public static final int REMOVE_EVENTS = 2;
     public static final int REMOVE_CLIENT = 3;

     public CallbackReg()
     {
      port = null;
      regType = null;
      regEvents = new Vector();
     }

     /*
      * Public setters.
      */
     public void setPort(String portIn)
     {
      port = portIn;
     }

     public void setRegType(int regTypeIn)
     {
      switch (regTypeIn) {
      case ADD_CLIENT:
       regType = "ADD_CLIENT";
       break;
      case ADD_EVENTS:
       regType = "ADD_EVENTS";
       break;
      case REMOVE_CLIENT:
       regType = "REMOVE_CLIENT";
       break;
      case REMOVE_EVENTS:
       regType = "REMOVE_EVENTS";
       break;
      default:
       System.out.println("Error, invalid regType " +
           regTypeIn);
       regType = "ADD_CLIENT";
       break;
      }
     }

     public void addRegEvent(Event regEvent)
     {
      regEvents.add(regEvent);
     }

     /*
      * convertToXml
      * ------------------
      * Constructs an SC_CALLBACK_REG XML Document from the member
      * variables.  Relies on the Event createXmlElement ability.
      */
     public String convertToXml()
     {
      Document document = null;
      DocumentBuilderFactory factory =
          DocumentBuilderFactory.newInstance();
      try {
       DocumentBuilder builder = factory.newDocumentBuilder();
       document = builder.newDocument();
      } catch (ParserConfigurationException pce) {
       // Parser with specified options can't be built
       pce.printStackTrace();
       System.exit(1);
      }
      Element root = (Element) document.createElement("SC_CALLBACK_REG");
      root.setAttribute("VERSION", "1.0");
      root.setAttribute("PORT", port);
      root.setAttribute("REG_TYPE", regType);
      for (int i = 0; i < regEvents.size(); i++) {
       Event tempEvent = (Event)
           (regEvents.elementAt(i));
       root.appendChild(tempEvent.createXmlElement(document));
      }
      document.appendChild(root);

      //
      // Now convert the document to a string.
      //
      DOMSource domSource = new DOMSource(document);
      StringWriter strWrite = new StringWriter();
      StreamResult streamResult = new StreamResult(strWrite);
      TransformerFactory tf = TransformerFactory.newInstance();
      try {
       Transformer transformer = tf.newTransformer();
       transformer.transform(domSource, streamResult);
      } catch (TransformerException e) {
       System.out.println(e.toString());
       return ("");
      }
      return (strWrite.toString());
     }

     // private member vars
     private String port;
     private String regType;
     private Vector regEvents;
    }

    /*
     * class RegReply
     * -----------
     * This class stores a status_code and status_msg (both Strings).
     * It knows how to parse an SC_REPLY XML Element into its members.
     */
    class RegReply
    {

     /*
      * The only constructor takes an XML Document and parses it.
      */
     public RegReply(Document doc)
     {
      //
      // Now convert the document to a string.
      //
      DOMSource domSource = new DOMSource(doc);
      StringWriter strWrite = new StringWriter();
      StreamResult streamResult = new StreamResult(strWrite);
      TransformerFactory tf = TransformerFactory.newInstance();
      try {
       Transformer transformer = tf.newTransformer();
       transformer.transform(domSource, streamResult);
      } catch (TransformerException e) {
       System.out.println(e.toString());
       return;
      }
      System.out.println(strWrite.toString());

      retrieveValues(doc);
     }

     /*
      * Public accessors
      */
     public String getStatusCode()
     {
      return (statusCode);
     }

     public String getStatusMsg()
     {
      return (statusMsg);
     }

     /*
      * Prints the info on a single line.
      */
     public void print(PrintStream out)
     {
      out.println(statusCode + ": " +
          (statusMsg != null ? statusMsg : ""));
     }

      /*
      * retrieveValues
      * ----------------
      * Parse the XML Document to retrieve the statusCode and statusMsg.
      */
     private void retrieveValues(Document doc)
     {
      Node n;
      NodeList nl;

      //
      // Find the SC_REPLY element.
      //
      nl = doc.getElementsByTagName("SC_REPLY");
      if (nl.getLength() != 1) {
       System.out.println("Error in parsing: can't find "
           + "SC_REPLY node.");
       return;
      }

      n = nl.item(0);

      // Retrieve the value of the STATUS_CODE attribute
      statusCode = ((Element)n).getAttribute("STATUS_CODE");

      //
      // Find the SC_STATUS_MSG element
      //
      nl = ((Element)n).getElementsByTagName("SC_STATUS_MSG");
      if (nl.getLength() != 1) {
       System.out.println("Error in parsing: can't find "
           + "SC_STATUS_MSG node.");
       return;
      }

      //
      // Get the TEXT section, if there is one.
      //
      n = nl.item(0).getFirstChild();
      if (n == null || n.getNodeType() != Node.TEXT_NODE) {
       // Not an error if there isn't one, so we
       // just silently return.
       return;
      }

      // Retrieve the value
      statusMsg = n.getNodeValue();
     }

     // private member vars
     private String statusCode;
     private String statusMsg;
    }

Copyright © 2000, 2012, Oracle and/or its affiliates. All rights reserved. Legal Notices |