//[C] 2002 Sun Microsystems, Inc.--- 
 
import java.awt.Container; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.WindowAdapter; 
import java.awt.event.WindowEvent; 
import java.io.IOException; 
import java.io.Serializable; 
import java.rmi.Naming; 
import java.rmi.Remote; 
import java.rmi.RemoteException; 
import java.rmi.server.UnicastRemoteObject; 
import java.util.HashMap; 
 
import javax.swing.BoxLayout; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.JTextArea; 
import javax.swing.JTextField; 
 
public class RunRouterPattern { 
  public static void main(String[] arguments) { 
    System.out.println("Example for the Router pattern"); 
    System.out 
        .println("This code same will create a series of GUIs, and use"); 
    System.out 
        .println(" the Router pattern to map message notifications between"); 
    System.out 
        .println(" them. In this code example, the Router will send messages"); 
    System.out 
        .println(" between the GUI clients based on the following mapping:"); 
    System.out.println(); 
    System.out.println("\tGUI # 1:\tGUI #2\tGUI #3"); 
    System.out.println("\tGUI # 2:\tGUI #1\tGUI #4"); 
    System.out.println("\tGUI # 3:\tGUI #1\tGUI #4"); 
    System.out.println("\tGUI # 4:\tGUI #1\tGUI #2\tGUI #3\tGUI #4"); 
    System.out.println(); 
 
    System.out.println("Running the RMI compiler (rmic)"); 
    try { 
      Process p1 = Runtime.getRuntime().exec("rmic Router"); 
      Process p2 = Runtime.getRuntime().exec("rmic RouterClient"); 
      p1.waitFor(); 
      p2.waitFor(); 
    } catch (IOException exc) { 
      System.err 
          .println("Unable to run rmic utility. Exiting application."); 
      System.exit(1); 
    } catch (InterruptedException exc) { 
      System.err 
          .println("Threading problems encountered while using the rmic utility."); 
    } 
 
    System.out.println("Starting the rmiregistry"); 
    System.out.println(); 
    Process rmiProcess = null; 
    try { 
      rmiProcess = Runtime.getRuntime().exec("rmiregistry"); 
      Thread.sleep(15000); 
    } catch (IOException exc) { 
      System.err 
          .println("Unable to start the rmiregistry. Exiting application."); 
      System.exit(1); 
    } catch (InterruptedException exc) { 
      System.err 
          .println("Threading problems encountered when starting the rmiregistry."); 
    } 
 
    System.out.println("Creating the Router object"); 
    System.out.println(); 
    Router mainRouter = new Router(); 
 
    InputKey keyOne = new InputKey(); 
    InputKey keyTwo = new InputKey(); 
    InputKey keyThree = new InputKey(); 
    InputKey keyFour = new InputKey(); 
 
    System.out.println("Creating the four RouterGui objects"); 
    System.out.println(); 
    RouterGui first = new RouterGui(keyOne); 
    RouterGui second = new RouterGui(keyTwo); 
    RouterGui third = new RouterGui(keyThree); 
    RouterGui fourth = new RouterGui(keyFour); 
 
    System.out.println("Creating GUI OutputChannel lists for the Router"); 
    System.out.println(); 
    OutputChannel[] subscriptionListOne = { second.getOutputChannel(), 
        third.getOutputChannel() }; 
    OutputChannel[] subscriptionListTwo = { first.getOutputChannel(), 
        fourth.getOutputChannel() }; 
    OutputChannel[] subscriptionListThree = { first.getOutputChannel(), 
        second.getOutputChannel(), third.getOutputChannel(), 
        fourth.getOutputChannel() }; 
 
    mainRouter.addRoute(keyOne, subscriptionListOne); 
    mainRouter.addRoute(keyTwo, subscriptionListTwo); 
    mainRouter.addRoute(keyThree, subscriptionListTwo); 
    mainRouter.addRoute(keyFour, subscriptionListThree); 
 
    first.createGui(); 
    second.createGui(); 
    third.createGui(); 
    fourth.createGui(); 
  } 
} 
 
class Message implements Serializable { 
  private InputChannel source; 
 
  private String message; 
 
  public Message(InputChannel source, String message) { 
    this.source = source; 
    this.message = message; 
  } 
 
  public InputChannel getSource() { 
    return source; 
  } 
 
  public String getMessage() { 
    return message; 
  } 
} 
 
interface OutputChannel extends Remote { 
  public void sendMessage(Message message) throws RemoteException; 
} 
 
interface Receiver { 
  public void receiveMessage(Message message); 
} 
 
class Router implements OutputChannel { 
  private static final String ROUTER_SERVICE_NAME = "router"; 
 
  private HashMap links = new HashMap(); 
 
  public Router() { 
    try { 
      UnicastRemoteObject.exportObject(this); 
      Naming.rebind(ROUTER_SERVICE_NAME, this); 
    } catch (Exception exc) { 
      System.err.println("Error using RMI to register the Router " + exc); 
    } 
  } 
 
  public synchronized void sendMessage(Message message) { 
    Object key = message.getSource(); 
    OutputChannel[] destinations = (OutputChannel[]) links.get(key); 
    new RouterWorkThread(message, destinations); 
  } 
 
  public void addRoute(InputChannel source, OutputChannel[] destinations) { 
    links.put(source, destinations); 
  } 
 
  private class RouterWorkThread implements Runnable { 
    private OutputChannel[] destinations; 
 
    private Message message; 
 
    private Thread runner; 
 
