COMP 310
Fall 2010

Lec33:  Chat App API finalization

Home  Info  Owlspace  Resources


Well-Known Data Types


Identifying IUsers

Question:   Is the UUID value tied to the instance of the IUser or is it tied to the instance of the ChatApp, i.e. the human operator?    That is, if one's model instantiates more than one instance its own IUser implementation, is that a different user or the same user?     Is this an API issue or not?


Overriding equals() and hashCode() in a proxy class to enable standard equality tests:

	private class ProxyUser implements IUser, Serializable {
		 * The decoree
		private IUser stub;
		// --- Other methods and fields elided -----------

		 * Overridden equals() method to compare UUID's
		 * @return  Equal if UUID's are equal.  False otherwise.
		public boolean equals(Object other){
			if(other instanceof IUser) { // make sure that other object is an IUser
				try {
					// Equality of IUsers is same as equality of UUID's.
					return stub.getUUID().equals(((IUser)other).getUUID());
				} catch (RemoteException e) {
					// Deal with the exception without throwing a RemoteException.
					System.err.println("ProxyUser.equals(): error getting UUID: "+ e);
					// Fall through and return false
			return false;

		 * Overridden hashCode() method to create a hashCode from that is hashCode of the UUID since
		 * equality is based on equality of UUID.
		 * @return a hashCode of the UUID.	
		public int hashCode(){
			try {
				// hashCode is shorter than UUID, but Java spec says that if two objects are equal then
				// their hashCodes must also be equal, which will be true here since equals() is based on 
				// UUID equality.  Java does NOT require that unequal entities have unequal hashCodes. 
				return stub.getUUID().hashCode();
			} catch (RemoteException e) {
				// Deal with the exception without throwing a RemoteException.
				System.err.println("ProxyStub.hashCode(): Error calling remote method on IUser stub: "+e);
				return super.hashCode();  // return some sort of hashCode


Unknown Data Type Management Protocol Options:

(Sub-items are a matched set)

  1. Receiver attempts to process a received data packet and discovers that they don't know how to process it.
  2. Receiver returns IUnknownIDStatus object to sender.
    1. Receiver caches the unknown data waiting to process it, OR
    2. Receiver  discards unknown data.
  3.  Sender receives IUnknownIDStatus and sends DataPacket<IAddCommand> to receiver ONLY.
  4.  Sender resends data
  5. Resending data?
    1. No need to resend if data was cached by receiver.  OR
    2. Resend data
      1. Data is automatically resent  -- sender must remember what data was originally sent.   OR
      2. Sender waits for request to resend data.   -- resend data to everyone?

Use Owlspace poll to decide between paths "A", "B-i" and "B-ii" above.    Final poll results:  Path B-i.  


Does IChatRoom need an interface to the View/Model too?

Use Owlspace poll to decide.   Final poll results:  IChatRoom has no access to local View/Model.  


Additonal Poll Results:


New ICmd2ModelAdapter Interface

import java.awt.Component;

import comp310f10.rmiChat.IUser;

 * Interface between a DataPacketAlgoCmd and the model of a ChatApp system.   Allows a foreign command
 * access to some limited services of its host ChatApp.  
public interface ICmd2ModelAdapter {
	 * Gets a reference to the local IUser stub which is needed to instantiate IStatus return objects.
	 * @return The local IUser's stub.
	public abstract IUser getLocalUserStub();
	 * Appends the given string onto a text display somewhere on the host ChatApp's GUI.
	 * @param s A string to display
	public abstract void append(String s);
	 * Allows the command to give a java.awt.Component to the host ChatApp to be displayed on 
	 * its GUI somewhere. 
	 * @param name  A title for the component, useful for tabs, frame titles, etc.
	 * @param newComp  The component to display.
	public void addComponent(String name, Component newComp);


This implies the existence of a method on ADataPacketAlgoCmd:

public abstract void setCmd2ModelAdpt(ICmd2ModelAdapter cmd2ModelAdpt);

Important implementation detail: 

Keeping a field value from being serialized:

As per the above API standard, a ADataPacketAlgoCmd implementaion may have a field of type ICmd2ModelAdapter that holds a reference to current adapter.    When a command is transferred from the sender to the receiver, the command may have been already connected to the sender's model via an ICmd2ModelAdapter implementation created by the sender. 

But when the command is sent to the receiver, the receiver will install its own ICmd2ModelAdapter that connects to its own model and view.   It is not necessary or desirable to serialize and transmit the value of the adapter reference  esp. since such adapters are usually anonymous inner classes. 

To tell Java not to serialize and transmit the value of a field, mark the field with the keyword "transient". 


private transient ICmd2ModelAdapter cmd2ModelAdpt; 

When this the command is deserialized at the receiver, this field will be null.    Thus, you MUST call setCmd2ModelAdpt() on the new command BEFORE it is installed into the data packet processing visitor (e.g. algo.setCmd())!


Java How-To's




© 2010 by Stephen Wong and Scott Rixner