---
# System prepended metadata

title: Design Spec

---

# Design Spec
> By Ahmed Zaheer Dadarkar

# Objective

* Build utility class `Serialize` which would contain functions to serialize and deserialize objects which are to be sent accross the network
    * Write a static function `serialize` of the class `Serialize` to take an 
      object (which is serializable) and convert it into a serialized string
      which can be used to completely recover the object at the receiver end.
    * Write a static function `deserialize` of the class `Serialize` to take
      a serialized string and return the corresponding object and its dynamic
      type.
* Implement the functionality to build different kinds of shapes
    * Provide a `BoardObject` class which would generalize each shape by
      containing the list of pixels belonging to the object.
    * Write static functions for the `BoardObjectBuilder` class to create
      different kinds of shapes like Circles, Squares, Triangles and
      Line Segments as `BoardObject` objects.
* Add Persistence Support Functions at the Server Side
    * Write a store function to take a filepath, convert the Board State
      into a file and store it at that filepath. 
    * Write a load function to take a filepath and acquire the Board State
      from the file at that filepath.
* Add Utility Classes
    * Add utility classes for Username, User ID, Object ID, Intensity,
      Position, Pixel and Filepath.

# Serializing Objects

## Serialize a Serializable Object

1. First get the dynamic type of the object
2. Then convert the bytes of the object into a String
3. Now, create a JSON Object with two key-value pairs, the first pair maps
   the String "objectType" to dynamic type of the object and the second pair
   maps the String "data" to the String of the bytes of the object (i.e.
   the data of the object)
4. Convert the JSON Object into a String and return it

## Deserialize a Serialized String

1. Parse the JSON String to get the String containing the dynamic object
   type and the String containing the object's data.
2. Convert the data of the object into an Object of Serializable type.
3. Return the Object and the String containing the dynamic object type.

Notes:

- Here, by dynamic type I mean runtime type of the object as opposed to the
  static type determined by a base class or an interface.
- One may recover the original object with its accurate type by first calling
  the deserialize function on the serialized String and extracting the object
  and it's dynamic type, then (downcast) casting based on the dynamic type
  to get the accurate typed object.

# Shape functionality

Following are the provided standard shapes and the parameters
required to construct a `BoardObject` object of that shape.

### Circle

Requires center pixel position and radius in terms
of pixel units. An algorithm to compute the pixels from these parameters
would be provided in the `drawCircle` function of `BoardObjectBuilder`.

### Rectangle

Requires top left corner pixel position of square and bottom right
corner pixel position of rectangle. An algorithm to compute the pixels
from these parameters would be provided in the `drawRectangle` function of
`BoardObjectBuilder`.

### Triangle

Requires three pixel positions which would denote the three vertices
of the triangle. An algorithm to compute the pixels from these
parameters would be provided in the `drawTriangle` function
of `BoardObjectBuilder`.

### Line Segment

Requires two pixel positions which would denote the end points of the
line segment. An algorithm to compute the pixels from these
parameters would be provided in the `drawSegment` function
of `BoardObjectBuilder`.

# Persistence Support Functions at the Server Side

### Store Board State

Given the board state and local file path, the board state
is serialized and stored at the given file path.

### Load Board State

Given the local file path corresponding to a file which represents
a board state, we would build the board state using that file.

# Utility Classes

Utility classes for Username, User ID, Object ID, Intensity, Position, 
Pixel and Filepath would be provided. These classes are provided
for better readability.

# Interfaces

```java
    // The Serialize class provides the serialize and deserialize
    // functions for Serializable objects. The `deserialize`
    // function when applied on a string serialized by the
    // `serialize` function outputs the exact same object
    // and its dynamic type.
    public class Serialize {
        // The `serialize` function takes as input an object
        // `serialObj` which implements the Serializable interface
        // and outputs the object as a serialized String
        public static String serialize (Serializable serialObj);
        
        // The `deserialize` function takes as input a
        // String `serialString` which is the serialized form
        // of a Serializable object, and returns the object
        // and its dynamic type
        public static Pair<String, Serializable> 
            deSerialize (String serialString);
    }
```

