Router Pattern in Java : Router Pattern « Design Pattern « Java






Router Pattern in Java

Router Pattern in Java
//[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 {
}


           
       








Related examples in the same category