/** tests the basic shapes. */
  public void testBasicShapes() throws Exception {
    Circle circle = new Circle();
    circle.setColor(Color.BLUE);
    circle.setId("someid");
    circle.setLineStyle(LineStyle.solid);
    circle.setPositionX(8);
    circle.setPositionY(9);
    circle.setRadius(10);

    JacksonJaxbJsonProvider provider = new JacksonJaxbJsonProvider();
    ObjectMapper circleMapper =
        provider.locateMapper(Circle.class, MediaType.APPLICATION_JSON_TYPE);
    ObjectMapper clientMapper = new ObjectMapper();

    ByteArrayOutputStream out = new ByteArrayOutputStream();
    circleMapper.writeValue(out, circle);
    ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());

    shapes.json.Circle clientCircle = clientMapper.readValue(in, shapes.json.Circle.class);
    assertSame(shapes.json.Color.BLUE, clientCircle.getColor());
    assertEquals("someid", clientCircle.getId());
    assertEquals(shapes.json.LineStyle.solid, clientCircle.getLineStyle());
    assertEquals(8, clientCircle.getPositionX());
    assertEquals(9, clientCircle.getPositionY());
    assertEquals(10, clientCircle.getRadius());

    out = new ByteArrayOutputStream();
    clientMapper.writeValue(out, clientCircle);
    in = new ByteArrayInputStream(out.toByteArray());

    circle = circleMapper.readValue(in, Circle.class);
    assertSame(Color.BLUE, circle.getColor());
    assertEquals("someid", circle.getId());
    assertEquals(LineStyle.solid, circle.getLineStyle());
    assertEquals(8, circle.getPositionX());
    assertEquals(9, circle.getPositionY());
    assertEquals(10, circle.getRadius());

    ObjectMapper rectangleMapper =
        provider.locateMapper(Rectangle.class, MediaType.APPLICATION_JSON_TYPE);

    Rectangle rectangle = new Rectangle();
    rectangle.setColor(Color.GREEN);
    rectangle.setId("rectid");
    rectangle.setHeight(500);
    rectangle.setWidth(1000);
    rectangle.setLineStyle(LineStyle.dotted);
    rectangle.setPositionX(-100);
    rectangle.setPositionY(-300);

    out = new ByteArrayOutputStream();
    rectangleMapper.writeValue(out, rectangle);
    in = new ByteArrayInputStream(out.toByteArray());

    shapes.json.Rectangle clientRect = clientMapper.readValue(in, shapes.json.Rectangle.class);
    assertSame(shapes.json.Color.GREEN, clientRect.getColor());
    assertEquals("rectid", clientRect.getId());
    assertEquals(shapes.json.LineStyle.dotted, clientRect.getLineStyle());
    assertEquals(500, clientRect.getHeight());
    assertEquals(1000, clientRect.getWidth());
    assertEquals(-100, clientRect.getPositionX());
    assertEquals(-300, clientRect.getPositionY());

    out = new ByteArrayOutputStream();
    clientMapper.writeValue(out, clientRect);
    in = new ByteArrayInputStream(out.toByteArray());

    rectangle = rectangleMapper.readValue(in, Rectangle.class);
    assertSame(Color.GREEN, rectangle.getColor());
    assertEquals("rectid", rectangle.getId());
    assertEquals(LineStyle.dotted, rectangle.getLineStyle());
    assertEquals(500, rectangle.getHeight());
    assertEquals(1000, rectangle.getWidth());
    assertEquals(-100, rectangle.getPositionX());
    assertEquals(-300, rectangle.getPositionY());

    ObjectMapper triangleMapper =
        provider.locateMapper(Triangle.class, MediaType.APPLICATION_JSON_TYPE);

    Triangle triangle = new Triangle();
    triangle.setBase(90);
    triangle.setColor(Color.RED);
    triangle.setHeight(100);
    triangle.setId("triangleId");
    triangle.setLineStyle(LineStyle.dashed);
    triangle.setPositionX(0);
    triangle.setPositionY(-10);

    out = new ByteArrayOutputStream();
    triangleMapper.writeValue(out, triangle);
    in = new ByteArrayInputStream(out.toByteArray());

    shapes.json.Triangle clientTri = clientMapper.readValue(in, shapes.json.Triangle.class);
    assertSame(shapes.json.Color.RED, clientTri.getColor());
    assertEquals("triangleId", clientTri.getId());
    assertEquals(shapes.json.LineStyle.dashed, clientTri.getLineStyle());
    assertEquals(90, clientTri.getBase());
    assertEquals(100, clientTri.getHeight());
    assertEquals(0, clientTri.getPositionX());
    assertEquals(-10, clientTri.getPositionY());

    out = new ByteArrayOutputStream();
    clientMapper.writeValue(out, clientTri);
    in = new ByteArrayInputStream(out.toByteArray());

    triangle = triangleMapper.readValue(in, Triangle.class);
    assertSame(Color.RED, triangle.getColor());
    assertEquals(90, triangle.getBase());
    assertEquals(100, triangle.getHeight());
    assertEquals("triangleId", triangle.getId());
    assertSame(LineStyle.dashed, triangle.getLineStyle());
    assertEquals(0, triangle.getPositionX());
    assertEquals(-10, triangle.getPositionY());
  }
  /** tests cat. This one has IDREFs. */
  public void testCat() throws Exception {
    Cat cat = new Cat();
    Circle face = new Circle();
    face.setRadius(20);
    cat.setFace(face);
    Triangle ear = new Triangle();
    ear.setBase(5);
    ear.setHeight(10);
    ear.setId("earId");
    cat.setEars(Arrays.asList(ear, ear));

    // The eyes are the same as the ears, but so it needs to be for this test.
    cat.setEyes(new Triangle[] {ear, ear});

    Line noseLine = new Line();
    noseLine.setId("noseId");
    Line mouthLine = new Line();
    mouthLine.setId("mouthLine");

    cat.setNose(noseLine);
    cat.setMouth(mouthLine);
    cat.setWhiskers(Arrays.asList(noseLine, mouthLine));

    JacksonJaxbJsonProvider provider = new JacksonJaxbJsonProvider();
    ObjectMapper catMapper = provider.locateMapper(Cat.class, MediaType.APPLICATION_JSON_TYPE);
    ObjectMapper clientMapper = new ObjectMapper();
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    catMapper.writeValue(out, cat);
    shapes.json.animals.Cat clientCat =
        clientMapper.readValue(
            new ByteArrayInputStream(out.toByteArray()), shapes.json.animals.Cat.class);

    shapes.json.Circle clientFace = clientCat.getFace();
    assertEquals(20, clientFace.getRadius());
    assertEquals(2, clientCat.getEars().size());
    shapes.json.Triangle[] clientEars =
        (shapes.json.Triangle[]) clientCat.getEars().toArray(new shapes.json.Triangle[2]);
    assertNotSame(
        "referential integrity should NOT have been preserved since Jackson doesn't support it yet",
        clientEars[0],
        clientEars[1]);
    assertEquals(5, clientEars[0].getBase());
    assertEquals(10, clientEars[0].getHeight());
    assertEquals("earId", clientEars[0].getId());
    assertEquals(5, clientEars[1].getBase());
    assertEquals(10, clientEars[1].getHeight());
    assertEquals("earId", clientEars[1].getId());

    shapes.json.Triangle[] clientEyes = clientCat.getEyes();
    assertEquals(2, clientEyes.length);
    assertNotSame(clientEyes[0], clientEyes[1]);
    assertEquals(5, clientEyes[0].getBase());
    assertEquals(10, clientEyes[0].getHeight());
    assertEquals("earId", clientEyes[0].getId());
    assertEquals(5, clientEyes[1].getBase());
    assertEquals(10, clientEyes[1].getHeight());
    assertEquals("earId", clientEyes[1].getId());
    assertFalse(
        "The ears should NOT be the same object as one of the eyes since Jackson doesn't support referential integrity.",
        clientEars[0] == clientEyes[0] || clientEars[0] == clientEyes[1]);

    shapes.json.Line clientNose = clientCat.getNose();
    assertEquals("noseId", clientNose.getId());
    shapes.json.Line clientMouth = clientCat.getMouth();
    assertEquals("mouthLine", clientMouth.getId());
    assertFalse(
        "The nose line should NOT also be one of the whiskers since Jackson doesn't support referential integrity.",
        clientCat.getWhiskers().contains(clientNose));
    assertFalse(
        "The mouth line should NOT also be one of the whiskers since Jackson doesn't support referential integrity.",
        clientCat.getWhiskers().contains(clientMouth));

    out = new ByteArrayOutputStream();
    clientMapper.writeValue(out, clientCat);
    cat = catMapper.readValue(new ByteArrayInputStream(out.toByteArray()), Cat.class);

    face = cat.getFace();
    assertEquals(20, face.getRadius());
    assertEquals(2, cat.getEars().size());
    Triangle[] ears = cat.getEars().toArray(new Triangle[2]);
    assertNotSame(
        "referential integrity should NOT have been preserved since Jackson doesn't support referential integrity.",
        ears[0],
        ears[1]);
    assertEquals(5, ears[0].getBase());
    assertEquals(10, ears[0].getHeight());
    assertEquals("earId", ears[0].getId());

    Triangle[] eyes = cat.getEyes();
    assertEquals(2, eyes.length);
    assertNotSame(eyes[0], eyes[1]);
    assertEquals(5, eyes[0].getBase());
    assertEquals(10, eyes[0].getHeight());
    assertEquals("earId", eyes[0].getId());
    assertEquals(5, eyes[1].getBase());
    assertEquals(10, eyes[1].getHeight());
    assertEquals("earId", eyes[1].getId());
    assertFalse(
        "The ears should NOT be the same object as one of the eyes since Jackson doesn't support referential integrity.",
        ears[0] == eyes[0] || ears[0] == eyes[1]);

    Line nose = cat.getNose();
    assertEquals("noseId", nose.getId());
    Line mouth = cat.getMouth();
    assertEquals("mouthLine", mouth.getId());
    assertFalse(
        "The nose line should also be one of the whiskers since Jackson doesn't support referential integrity.",
        cat.getWhiskers().contains(nose));
    assertFalse(
        "The mouth line should also be one of the whiskers since Jackson doesn't support referential integrity.",
        cat.getWhiskers().contains(mouth));
  }
  /** tests house. This one has things like nillable and required properties. */
  public void testHouse() throws Exception {
    House house = new House();
    Rectangle base = new Rectangle();
    base.setColor(Color.BLUE);
    base.setHeight(80);
    base.setWidth(80);
    base.setLineStyle(LineStyle.solid);
    base.setId("baseid");
    house.setBase(base);
    Rectangle door = new Rectangle();
    door.setColor(Color.YELLOW);
    door.setHeight(35);
    door.setWidth(20);
    door.setLineStyle(LineStyle.solid);
    door.setId("doorId");
    house.setDoor(door);
    Circle knob = new Circle();
    knob.setColor(Color.RED);
    knob.setId("knobId");
    knob.setLineStyle(LineStyle.dashed);
    knob.setRadius(2);
    house.setDoorKnob(knob);
    Label label1 = new Label();
    label1.setValue("bachelor-pad");
    Label label2 = new Label();
    label2.setValue("single-family-dwelling");
    house.setLabels(Arrays.asList(label1, label2));
    Triangle roof = new Triangle();
    roof.setBase(84);
    roof.setHeight(20);
    roof.setColor(Color.YELLOW);
    roof.setLineStyle(LineStyle.solid);
    house.setRoof(roof);
    Rectangle window = new Rectangle();
    window.setColor(Color.YELLOW);
    window.setHeight(10);
    window.setWidth(10);
    window.setLineStyle(LineStyle.solid);
    house.setWindows(Arrays.asList(window));
    house.setConstructedDate(new DateTime(3L));
    house.setType(XmlQNameEnumUtil.toQName(HouseType.brick));
    house.setStyle(XmlQNameEnumUtil.toQName(HouseStyle.latin));
    house.setColor(XmlQNameEnumUtil.toURI(HouseColor.blue));

    JacksonJaxbJsonProvider provider = new JacksonJaxbJsonProvider();
    ObjectMapper houseMapper = provider.locateMapper(House.class, MediaType.APPLICATION_JSON_TYPE);
    ObjectMapper clientMapper = new ObjectMapper();
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    houseMapper.writeValue(out, house);
    ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
    shapes.json.structures.House clientHouse =
        clientMapper.readValue(in, shapes.json.structures.House.class);

    shapes.json.Rectangle clientBase = clientHouse.getBase();
    assertSame(shapes.json.Color.BLUE, clientBase.getColor());
    assertSame(shapes.json.LineStyle.solid, clientBase.getLineStyle());
    assertEquals(80, clientBase.getHeight());
    assertEquals(80, clientBase.getWidth());
    assertEquals("baseid", clientBase.getId());
    shapes.json.Rectangle clientDoor = clientHouse.getDoor();
    assertSame(shapes.json.Color.YELLOW, clientDoor.getColor());
    assertSame(shapes.json.LineStyle.solid, clientDoor.getLineStyle());
    assertEquals(35, clientDoor.getHeight());
    assertEquals(20, clientDoor.getWidth());
    assertEquals("doorId", clientDoor.getId());
    shapes.json.Circle clientKnob = clientHouse.getDoorKnob();
    assertSame(shapes.json.Color.RED, clientKnob.getColor());
    assertSame(shapes.json.LineStyle.dashed, clientKnob.getLineStyle());
    assertEquals(2, clientKnob.getRadius());
    assertEquals("knobId", clientKnob.getId());
    List<String> labels = Arrays.asList("bachelor-pad", "single-family-dwelling");
    clientHouse.getLabels().size();
    for (Object l : clientHouse.getLabels()) {
      shapes.json.Label label = (shapes.json.Label) l;
      assertTrue(labels.contains(label.getValue()));
    }
    shapes.json.Triangle clientRoof = clientHouse.getRoof();
    assertSame(shapes.json.Color.YELLOW, clientRoof.getColor());
    assertSame(shapes.json.LineStyle.solid, clientRoof.getLineStyle());
    assertNull(clientRoof.getId());
    assertEquals(84, clientRoof.getBase());
    assertEquals(20, clientRoof.getHeight());
    assertEquals(1, clientHouse.getWindows().size());
    shapes.json.Rectangle clientWindow = (shapes.json.Rectangle) clientHouse.getWindows().get(0);
    assertSame(shapes.json.Color.YELLOW, clientWindow.getColor());
    assertSame(shapes.json.LineStyle.solid, clientWindow.getLineStyle());
    assertEquals(10, clientWindow.getHeight());
    assertEquals(10, clientWindow.getWidth());
    assertNull(clientWindow.getId());
    assertEquals(new Date(3L), clientHouse.getConstructedDate());

    out = new ByteArrayOutputStream();
    clientMapper.writeValue(out, clientHouse);
    house = houseMapper.readValue(new ByteArrayInputStream(out.toByteArray()), House.class);
    base = house.getBase();
    assertSame(Color.BLUE, base.getColor());
    assertSame(LineStyle.solid, base.getLineStyle());
    assertEquals(80, base.getHeight());
    assertEquals(80, base.getWidth());
    assertEquals("baseid", base.getId());
    door = house.getDoor();
    assertSame(Color.YELLOW, door.getColor());
    assertSame(LineStyle.solid, door.getLineStyle());
    assertEquals(35, door.getHeight());
    assertEquals(20, door.getWidth());
    assertEquals("doorId", door.getId());
    knob = house.getDoorKnob();
    assertSame(Color.RED, knob.getColor());
    assertSame(LineStyle.dashed, knob.getLineStyle());
    assertEquals(2, knob.getRadius());
    assertEquals("knobId", knob.getId());
    labels = Arrays.asList("bachelor-pad", "single-family-dwelling");
    house.getLabels().size();
    for (Object l : house.getLabels()) {
      Label label = (Label) l;
      assertTrue(labels.contains(label.getValue()));
    }
    roof = house.getRoof();
    assertSame(Color.YELLOW, roof.getColor());
    assertSame(LineStyle.solid, roof.getLineStyle());
    assertNull(roof.getId());
    assertEquals(84, roof.getBase());
    assertEquals(20, roof.getHeight());
    assertEquals(1, house.getWindows().size());
    window = house.getWindows().get(0);
    assertSame(Color.YELLOW, window.getColor());
    assertSame(LineStyle.solid, window.getLineStyle());
    assertEquals(10, window.getHeight());
    assertEquals(10, window.getWidth());
    assertNull(window.getId());
    assertEquals(new DateTime(3L), house.getConstructedDate());
    assertEquals(XmlQNameEnumUtil.toQName(HouseType.brick), house.getType());
    assertEquals(XmlQNameEnumUtil.toQName(HouseStyle.latin), house.getStyle());
    assertEquals(XmlQNameEnumUtil.toURI(HouseColor.blue), house.getColor());

    // now let's check the nillable and required stuff:

    // roof is required, but nillable.
    clientHouse.setRoof(null);
    out = new ByteArrayOutputStream();
    clientMapper.writeValue(out, clientHouse);
    house = houseMapper.readValue(new ByteArrayInputStream(out.toByteArray()), House.class);
    base = house.getBase();
    assertSame(Color.BLUE, base.getColor());
    assertSame(LineStyle.solid, base.getLineStyle());
    assertEquals(80, base.getHeight());
    assertEquals(80, base.getWidth());
    assertEquals("baseid", base.getId());
    door = house.getDoor();
    assertSame(Color.YELLOW, door.getColor());
    assertSame(LineStyle.solid, door.getLineStyle());
    assertEquals(35, door.getHeight());
    assertEquals(20, door.getWidth());
    assertEquals("doorId", door.getId());
    knob = house.getDoorKnob();
    assertSame(Color.RED, knob.getColor());
    assertSame(LineStyle.dashed, knob.getLineStyle());
    assertEquals(2, knob.getRadius());
    assertEquals("knobId", knob.getId());
    labels = Arrays.asList("bachelor-pad", "single-family-dwelling");
    house.getLabels().size();
    for (Object l : house.getLabels()) {
      Label label = (Label) l;
      assertTrue(labels.contains(label.getValue()));
    }
    roof = house.getRoof();
    assertNull(roof);
    assertEquals(1, house.getWindows().size());
    window = house.getWindows().get(0);
    assertSame(Color.YELLOW, window.getColor());
    assertSame(LineStyle.solid, window.getLineStyle());
    assertEquals(10, window.getHeight());
    assertEquals(10, window.getWidth());
    assertNull(window.getId());

    // windows are nillable...
    clientHouse.setWindows(null);
    out = new ByteArrayOutputStream();
    clientMapper.writeValue(out, clientHouse);
    house = houseMapper.readValue(new ByteArrayInputStream(out.toByteArray()), House.class);
    base = house.getBase();
    assertSame(Color.BLUE, base.getColor());
    assertSame(LineStyle.solid, base.getLineStyle());
    assertEquals(80, base.getHeight());
    assertEquals(80, base.getWidth());
    assertEquals("baseid", base.getId());
    door = house.getDoor();
    assertSame(Color.YELLOW, door.getColor());
    assertSame(LineStyle.solid, door.getLineStyle());
    assertEquals(35, door.getHeight());
    assertEquals(20, door.getWidth());
    assertEquals("doorId", door.getId());
    knob = house.getDoorKnob();
    assertSame(Color.RED, knob.getColor());
    assertSame(LineStyle.dashed, knob.getLineStyle());
    assertEquals(2, knob.getRadius());
    assertEquals("knobId", knob.getId());
    labels = Arrays.asList("bachelor-pad", "single-family-dwelling");
    house.getLabels().size();
    for (Object l : house.getLabels()) {
      Label label = (Label) l;
      assertTrue(labels.contains(label.getValue()));
    }
    roof = house.getRoof();
    assertNull(roof);
    assertNull(house.getWindows());
  }