CSC407 Winter 2007

Exercise 1

General

This exercise is out of 20, and is worth 10% of your course grade. All work must be submitted via Subversion, and must be readable on CDF. See the home page for the course late policy.

This assignment is due at 5:00 pm EST on Wednesday, January 31. Please ask questions early.

Changes

2007-01-30: PictureDB.getAllPicturePaths should have been static. The spec has been updated; you will not be penalized if your solution to Part 1 assumes that it is not static (as per the original spec).

2007-01-29: you may not change the code skeletons in Question 1. As in the real world, you must work with (or around) the libraries you are given.

2007-01-27: Please submit material in the e01 directory of your repository, not ex01 as the first (mistaken) version of this spec said. -5 millimarks to Greg...

2007-01-27: Question 1 (design patterns) is to be done and submitted individually. Only the term paper will be done in pairs.

2007-01-26: several students have suggested that Facade might be a better choice than Decorator for wrapping the image libraries in the design patterns question. Their arguments are good, so you may use either in your solution. However, you must make it clear in your documentation which you have chosen.

Design Patterns (10 marks)

It's 9:00 a.m. Monday morning, and you have received this message from your boss:

I want you to design a Java tool for manipulating images that have
been subdivided into regions.  Each region can be further subdivided
recursively, down to the single-pixel level.  I think we can use a
tree to represent this; regions at the same level in the tree will
never overlap, but the set of regions may not completely cover the
image.  (I've attached a sketch to give you an idea of what I mean.)

I'd like you to use the Composite pattern to represent the subdivided
images.  We have two different libraries that actually store image
data, and may need to work with more, so use Decorator to wrap them
up.  (Details on their APIs are below.)  Oh, and we have to work with
at least two different image databases; use the Facade pattern to work
with them (their APIs are below as well.)

Finally, use the Command pattern to represent operations on images, so
that we can undo them.  (At least, the ones that can be undone --- I'm
not sure they all can be.)  It's OK to use a Singleton to keep track of
previous commands; all we need to show the customer to convince them we
can do this work is "clear image", "crop to XY size", "sharpen", and
"print".
  

Create a subdirectory in your e01 directory called design that contains Java skeletons for the interfaces and classes you would take to your boss to find out if you were on the right track. You should not implement the classes, but you must include Javadoc, and headers for the methods you think are most important.

Image Decomposition

APIs of Image Storage Classes

From ronsimages.org

public interface RonsImageInterface {

  /** Return image size as integer rectangle with non-zero area. */
  public Rectangle getSize();

  /**
   * Get color at specified pixel, throwing exception if pixel
   * coordinates are not in image.
   */
  public Color getPixel(int x, int y)
    throws CoordinateException;

  /**
   * Set color at specified pixel, throwing exception if pixel
   * coordinates are not in image, or if color is invalid.
   */
  public void setPixel(int x, int y, Color color)
    throws CoordinateException,
           InvalidColorException

  /** Construct an image by copying a region of another, throwing
   *  exception if subdivision coordinates are not in original.
   */
   public RonsImageInterface makeCopy(int lo_x, int lo_y, int hi_x, int hi_y)
    throws CoordinateException;
}

public class RonsImage implements RonsImageInterface {

  /** Construct an image with all pixels set to the specified color. */
  public RonsImage(int x, int y, Color color) {...}

  /* ... plus all methods from interface ... */
}
  

From draco-malfoy.com

public interface Picture {

  /** How big is this picture? *
  public Rectangle getSize();

  /**
   * What color is this picture?  Return null if the picture isn't
   * all the same color.
   */
  public Color getColor();
}

public class Pixel implements Picture {

  /** Create a pixel. */
  public Pixel(Color color) {...}
}

public class RectImg implements Picture {

  /**
   * Make a stupid boring old square image all the same color.
   */
  public RectImg(int size, Color color) {...}

  /**
   * Change the size of an image.  Cuts stupid pixels if they're
   * out of range, and fills with black if the image grows, because
   * everybody knows that black is the c00lest c0l0r.  Doesn't throw
   * any stupid exceptions, because exceptions are for n00bs.
   */
  public resize(int width, int height) {...}

  /**
   * Get part of an image.  If x0==x1 and y0==y1, this returns a
   * Pixel instead of a RectImg.
   */
   public Picture getPart(int x0, int x1, int y0, int y1) {...}
}
  

APIs of Image Databases

From whinyharry.co.uk

public interface Image {
  /**
   * Empty --- create a class that implements this interface,
   * and pass it to the 'createConnection' method to tell the
   * database what class you want to use to wrap the image data.
   */
}

public class ImageDatabase {

  /**
   * Create connection to image database.  This class doesn't have
   * any public constructors, so this is the only way to connect to
   * the database.
   */
  public static ImageDatabase createConnection(
    String connectionUrl,
    String userId,
    String password,
    Class imageClass
  );

  /** Close connection when done. */
  public void close();

  /** Fetch an image by name, returning null if there's no such image. */
  public Image getImage(String name);

  /**
    * Get a list of all the images in the database whose names match
    * a Unix-style pattern.  If the pattern is null or the empty string,
    * return the names of all images.
    */
  public List getImages(String pattern);
}
  

From rhymeswithhermione.com

public class Picture {
  /** Get picture extent. */
  public Rectangle getExtent();

  /** Get value at particular pixel. */
  public Color getPixelValue(int x, int y)
    throws CoordinateException;
}

public class PictureDB {
  /**
   * Fetch a picture stored in a particular database on disk.
   * If the database specified by the first argument doesn't
   * exist, or the current user doesn't have permission to access
   * it, or the specified picture doesn't exist inside the database,
   * throw an exception.
   */
  public static Picture fetch(String dbPath, String picturePath)
    throws NoSuchDBException,
           NoPermissionException,
           NoSuchPictureException;

  /**
   * Get a list of all pictures in the database.
   */
  public static List getAllPicturePaths(String dbPath)
    throws NoSuchDBException,
           NoPermissionException;
}
  

Term Paper (10 marks)

For the first part of your term paper, you must write the following:

Note that all files must be submitted with exactly these names: be careful about case. Please use an 11-point font and single spacing, and remember that we will be viewing and printing files on the CDF Linux machines---anything that is unreadable there will not be marked.

All of these files are to be submitted an e01 directory inside one team member's Subversion repository. The other team member must create a plain text file in her e01 directory called redirect.txt in the following format:

Partner: g0llum
Revision: 14
  

where "Revision" is the revision number that identifies the final version of the work in the partner's repository. The TA will check out and mark this revision, and only this revision.