Java/Design Pattern/HOPP Pattern

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

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";
    }
}