Mega Code Archive

 
Categories / Java / Design Pattern
 

Successive Update Pattern in Java

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.Date; import java.util.HashMap; public class RunSuccessiveUpdatePattern {     public static void main(String [] arguments){         System.out.println("Example for the SuccessiveUpdate pattern");         System.out.println("This code provides a basic demonstration");         System.out.println(" of how the client pull form of this pattern");         System.out.println(" could be applied.");         System.out.println("In this case, a change made by a client to a");         System.out.println(" central Task object is subsequently retrieved");         System.out.println(" and displayed by another client.");                  System.out.println("Running the RMI compiler (rmic)");         System.out.println();         try{             Process p1 = Runtime.getRuntime().exec("rmic ClientPullServerImpl");             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 ClientPullServer and two PullClient objects");         ClientPullServer server = new ClientPullServerImpl();         PullClient clientOne = new PullClient("Thing I");         PullClient clientTwo = new PullClient("Thing II");         clientOne.requestTask("First work step");         clientTwo.requestTask("First work step");                  try{             Thread.sleep(10000);         }         catch (InterruptedException exc){ }                  Task task = clientOne.getUpdatedTask();         task.setTaskDetails("Trial for task update");         clientOne.updateTask(task);                  Task newTask = clientTwo.getUpdatedTask();         newTask.setTaskDetails("New details string");         clientTwo.updateTask(newTask);                       } } class Command implements Serializable{     public static final int GET_PROJECT = 1;     public static final int GET_TASK = 2;     public static final int CREATE_CONTACT = 4;     public static final int CREATE_ADDRESS = 8;     public static final int CREATE_PHONE_NUMBER = 16;          private int command;     private Object [] arguments;          public int getCommand(){         return command;     }          public Object [] getArguments(){         return arguments;     }          public void setArguments(Object [] newArguments){         arguments = newArguments;     }          public void setCommand(int newCommand){         command = newCommand;     }          public Command(int name, Object [] argumentList){         command = name;         arguments = argumentList;     } } interface Task extends Serializable{     public String getTaskID();     public Date getLastEditDate();     public String getTaskName();     public String getTaskDetails();     public ArrayList getSubTasks();          public void setTaskName(String newName);     public void setTaskDetails(String newDetails);     public void addSubTask(Task task);     public void removeSubTask(Task task); } class TaskImpl implements Task{     private String taskID;     private Date lastEditDate;     private String taskName;     private String taskDetails;     private ArrayList subTasks = new ArrayList();          public TaskImpl(){         lastEditDate = new Date();         taskName = "";         taskDetails = "";     }     public TaskImpl(String newTaskName, String newTaskDetails,       Date newEditDate, ArrayList newSubTasks){         lastEditDate = newEditDate;         taskName = newTaskName;         taskDetails = newTaskDetails;         if (newSubTasks != null){ subTasks = newSubTasks; }     }          public String getTaskID(){         return taskID;     }     public Date getLastEditDate(){ return lastEditDate; }     public String getTaskName(){ return taskName; }     public String getTaskDetails(){ return taskDetails; }     public ArrayList getSubTasks(){ return subTasks; }          public void setLastEditDate(Date newDate){         if (newDate.after(lastEditDate)){             lastEditDate = newDate;         }     }     public void setTaskName(String newName){ taskName = newName; }     public void setTaskDetails(String newDetails){ taskDetails = newDetails; }     public void addSubTask(Task task){         if (!subTasks.contains(task)){             subTasks.add(task);         }     }     public void removeSubTask(Task task){         subTasks.remove(task);     }          public String toString(){         return taskName + " " + taskDetails;     } } class ClientPullRequester implements Runnable{     private static final int DEFAULT_POLLING_INTERVAL = 10000;     private Thread processingThread;     private PullClient parent;     private ClientPullServer updateServer;     private String taskID;     private boolean shutdown;     private Task currentTask = new TaskImpl();     private int pollingInterval = DEFAULT_POLLING_INTERVAL;          public ClientPullRequester(PullClient newParent, ClientPullServer newUpdateServer,       String newTaskID){         parent = newParent;         taskID = newTaskID;         updateServer = newUpdateServer;         processingThread = new Thread(this);         processingThread.start();     }          public void run(){         while (!isShutdown()){             try{                 currentTask = updateServer.getTask(taskID, currentTask.getLastEditDate());                 parent.setUpdatedTask(currentTask);             }             catch (RemoteException exc){ }             catch (UpdateException exc){                 System.out.println("  " + parent + ": " + exc.getMessage());             }             try{                 Thread.sleep(pollingInterval);             }             catch (InterruptedException exc){ }         }     }          public void updateTask(Task changedTask){         try{             updateServer.updateTask(taskID, changedTask);         }         catch (RemoteException exc){ }         catch (UpdateException exc){             System.out.println("  " + parent + ": " + exc.getMessage());         }     }          public int getPollingInterval(){ return pollingInterval; }     public boolean isShutdown(){ return shutdown; }          public void setPollingInterval(int newPollingInterval){ pollingInterval = newPollingInterval; }     public void setShutdown(boolean isShutdown){ shutdown = isShutdown; } } class UpdateServerDelegate{     private static HashMap tasks = new HashMap();          public static Task getTask(String taskID, Date lastUpdate) throws UpdateException{         if (tasks.containsKey(taskID)){             Task storedTask = (Task)tasks.get(taskID);             if (storedTask.getLastEditDate().after(lastUpdate)){                 return storedTask;             }             else{                 throw new UpdateException("Task " + taskID + " does not need to be updated", UpdateException.TASK_UNCHANGED);             }         }         else{             return loadNewTask(taskID);         }     }          public static void updateTask(String taskID, Task task) throws UpdateException{         if (tasks.containsKey(taskID)){             if (task.getLastEditDate().equals(((Task)tasks.get(taskID)).getLastEditDate())){                 ((TaskImpl)task).setLastEditDate(new Date());                 tasks.put(taskID, task);             }             else{                 throw new UpdateException("Task " + taskID + " data must be refreshed before editing", UpdateException.TASK_OUT_OF_DATE);             }         }     }          private static Task loadNewTask(String taskID){         Task newTask = new TaskImpl(taskID, "", new Date(), null);         tasks.put(taskID, newTask);         return newTask;     } } class PullClient{     private static final String UPDATE_SERVER_SERVICE_NAME = "updateServer";     private static final String UPDATE_SERVER_MACHINE_NAME = "localhost";     private ClientPullServer updateServer;     private ClientPullRequester requester;     private Task updatedTask;     private String clientName;          public PullClient(String newClientName){         clientName = newClientName;         try{             String url = "//" + UPDATE_SERVER_MACHINE_NAME + "/" + UPDATE_SERVER_SERVICE_NAME;             updateServer = (ClientPullServer)Naming.lookup(url);         }         catch (RemoteException exc){}         catch (NotBoundException exc){}         catch (MalformedURLException exc){}         catch (ClassCastException exc){}     }          public void requestTask(String taskID){         requester = new ClientPullRequester(this, updateServer, taskID);     }          public void updateTask(Task task){         requester.updateTask(task);     }          public Task getUpdatedTask(){         return updatedTask;     }          public void setUpdatedTask(Task task){         updatedTask = task;         System.out.println(clientName + ": received updated task: " + task);     }          public String toString(){         return clientName;     } } class TaskResponse implements Serializable{     private Date lastUpdate;     private Task task;          public TaskResponse(Date newUpdate, Task newTask){         lastUpdate = newUpdate;         task = newTask;     }          public Date getLastUpdate(){         return lastUpdate;     }          public Task getTask(){         return task;     }          public void setLastUpdate(Date newDate){         if (newDate.after(lastUpdate)){             lastUpdate = newDate;         }     } } class UpdateException extends Exception{     public static final int TASK_UNCHANGED = 1;     public static final int TASK_OUT_OF_DATE = 2;     private int errorCode;          public UpdateException(String cause, int newErrorCode){         super(cause);         errorCode = newErrorCode;     }     public UpdateException(String cause){ super(cause); }          public int getErrorCode(){ return errorCode; } } interface ClientPullServer extends Remote{     public Task getTask(String taskID, Date lastUpdate) throws RemoteException, UpdateException;     public void updateTask(String taskID, Task updatedTask) throws RemoteException, UpdateException; } class ClientPullServerImpl implements ClientPullServer{     private static final String UPDATE_SERVER_SERVICE_NAME = "updateServer";     public ClientPullServerImpl(){         try {             UnicastRemoteObject.exportObject(this);             Naming.rebind(UPDATE_SERVER_SERVICE_NAME, this);         }         catch (Exception exc){             System.err.println("Error using RMI to register the ClientPullServerImpl " + exc);         }     }          public Task getTask(String taskID, Date lastUpdate) throws UpdateException{         return UpdateServerDelegate.getTask(taskID, lastUpdate);     }          public void updateTask(String taskID, Task updatedTask) throws UpdateException{         UpdateServerDelegate.updateTask(taskID, updatedTask);     } }