Java/Design Pattern/HOPP Pattern
HOPP Pattern in Java
<source lang="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"; }
}
</source>