Java/Design Pattern/Router Pattern — различия между версиями

Материал из Java эксперт
Перейти к: навигация, поиск
 
м (1 версия)
 
(нет различий)

Текущая версия на 06:50, 1 июня 2010

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 {
}