package examples.workspace.monitor;

import java.net.*;
import java.util.*;
import java.sql.*;
import weblogic.common.*;
import weblogic.event.common.*;
import weblogic.event.actions.*;
import weblogic.event.evaluators.*;
import weblogic.workspace.common.*;

/**
 * This example demonstrates how to use the various types of workspace
 * monitors. SetMonitors and DestroyMonitors are used for a variety
 * of purposes, such as sending an event when a workspace value is
 * removed, mirroring a workspace value in another workspace,
 * restricting a workspace value to a given range, or altering a
 * workspace value from what the user specified. The XXXMonitor class,
 * also called here, shows how a Master Monitor is used, and the
 * RangeMonitor shows how you can check the range of a Workspace value
 * before it is set, and throw a MonitorException if it is out of range.
 * <p>
 * <p>
 *
 *<h3>To set up this example:</h3>
 *<ol>
 *<li>Set up your development shell as described in <a
 *href=../../../techstart/environment.html>Setting up your environment</a>.
 *<p>
 *<li>Compile this example by executing the following command in your development shell:
 *
 *<p>
 *<font face="Courier New"><b>$ javac -d %CLIENT_CLASSES% MonitorDemo.java</b></font>
 *<p>
 *<li>Start WebLogic Server in a separate shell.
 *<p>	
 *<p>
 *<li>Run this example by executing the following command in your development shell:
 *
 *<p>
 *
 *<font face="Courier New"><b>$ java examples.workspace.monitor.MonitorDemo  t3://<i>hostname:port</i></b></font>
 *<p>Where <i>hostname:port</i> is the host name and port number of your WebLogic Server.  
 *<p>
 *
 *<p>
 *<dl>
 * @author                    Copyright (c) 1997-2000 by BEA Systems, Inc.
 *                            All Rights Reserved.
 */
public class MonitorDemo implements ActionDef {
  
  private Object lock = new Object();

  /**
   * Starts the Monitor process. Supply the WebLogic Server URL as an
   * argument.
   */
  public static void main(String argv[]) throws Exception  {
    
    if (argv.length != 1) {
      System.out.println("Usage:   java examples.workspace.monitor.MonitorDemo URL");
      System.out.println("Example: java examples.workspace.monitor.MonitorDemo t3://localhost:7001");
      return;
    } 
    
    String host = argv[0];
    // Create a T3Client and let the system assign a Workspace ID
    T3Client t3 = new T3Client(host);
    MonitorDemo md = new MonitorDemo();
    
    // Connect to the Server
    t3.connect();

    // Create 2 ParamSets to be used with the pre- and post-
    // operations. Since we don't really need params, we'll leave
    // them empty.
    ParamSet initPS = new ParamSet();
    ParamSet callbackPS = new ParamSet();

    // Get the Workspace
    WorkspaceDef defaultWS = t3.services.workspace().getWorkspace();
    WorkspaceDef workspace = defaultWS;

    try {
      // DestructionMonitor sends an event when a Workspace value is
      // removed.  The "lock" is used to force the thread to wait
      // until the message notification arrives.
      System.out.println("====================\nDestruction Monitor\n");
      initPS.setParam("topic", "destroyTopic");
      Monitor destuctionMonitor = new Monitor("examples.workspace.monitor.DestructionMonitor", 
                                              initPS, callbackPS);
      
      Evaluate eval = new Evaluate("weblogic.event.evaluators.EvaluateTrue");
      Action action = new Action(md);
      
      EventRegistrationDef destroyReg = 
        t3.services.events().getEventRegistration("destroyTopic", eval, action);
      destroyReg.register();
      
      workspace.addMonitor("key1", destuctionMonitor);
      System.out.println("Storing value under key1");
      workspace.store("key1", "testValue");
      System.out.println("Removing key1 from workspace (expect message notification)");
      synchronized(md.lock) {
        workspace.remove("key1");
        md.lock.wait();
      }
      
      // MirrorMonitor uses a SetMonitor and a DestroyMonitor to to
      // mirror the state of a workspace value in another Workspace.
      System.out.println("\n====================\nMirror Monitor\n");
      
      initPS.setParam("mirror", "mirroredWorkspace");
      Monitor mirrorMonitor = new Monitor("examples.workspace.monitor.MirrorMonitor", 
                                          initPS, callbackPS);
      
      workspace.addMonitor("key2", mirrorMonitor);
      String mirrorVal = "mirror this";
      workspace.store("key2", mirrorVal);
      System.out.println("Set key2="+mirrorVal+", in default workspace");
      WorkspaceDef mirror = defaultWS.getWorkspace("mirroredWorkspace", WorkspaceDef.OPEN, 
                                                   WorkspaceDef.SCOPE_SERVER);
      String mirroredValue = (String) mirror.fetch("key2");
      System.out.println("Got key2="+mirrorVal+", in workspace "+mirror.getName());
      
      
      
      // RangeMonitor restricts values to the range 0-100.
      System.out.println("\n====================\nRange Monitor (accepts values in 0...100)\n");
      Monitor rangeMonitor = new Monitor("examples.workspace.monitor.RangeMonitor",
                                         initPS, callbackPS);
      
      workspace.addMonitor("key3", rangeMonitor);
      System.out.println("Setting Value within range 0...100");
      workspace.store("key3", new Integer(50));
      try { 
        System.out.println("Setting Value outside range 0...100");
        workspace.store("key3", new Integer(150));
      }
      catch (T3Exception ex) {
        System.out.println("Received Exception for out-of-range value");
      }
      
      // XXXMonitor is an example of a MasterMonitor, which has the
      // ability to alter the value being monitored.  This monitor
      // actually replaces the supplied value with "XXX".
      System.out.println("\n====================\nSet Monitor (scrambles value)\n");
      Monitor xxxMonitor = new Monitor("examples.workspace.monitor.XXXMonitor",
                                       initPS, callbackPS);
      xxxMonitor.setMaster(true);
      
      String val = "hello world";
      workspace.addMonitor("key4", xxxMonitor);
      workspace.store("key4", val);
      System.out.println("Set Value: "+val);
      val = (String) workspace.fetch("key4");
      System.out.println("Got Value: "+val);
    }
    catch (Exception e) {
      e.printStackTrace();
    }
    
    // Disconnect the client. Since the soft disconnect timeout is
    // NEVER, the WebLogic Server will preserve the session.
    t3.disconnect();
  }
  
  // This implements ActionDef, which this class must do in order to
  // submit an EventRegistration.
  public void setServices(T3ServicesDef services) {}
  
  public void registerInit(ParamSet ps) {}
  
  public void action(EventMessageDef message) {
    System.out.println("Message Received: " + message.getTopic());
    synchronized(lock) {
      lock.notify();
    }
  }
}