```java
    
    // This functions in `BoardObjectBuilder` class
    // are responsible for computing the pixels
    // from the given parameters, updating
    // the board state maps, inserting into
    // the list of objects in the board state
    // and returning the built board object to the
    // caller.
    public class BoardObjectBuilder {
        // Construct a circle based on the
        // center, radius and color
        public static BoardObject drawCircle (
            Position center,
            Radius radius,
            Intensity intensity
        );
        
        // Construct a rectangle based on the
        // top left, bottom right positions and
        // the color
        public static BoardObject drawRectangle (
            Position topLeft,
            Position bottomRight,
            Intensity intensity
        );
        
        // Construct a triangle based on three
        // verticex coordinates and the color
        public static BoardObject drawTriangle (
            Position vertA,
            Position vertB,
            Position vertC,
            Intensity intensity
        );
        
        // Construct a line segment based on end
        // point coordinates of the segment 
        // and the color
        public static BoardObject drawSegment (
            Position pointA,
            Position pointB,
            Intensity intensity
        );
    }
    
    // Supportive Datatype for BoardObjectOperation
    // This datatype would be helpful to get the
    // type of operation that should be performed
    // on the object without giving information
    // about the parameters of the operation
    public enum BoardObjectOperationType {
        CREATE,        // Non-parametric operations
        DELETE,
        ROTATE,        // Parametric operations
        COLOR_CHANGE
    }
    // Note that CREATE and DELETE are non-parametric
    // operations in the sense that they do not require
    // parameters, while ROTATE and COLOR_CHANGE are
    // parametric operations because they require
    // the angle and intensity respectively
    
    // Note: If all operations were non-parametric, then
    // we could have just used the enum `BoardObjectOperationType`,
    // but since they are not we use the following interface
    // to represent the operations
    
    // This interface would provide the operation that would
    // be performed on the object.
    public interface BoardObjectOperation {
        // Board Object Operation type
        private BoardObjectOperationType boardOpType;

        // This method would give the type, which
        // would then help us to (downcast) cast
        // it into its original dynamic type for
        // retrieving the parameters
        public BoardObjectOperationType getOperationType();
    }
    
    // The Creation Operation - It has no parameters
    public class CreateOperation implements BoardObjectOperation {
        private BoardObjectOperationType operationType;
        
        public CreateOperation ();
        public BoardObjectOperationType getOperationType ();
    }
    
    // The Deletion Operation - It has no parameters
    public class DeleteOperation implements BoardObjectOperation  {
        private BoardObjectOperationType operationType;
        
        public DeleteOperation ();
        public BoardObjectOperationType getOperationType ();
    }
    
    // The Rotation Operation - It has the angle parameter
    public class RotateOperation implements BoardObjectOperation  {
        private Angle angleCCW;
        private BoardObjectOperationType operationType;
        
        public RedoOperation (Angle angleCCW);
        public BoardObjectOperationType getOperationType ();
    }
    
    // The Color Change Operation - It has the intensity
    // parameter (i.e. color)
    public class ColorChangeOperation implements BoardObjectOperation  {
        private Intensity intensity;
        private BoardObjectOperationType operationType;
        
        public ColorChangeOperation (Intensity intensity);
        public BoardObjectOperationType getOperationType ();
    }
    
    // The `BoardObject` class represents a shape
    // by storing the list of pixels which represent
    // that shape. An object of this class is what
    // is sent accross the network when it is created
    // or an operation is performed on it
    public class BoardObject implements Serializable {
        private ArrayList <Pixel> pixels;     // List of Pixels Representing the object
        private BoardObjectOperation boardOp; // The operation performed on this object
        private ObjectId objectId;            // The object ID
        private Timestamp timestamp;          // Time of creation of this object
        private UserId userId;           // User ID of the user who owns this object
        private ArrayList <Pixel> prevPixelIntensities; // previous intensities (color) of
                                                        // this object - required by undo
        private boolean isReset;         // Is this object a reset object ?
        // By reset object we mean an object which is built by an erase or clear
        // screen operation. This object then, cannot be rotated or color changed
        
        // Construct a Board Object using the list of pixels,
        // object ID, timestamp and user ID
        public BoardObject (
            ArrayList <Pixel> pixels,
            ObjectId objectId,
            Timestamp timestamp,
            UserId userId
        );
        public BoardObjectOperation getOperation (); // Get the operation corresponding to this shape
        // Set the operation corresponding to this shape
        // This operation has special functionality for color change
        // operation - it stores previous intensities into the
        // `prevPixelIntensities` variable - required by undo
        public void setOperation (BoardObjectOperation boardOp);
        // Get the board object's list of pixels
        public ArrayList <Pixel> getPixels ();
        // Set the pixels using the given list of pixels
        public void setPixels (ArrayList <Pixel> pixels);
        // Get the user's User ID who owns this object
        public UserId getUserId();
        // Set user ID of the object
        public void setUserId(UserId userId);
        // Get object ID
        public ObjectId getObjectId();
        // Get timestamp of creation of object
        public Timestamp getTimestamp();
        // Is this a reset object ?
        public boolean isResetObject();
        // Get previous intensities of pixels
        public ArrayList <Pixel> getPrevIntensity();
    }
```

