Java/Design Pattern/Session Pattern

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

Session Pattern in Java

//[C] 2002 Sun Microsystems, Inc.---
import java.io.IOException;
import java.io.Serializable;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.HashMap;
public class RunSessionPattern {
  public static void main(String[] arguments) {
    System.out.println("Example for the Session pattern");
    System.out
        .println("This demonstration will show how a Session can be used");
    System.out
        .println(" to organize a series of actions between a client and");
    System.out.println(" server.");
    System.out
        .println("In this case, clients will use sessions to coordinate");
    System.out.println(" edits of Contact addresses.");
    System.out.println();
    System.out.println("Running the RMI compiler (rmic)");
    System.out.println();
    try {
      Process p1 = Runtime.getRuntime().exec("rmic SessionServerImpl");
      p1.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 SessionServer and two SessionClient objects");
    System.out.println();
    SessionServer serverObject = new SessionServerImpl();
    SessionClient clientOne = new SessionClient();
    SessionClient clientTwo = new SessionClient();
    System.out.println("Creating sample Contacts and Addresses");
    System.out.println();
    Contact firstContact = new ContactImpl("First", "Contact", "primo",
        "OOI", null);
    Contact secondContact = new ContactImpl("Second", "Contact", "secondo",
        "OOI", null);
    Address workAddress = new AddressImpl("Work address", "5440 Division",
        "Fargo", "ND", "54321");
    Address homeAddress = new AddressImpl("Home address", "40 Planar Way",
        "Paris", "TX", "84301");
    System.out
        .println("Adding a contact. Both clients will attempt to edit");
    System.out
        .println(" the same contact at first, which will result in a");
    System.out.println(" SessionException.");
    try {
      clientOne.addContact(firstContact);
      clientTwo.addContact(firstContact);
    } catch (SessionException exc) {
      System.err.println("Exception encountered:");
      System.err.println(exc);
    }
    try {
      System.out
          .println("Adding a different contact to the second client");
      clientTwo.addContact(secondContact);
      System.out
          .println("Adding addresses to the first and second clients");
      clientTwo.addAddress(workAddress);
      clientOne.addAddress(homeAddress);
      clientTwo.addAddress(workAddress);
      clientTwo.addAddress(homeAddress);
      System.out.println("Removing address from a client");
      clientTwo.removeAddress(homeAddress);
      System.out.println("Finalizing the edits to the contacts");
      clientOne.rumitChanges();
      clientTwo.rumitChanges();
      System.out.println("Changes finalized");
      clientTwo.addContact(firstContact);
    } catch (SessionException exc) {
      System.err.println("Exception encountered:");
      System.err.println(exc);
    }
    System.out.println("The following lines will show the state");
    System.out.println(" of the server-side delegate, which in this");
    System.out.println(" example represents a persistent data store.");
    System.out.println();
    System.out.println("Contact list:");
    System.out.println(SessionServerDelegate.getContacts());
    System.out.println("Address list:");
    System.out.println(SessionServerDelegate.getAddresses());
    System.out.println("Edit contacts:");
    System.out.println(SessionServerDelegate.getEditContacts());
  }
}
interface Address extends Serializable {
  public static final String EOL_STRING = System
      .getProperty("line.separator");
  public static final String SPACE = " ";
  public static final String COMMA = ",";
  public String getType();
  public String getDescription();
  public String getStreet();
  public String getCity();
  public String getState();
  public String getZipCode();
  public void setType(String newType);
  public void setDescription(String newDescription);
  public void setStreet(String newStreet);
  public void setCity(String newCity);
  public void setState(String newState);
  public void setZipCode(String newZip);
}
class AddressImpl implements Address {
  private String type;
  private String description;
  private String street;
  private String city;
  private String state;
  private String zipCode;
  public AddressImpl() {
  }
  public AddressImpl(String newDescription, String newStreet, String newCity,
      String newState, String newZipCode) {
    description = newDescription;
    street = newStreet;
    city = newCity;
    state = newState;
    zipCode = newZipCode;
  }
  public String getType() {
    return type;
  }
  public String getDescription() {
    return description;
  }
  public String getStreet() {
    return street;
  }
  public String getCity() {
    return city;
  }
  public String getState() {
    return state;
  }
  public String getZipCode() {
    return zipCode;
  }
  public void setType(String newType) {
    type = newType;
  }
  public void setDescription(String newDescription) {
    description = newDescription;
  }
  public void setStreet(String newStreet) {
    street = newStreet;
  }
  public void setCity(String newCity) {
    city = newCity;
  }
  public void setState(String newState) {
    state = newState;
  }
  public void setZipCode(String newZip) {
    zipCode = newZip;
  }
  public boolean equals(Object o) {
    if (!(o instanceof AddressImpl)) {
      return false;
    } else {
      AddressImpl address = (AddressImpl) o;
      if (street.equals(address.street) && city.equals(address.city)
          && state.equals(address.state)
          && zipCode.equals(address.zipCode)) {
        return true;
      }
      return false;
    }
  }
  public String toString() {
    return street + EOL_STRING + city + COMMA + SPACE + state + SPACE
        + zipCode + EOL_STRING;
  }
}
class SessionServerImpl implements SessionServer {
  private static final String SESSION_SERVER_SERVICE_NAME = "sessionServer";
  public SessionServerImpl() {
    try {
      UnicastRemoteObject.exportObject(this);
      Naming.rebind(SESSION_SERVER_SERVICE_NAME, this);
    } catch (Exception exc) {
      System.err
          .println("Error using RMI to register the SessionServerImpl "
              + exc);
    }
  }
  public long addContact(Contact contact, long sessionID)
      throws SessionException {
    return SessionServerDelegate.addContact(contact, sessionID);
  }
  public long addAddress(Address address, long sessionID)
      throws SessionException {
    return SessionServerDelegate.addAddress(address, sessionID);
  }
  public long removeAddress(Address address, long sessionID)
      throws SessionException {
    return SessionServerDelegate.removeAddress(address, sessionID);
  }
  public long finalizeContact(long sessionID) throws SessionException {
    return SessionServerDelegate.finalizeContact(sessionID);
  }
}
interface SessionServer extends Remote {
  public long addContact(Contact contact, long sessionID)
      throws RemoteException, SessionException;
  public long addAddress(Address address, long sessionID)
      throws RemoteException, SessionException;
  public long removeAddress(Address address, long sessionID)
      throws RemoteException, SessionException;
  public long finalizeContact(long sessionID) throws RemoteException,
      SessionException;
}
class SessionServerDelegate {
  private static final long NO_SESSION_ID = 0;
  private static long nextSessionID = 1;
  private static ArrayList contacts = new ArrayList();
  private static ArrayList addresses = new ArrayList();
  private static HashMap editContacts = new HashMap();
  public static long addContact(Contact contact, long sessionID)
      throws SessionException {
    if (sessionID <= NO_SESSION_ID) {
      sessionID = getSessionID();
    }
    if (contacts.indexOf(contact) != -1) {
      if (!editContacts.containsValue(contact)) {
        editContacts.put(new Long(sessionID), contact);
      } else {
        throw new SessionException(
            "This contact is currently being edited by another user.",
            SessionException.CONTACT_BEING_EDITED);
      }
    } else {
      contacts.add(contact);
      editContacts.put(new Long(sessionID), contact);
    }
    return sessionID;
  }
  public static long addAddress(Address address, long sessionID)
      throws SessionException {
    if (sessionID <= NO_SESSION_ID) {
      throw new SessionException(
          "A valid session ID is required to add an address",
          SessionException.SESSION_ID_REQUIRED);
    }
    Contact contact = (Contact) editContacts.get(new Long(sessionID));
    if (contact == null) {
      throw new SessionException(
          "You must select a contact before adding an address",
          SessionException.CONTACT_SELECT_REQUIRED);
    }
    if (addresses.indexOf(address) == -1) {
      addresses.add(address);
    }
    contact.addAddress(address);
    return sessionID;
  }
  public static long removeAddress(Address address, long sessionID)
      throws SessionException {
    if (sessionID <= NO_SESSION_ID) {
      throw new SessionException(
          "A valid session ID is required to remove an address",
          SessionException.SESSION_ID_REQUIRED);
    }
    Contact contact = (Contact) editContacts.get(new Long(sessionID));
    if (contact == null) {
      throw new SessionException(
          "You must select a contact before removing an address",
          SessionException.CONTACT_SELECT_REQUIRED);
    }
    if (addresses.indexOf(address) == -1) {
      throw new SessionException("There is no record of this address",
          SessionException.ADDRESS_DOES_NOT_EXIST);
    }
    contact.removeAddress(address);
    return sessionID;
  }
  public static long finalizeContact(long sessionID) throws SessionException {
    if (sessionID <= NO_SESSION_ID) {
      throw new SessionException(
          "A valid session ID is required to finalize a contact",
          SessionException.SESSION_ID_REQUIRED);
    }
    Contact contact = (Contact) editContacts.get(new Long(sessionID));
    if (contact == null) {
      throw new SessionException(
          "You must select and edit a contact before committing changes",
          SessionException.CONTACT_SELECT_REQUIRED);
    }
    editContacts.remove(new Long(sessionID));
    return NO_SESSION_ID;
  }
  private static long getSessionID() {
    return nextSessionID++;
  }
  public static ArrayList getContacts() {
    return contacts;
  }
  public static ArrayList getAddresses() {
    return addresses;
  }
  public static ArrayList getEditContacts() {
    return new ArrayList(editContacts.values());
  }
}
interface Contact extends Serializable {
  public static final String SPACE = " ";
  public static final String EOL_STRING = System
      .getProperty("line.separator");
  public String getFirstName();
  public String getLastName();
  public String getTitle();
  public String getOrganization();
  public ArrayList getAddresses();
  public void setFirstName(String newFirstName);
  public void setLastName(String newLastName);
  public void setTitle(String newTitle);
  public void setOrganization(String newOrganization);
  public void addAddress(Address address);
  public void removeAddress(Address address);
}
class ContactImpl implements Contact {
  private String firstName;
  private String lastName;
  private String title;
  private String organization;
  private ArrayList addresses = new ArrayList();
  public ContactImpl() {
  }
  public ContactImpl(String newFirstName, String newLastName,
      String newTitle, String newOrganization, ArrayList newAddresses) {
    firstName = newFirstName;
    lastName = newLastName;
    title = newTitle;
    organization = newOrganization;
    if (newAddresses != null) {
      addresses = newAddresses;
    }
  }
  public String getFirstName() {
    return firstName;
  }
  public String getLastName() {
    return lastName;
  }
  public String getTitle() {
    return title;
  }
  public String getOrganization() {
    return organization;
  }
  public ArrayList getAddresses() {
    return addresses;
  }
  public void setFirstName(String newFirstName) {
    firstName = newFirstName;
  }
  public void setLastName(String newLastName) {
    lastName = newLastName;
  }
  public void setTitle(String newTitle) {
    title = newTitle;
  }
  public void setOrganization(String newOrganization) {
    organization = newOrganization;
  }
  public void addAddress(Address address) {
    if (!addresses.contains(address)) {
      addresses.add(address);
    }
  }
  public void removeAddress(Address address) {
    addresses.remove(address);
  }
  public boolean equals(Object o) {
    if (!(o instanceof ContactImpl)) {
      return false;
    } else {
      ContactImpl contact = (ContactImpl) o;
      if (firstName.equals(contact.firstName)
          && lastName.equals(contact.lastName)
          && organization.equals(contact.organization)
          && title.equals(contact.title)) {
        return true;
      }
      return false;
    }
  }
  public String toString() {
    return firstName + SPACE + lastName + EOL_STRING + addresses;
  }
}
class SessionClient {
  private static final String SESSION_SERVER_SERVICE_NAME = "sessionServer";
  private static final String SESSION_SERVER_MACHINE_NAME = "localhost";
  private long sessionID;
  private SessionServer sessionServer;
  public SessionClient() {
    try {
      String url = "//" + SESSION_SERVER_MACHINE_NAME + "/"
          + SESSION_SERVER_SERVICE_NAME;
      sessionServer = (SessionServer) Naming.lookup(url);
    } catch (RemoteException exc) {
    } catch (NotBoundException exc) {
    } catch (MalformedURLException exc) {
    } catch (ClassCastException exc) {
    }
  }
  public void addContact(Contact contact) throws SessionException {
    try {
      sessionID = sessionServer.addContact(contact, 0);
    } catch (RemoteException exc) {
    }
  }
  public void addAddress(Address address) throws SessionException {
    try {
      sessionServer.addAddress(address, sessionID);
    } catch (RemoteException exc) {
    }
  }
  public void removeAddress(Address address) throws SessionException {
    try {
      sessionServer.removeAddress(address, sessionID);
    } catch (RemoteException exc) {
    }
  }
  public void commitChanges() throws SessionException {
    try {
      sessionID = sessionServer.finalizeContact(sessionID);
    } catch (RemoteException exc) {
    }
  }
}
class SessionException extends Exception {
  public static final int CONTACT_BEING_EDITED = 1;
  public static final int SESSION_ID_REQUIRED = 2;
  public static final int CONTACT_SELECT_REQUIRED = 3;
  public static final int ADDRESS_DOES_NOT_EXIST = 4;
  private int errorCode;
  public SessionException(String cause, int newErrorCode) {
    super(cause);
    errorCode = newErrorCode;
  }
  public SessionException(String cause) {
    super(cause);
  }
  public int getErrorCode() {
    return errorCode;
  }
}