import java.io.*;
import java.util.*;

public class MySerializable {

    public static void main(String[] args) throws IOException, Exception {
  ArrayList<Shape> shapes;
  shapes = new ArrayList<Shape>();
  // Make some shapes:
  for (int i = 0; i < 10; i++)
      shapes.add(Shape.randomFactory());
  // Save the state vector:
  ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(
    "CADState.out"));
  Line.serializeStaticState(out);
  Circle.serializeStaticState(out);
  Square.serializeStaticState(out);
  out.writeObject(shapes);
  out.close();

  ObjectInputStream in = new ObjectInputStream(new FileInputStream(
    "CADState.out"));
  // Read in the same order they were written:
  Line.deserializeStaticState(in);
  Circle.deserializeStaticState(in);
  Square.deserializeStaticState(in);
  ArrayList<Shape> s = (ArrayList<Shape>) in.readObject();
  in.close();

  // Display the shapes:
  System.out.println(shapes);
  System.out.println(s);
    }
}

abstract class Shape implements Serializable {
    public static final int RED = 1, BLUE = 2, GREEN = 3;
    private int xPos, yPos, dimension;
    private static Random r = new Random();
    private static int counter = 0;

    abstract public void setColor(int newColor);

    abstract public int getColor();

    public Shape(int xVal, int yVal, int dim) {
  xPos = xVal;
  yPos = yVal;
  dimension = dim;
    }

    public String toString() {
  return getClass() + " color[" + getColor() + "] xPos[" + xPos
    + "] yPos[" + yPos + "] dim[" + dimension + "]\n";
    }

    public static Shape randomFactory() {
  int xVal = r.nextInt() % 100;
  int yVal = r.nextInt() % 100;
  int dim = r.nextInt() % 100;
  switch (counter++ % 3) {
  default:
  case 0:
      return new Circle(xVal, yVal, dim);
  case 1:
      return new Square(xVal, yVal, dim);
  case 2:
      return new Line(xVal, yVal, dim);
  }
    }
}

class Circle extends Shape {
    private static int color = RED;

    public static void serializeStaticState(ObjectOutputStream os)
      throws IOException {
  os.writeInt(color);
    }

    public static void deserializeStaticState(ObjectInputStream os)
      throws IOException {
  color = os.readInt();
    }

    public Circle(int xVal, int yVal, int dim) {
  super(xVal, yVal, dim);
    }

    public void setColor(int newColor) {
  color = newColor;
    }

    public int getColor() {
  return color;
    }
}

class Square extends Shape {
    private static int color = BLUE;

    public static void serializeStaticState(ObjectOutputStream os)
      throws IOException {
  os.writeInt(color);
    }

    public static void deserializeStaticState(ObjectInputStream os)
      throws IOException {
  color = os.readInt();
    }

    public Square(int xVal, int yVal, int dim) {
  super(xVal, yVal, dim);
  color = RED;
    }

    public void setColor(int newColor) {
  color = newColor;
    }

    public int getColor() {
  return color;
    }
}

class Line extends Shape {
    private static int color = GREEN;

    public static void serializeStaticState(ObjectOutputStream os)
      throws IOException {
  os.writeInt(color);
    }

    public static void deserializeStaticState(ObjectInputStream os)
      throws IOException {
  color = os.readInt();
    }

    public Line(int xVal, int yVal, int dim) {
  super(xVal, yVal, dim);
    }

    public void setColor(int newColor) {
  color = newColor;
    }

    public int getColor() {
  return color;
    }
}