    private RouterWorkThread(Message newMessage, 
        OutputChannel[] newDestinations) { 
      message = newMessage; 
      destinations = newDestinations; 
      runner = new Thread(this); 
      runner.start(); 
    } 
 
    public void run() { 
      for (int i = 0; i < destinations.length; i++) { 
        try { 
          destinations[i].sendMessage(message); 
        } catch (RemoteException exc) { 
          System.err.println("Unable to send message to " 
              + destinations[i]); 
        } 
      } 
    } 
  } 
} 
 
class RouterClient implements OutputChannel { 
  private static final String ROUTER_CLIENT_SERVICE_PREFIX = "routerClient"; 
 
  private static final String ROUTER_SERVER_MACHINE_NAME = "localhost"; 
 
  private static final String ROUTER_SERVER_SERVICE_NAME = "router"; 
 
  private static int clientIndex = 1; 
 
  private String routerClientServiceName = ROUTER_CLIENT_SERVICE_PREFIX 
      + clientIndex++; 
 
  private OutputChannel router; 
 
  private Receiver receiver; 
 
  public RouterClient(Receiver newReceiver) { 
    receiver = newReceiver; 
    try { 
      UnicastRemoteObject.exportObject(this); 
      Naming.rebind(routerClientServiceName, this); 
      String url = "//" + ROUTER_SERVER_MACHINE_NAME + "/" 
          + ROUTER_SERVER_SERVICE_NAME; 
      router = (OutputChannel) Naming.lookup(url); 
    } catch (Exception exc) { 
      System.err.println("Error using RMI to register the Router " + exc); 
    } 
 
  } 
 
  public void sendMessageToRouter(Message message) { 
    try { 
      router.sendMessage(message); 
    } catch (RemoteException exc) { 
    } 
  } 
 
  public void sendMessage(Message message) { 
    receiver.receiveMessage(message); 
  } 
 
  public String toString() { 
    return routerClientServiceName; 
  } 
} 
 
class RouterGui implements ActionListener, Receiver { 
  private static int instanceCount = 1; 
 
  private RouterClient routerClient; 
 
  private JFrame mainFrame; 
 
  private JButton exit, clearDisplay, sendMessage; 
 
  private JTextArea display; 
 
  private JTextField inputTextField; 
 
  private InputChannel inputChannel; 
 
  public OutputChannel getOutputChannel() { 
    return routerClient; 
  } 
 
  public RouterGui(InputChannel newInputChannel) { 
    inputChannel = newInputChannel; 
    routerClient = new RouterClient(this); 
  } 
 
  public void createGui() { 
    mainFrame = new JFrame("Demonstration for the Router pattern - GUI #" 
        + instanceCount++); 
    Container content = mainFrame.getContentPane(); 
    content.setLayout(new BoxLayout(content, BoxLayout.Y_AXIS)); 
 
    JPanel displayPanel = new JPanel(); 
    display = new JTextArea(10, 40); 
    JScrollPane displayArea = new JScrollPane(display); 
    display.setEditable(false); 
    displayPanel.add(displayArea); 
    content.add(displayPanel); 
 
    JPanel dataPanel = new JPanel(); 
    dataPanel.add(new JLabel("Message:")); 
    inputTextField = new JTextField(30); 
    dataPanel.add(inputTextField); 
    content.add(dataPanel); 
 
    JPanel controlPanel = new JPanel(); 
    sendMessage = new JButton("Send Message"); 
    clearDisplay = new JButton("Clear"); 
    exit = new JButton("Exit"); 
    controlPanel.add(sendMessage); 
    controlPanel.add(clearDisplay); 
    controlPanel.add(exit); 
    content.add(controlPanel); 
 
    sendMessage.addActionListener(this); 
    clearDisplay.addActionListener(this); 
    exit.addActionListener(this); 
    inputTextField.addActionListener(this); 
 
    mainFrame.addWindowListener(new WindowCloseManager()); 
    mainFrame.pack(); 
    mainFrame.setVisible(true); 
  } 
 
  public void actionPerformed(ActionEvent evt) { 
    Object source = evt.getSource(); 
    if (source == sendMessage) { 
      sendMessage(); 
    } else if (source == inputTextField) { 
      sendMessage(); 
    } else if (source == clearDisplay) { 
      clearDisplay(); 
    } else if (source == exit) { 
      exitApplication(); 
    } 
  } 
 
  private class WindowCloseManager extends WindowAdapter { 
    public void windowClosing(WindowEvent evt) { 
      exitApplication(); 
    } 
  } 
 
  private void exitApplication() { 
    System.exit(0); 
  } 
 
  private void clearDisplay() { 
    inputTextField.setText(""); 
    display.setText(""); 
  } 
 
  private void sendMessage() { 
    String data = inputTextField.getText(); 
    routerClient.sendMessageToRouter(new Message(inputChannel, data)); 
    inputTextField.setText(""); 
  } 
 
  public void receiveMessage(Message message) { 
    display.append(message.getMessage() + "\n"); 
  } 
} 
 
class InputKey implements InputChannel { 
  private static int nextValue = 1; 
 
  private int hashVal = nextValue++; 
 
  public int hashCode() { 
    return hashVal; 
  } 
 
  public boolean equals(Object object) { 
    if (!(object instanceof InputKey)) { 
      return false; 
    } 
    if (object.hashCode() != hashCode()) { 
      return false; 
    } 
    return true; 
  } 
} 
 
interface InputChannel extends Serializable { 
} 
 
 
            
       
  |