```java
    // This class provides functions for storing board
    // state at a location in the filepath, and retrieving
    // it back from the filepath
    public class PersistanceSupport {
        // Store Board State as file given by the filepath
        public static void storeState (
            BoardState boardState,
            Filepath filepath
        );
        
        // Load the Board State from file given by the filepath
        public static BoardState loadState (
            Filepath filepath
        );
    }
```

```java
    // This class corresponds to the Username
    public class Username {
        // The Username is internally stored as a String
        private String username;
        
        // Build username as string
        public Username(String username);
        public String toString(); // Conver Username to String
    }
    // This class corresponds to the User ID
    public class UserId {
        // The User ID is internally stored as a String
        private String userId;
        
        // Build user ID using the IP Address and
        // user name of the user
        public UserId(String ipAddress, Username username);
        public String toString(); // Convert User ID to String
    }
    
    // This class corresponds to the Object ID
    public class ObjectId {
        // The Object ID is internally stored as a String
        private String objectId;
        
        // Build Object ID using the user ID and timestamp
        public ObjectId(UserId userId, Timestamp timestamp);
        public String toString(); // Convert Object ID to String
    }
    
    // This class corresponds to RGB values
    public class Intensity {
        public int r, g, b; 
    }
    
    // This class corresponds to row and column of a position
    public class Position {
        public int r, c;
    }
    
    // This class corresponds to position
    // and intensity at that position
    public class Pixel {
        public Position position;
        public Intensity intensity;
    }
    
    // This class corresponds to the
    // file path
    public class Filepath {
        private String filepath;
        
        public Filepath(String filepath);
        public String toString();
    }
    
    // This class corresponds to the radius
    public class Radius {
        public double radius;
    }
    
    // This class corresponds to the angle
    public class Angle {
        public double angle;
    }
    
    // This class corresponds to the dimension
    public class Dimension {
        public int numRows, numCols;
    }
```

# Class diagram for Board Object and Related Classes

![](https://i.imgur.com/Hs8tzEB.png)

# Design Analysis

* All those classes mentioned above which have only static members will
  not be instantiated for objects. They are only used to group together
  similar functions.
* We thought about using JSON instead of XML because we could not find Java
  APIs for XML which were easy-to-use and commonly used, but found very
  easy-to-use APIs for JSON.
* The `Serializable` interface does not require any methods to be implemented.
* The algorithms for computing the pixels from the parameters of different shapes
  would use slight approximations for digits behind the decimal point for the
  computed pixels since the screen is a 2D array of pixels (smallest object
  that can be manipulted is the pixel). 
* One may notice that the `BoardObject` class contains an arrayList of `Pixels`
  and not `Positions`. Although this may not be required in the current design
  since we only support single-colored objects. But, we can extend this to
  multi-colored objects later (if we have sufficient time). At a cost of adding
  an intensity along with every pixel position of the object, we may later be
  able to allow gradient like patterns for multi-colored objects.
* One may notice that we could have provided all operations that could be
  performed on objects as member functions (methods) of the `BoardObject`
  class. But we chose not to do so since we planned to instead create different
  classes (with static members) for each operation (like rotate, color change,
  delete) and let other team members handle it.
* Information about the operation to be performed on the board object is present
  within the `BoardObject` in the form of an object of `BoardObjectOperation`
  class named `boardOp`. Here, if all operations were non-parameteric (i.e. did
  not have parameters like angle or color), then we could have used just an enum
  type, but since that is not the case, we ended up building a single interface
  and a class for each operation.
* We would be providing utility classes which are inherently Strings itself.
  The reason for doing is that we can identify the object by the object name
  as well as its type. For example, we know from this `UserId userId` that
  `userId` represents a user's ID, this provides extended readibility (extension
  to what the object name provides, i.e. `userId`).

# Summary and Conclusion

* The serialize and deserialize methods can work on any object that is Serializable
  i.e. not just on board objects. This would be useful for other serializable 
  objects like the board state that have to be transferred using the network.
* The various algorithms for drawing different standard shapes would be present
  as static functions within the `BoardObjectBuilder` class.
* The `BoardObject` class is the class whose objects would be operated upon by
  various different operations like rotate, delete, undo, redo, color change.
  Objects of this class would be sent accross the network to inform the server
  and other clients about an operation performed on the object by a client.
* The store and load functions for storing and loading the board state in the
  the server's file system would be provided for use by the server which has
  to maintain persistance of the board object.