Java/Design Pattern/HOPP Pattern
HOPP Pattern in Java
//[C] 2002 Sun Microsystems, Inc.---
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.rmi.Naming;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
public class RunHOPPPattern {
private static java.util.Calendar dateCreator = java.util.Calendar.getInstance();
public static void main(String [] arguments) throws RemoteException{
System.out.println("Example for the HOPP pattern");
System.out.println();
System.out.println("This example will use RMI to demonstrate the HOPP pattern.");
System.out.println(" In the sample, there will be two objects created, CalendarImpl");
System.out.println(" and CalendarHOPP. The CalendarImpl object provides the true");
System.out.println(" server-side implementation, while the CalendarHOPP would be");
System.out.println(" a client or middle-tier representative. The CalendarHOPP will");
System.out.println(" provide some functionality, in this case supplying the hostname");
System.out.println(" in response to the getHost method.");
System.out.println();
System.out.println("Note: This example runs the rmiregistry, CalendarHOPP and CalendarImpl");
System.out.println(" on the same machine.");
System.out.println();
try{
Process p1 = Runtime.getRuntime().exec("rmic CalendarImpl");
Process p2 = Runtime.getRuntime().exec("rmic CalendarHOPP");
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 CalendarImpl object, which provides the server-side implementation.");
System.out.println("(Note: If the CalendarImpl object does not have a file containing Appointments,");
System.out.println(" this call will produce an error message. This will not affect the example.)");
CalendarImpl remoteObject = new CalendarImpl();
System.out.println();
System.out.println("Creating the CalendarHOPP object, which provides client-side functionality.");
CalendarHOPP localObject = new CalendarHOPP();
System.out.println();
System.out.println("Getting the hostname. The CalendarHOPP will handle this method locally.");
System.out.println("Hostname is " + localObject.getHost());
System.out.println();
System.out.println("Creating and adding appointments. The CalendarHOPP will forward");
System.out.println(" these calls to the CalendarImpl object.");
Contact attendee = new ContactImpl("Jenny", "Yip", "Chief Java Expert", "MuchoJava LTD");
ArrayList contacts = new ArrayList();
contacts.add(attendee);
Location place = new LocationImpl("Albuquerque, NM");
localObject.addAppointment(new Appointment("Opening speeches at annual Java Guru"s dinner",
contacts, place, createDate(2001, 4, 1, 16, 0),
createDate(2001, 4, 1, 18, 0)), createDate(2001, 4, 1, 0, 0));
localObject.addAppointment(new Appointment("Java Guru post-dinner Cafe time",
contacts, place, createDate(2001, 4, 1, 19, 30),
createDate(2001, 4, 1, 21, 45)), createDate(2001, 4, 1, 0, 0));
System.out.println("Appointments added.");
System.out.println();
System.out.println("Getting the Appointments for a date. The CalendarHOPP will forward");
System.out.println(" this call to the CalendarImpl object.");
System.out.println(localObject.getAppointments(createDate(2001, 4, 1, 0, 0)));
}
public static Date createDate(int year, int month, int day, int hour, int minute){
dateCreator.set(year, month, day, hour, minute);
return dateCreator.getTime();
}
}
interface Contact extends Serializable{
public static final String SPACE = " ";
public String getFirstName();
public String getLastName();
public String getTitle();
public String getOrganization();
public void setFirstName(String newFirstName);
public void setLastName(String newLastName);
public void setTitle(String newTitle);
public void setOrganization(String newOrganization);
}
class ContactImpl implements Contact{
private String firstName;
private String lastName;
private String title;
private String organization;
public ContactImpl(){}
public ContactImpl(String newFirstName, String newLastName,
String newTitle, String newOrganization){
firstName = newFirstName;
lastName = newLastName;
title = newTitle;
organization = newOrganization;
}
public String getFirstName(){ return firstName; }
public String getLastName(){ return lastName; }
public String getTitle(){ return title; }
public String getOrganization(){ return organization; }
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 String toString(){
return firstName + SPACE + lastName;
}
}
interface Location extends Serializable{
public String getLocation();
public void setLocation(String newLocation);
}
class LocationImpl implements Location{
private String location;
public LocationImpl(){ }
public LocationImpl(String newLocation){
location = newLocation;
}
public String getLocation(){ return location; }
public void setLocation(String newLocation){ location = newLocation; }
public String toString(){ return location; }
}
interface Calendar extends Remote{
public String getHost() throws RemoteException;
public ArrayList getAppointments(Date date) throws RemoteException;
public void addAppointment(Appointment appointment, Date date) throws RemoteException;
}
class CalendarHOPP implements Calendar, java.io.Serializable{
private static final String PROTOCOL = "rmi://";
private static final String REMOTE_SERVICE = "/calendarimpl";
private static final String HOPP_SERVICE = "calendar";
private static final String DEFAULT_HOST = "localhost";
private Calendar calendar;
private String host;
public CalendarHOPP(){
this(DEFAULT_HOST);
}
public CalendarHOPP(String host){
try {
this.host = host;
String url = PROTOCOL + host + REMOTE_SERVICE;
calendar = (Calendar)Naming.lookup(url);
Naming.rebind(HOPP_SERVICE, this);
}
catch (Exception exc){
System.err.println("Error using RMI to look up the CalendarImpl or register the CalendarHOPP " + exc);
}
}
public String getHost(){ return host; }
public ArrayList getAppointments(Date date) throws RemoteException{ return calendar.getAppointments(date); }
public void addAppointment(Appointment appointment, Date date) throws RemoteException { calendar.addAppointment(appointment, date); }
}
class CalendarImpl implements Calendar{
private static final String REMOTE_SERVICE = "calendarimpl";
private static final String DEFAULT_FILE_NAME = "calendar.ser";
private HashMap appointmentCalendar = new HashMap();
public CalendarImpl(){
this(DEFAULT_FILE_NAME);
}
public CalendarImpl(String filename){
File inputFile = new File(filename);
appointmentCalendar = (HashMap)FileLoader.loadData(inputFile);
if (appointmentCalendar == null){
appointmentCalendar = new HashMap();
}
try {
UnicastRemoteObject.exportObject(this);
Naming.rebind(REMOTE_SERVICE, this);
}
catch (Exception exc){
System.err.println("Error using RMI to register the CalendarImpl " + exc);
}
}
public String getHost(){ return ""; }
public ArrayList getAppointments(Date date){
ArrayList returnValue = null;
Long appointmentKey = new Long(date.getTime());
if (appointmentCalendar.containsKey(appointmentKey)){
returnValue = (ArrayList)appointmentCalendar.get(appointmentKey);
}
return returnValue;
}
public void addAppointment(Appointment appointment, Date date){
Long appointmentKey = new Long(date.getTime());
if (appointmentCalendar.containsKey(appointmentKey)){
ArrayList appointments = (ArrayList)appointmentCalendar.get(appointmentKey);
appointments.add(appointment);
}
else {
ArrayList appointments = new ArrayList();
appointments.add(appointment);
appointmentCalendar.put(appointmentKey, appointments);
}
}
}
class FileLoader{
public static Object loadData(File inputFile){
Object returnValue = null;
try{
if (inputFile.exists()){
if (inputFile.isFile()){
ObjectInputStream readIn = new ObjectInputStream(new FileInputStream(inputFile));
returnValue = readIn.readObject();
readIn.close();
}
else {
System.err.println(inputFile + " is a directory.");
}
}
else {
System.err.println("File " + inputFile + " does not exist.");
}
}
catch (ClassNotFoundException exc){
exc.printStackTrace();
}
catch (IOException exc){
exc.printStackTrace();
}
return returnValue;
}
public static void storeData(File outputFile, Serializable data){
try{
ObjectOutputStream writeOut = new ObjectOutputStream(new FileOutputStream(outputFile));
writeOut.writeObject(data);
writeOut.close();
}
catch (IOException exc){
exc.printStackTrace();
}
}
}
class Appointment implements Serializable{
private String description;
private ArrayList contacts;
private Location location;
private Date startDate;
private Date endDate;
public Appointment(String description, ArrayList contacts, Location location, Date startDate, Date endDate){
this.description = description;
this.contacts = contacts;
this.location = location;
this.startDate = startDate;
this.endDate = endDate;
}
public String getDescription(){ return description; }
public ArrayList getContacts(){ return contacts; }
public Location getLocation(){ return location; }
public Date getStartDate(){ return startDate; }
public Date getEndDate(){ return endDate; }
public void setDescription(String description){ this.description = description; }
public void setContacts(ArrayList contacts){ this.contacts = contacts; }
public void setLocation(Location location){ this.location = location; }
public void setStartDate(Date startDate){ this.startDate = startDate; }
public void setEndDate(Date endDate){ this.endDate = endDate; }
public String toString(){
return "Appointment:" + "\n Description: " + description +
"\n Location: " + location + "\n Start: " +
startDate + "\n End: " + endDate + "\n";
}
}