/**
   * Tests {@link TriggerContextConverter#marshal(Object,
   * com.thoughtworks.xstream.io.HierarchicalStreamWriter,
   * com.thoughtworks.xstream.converters.MarshallingContext)}. With an empty list of "others".
   *
   * @throws Exception if so.
   */
  @Test
  public void testMarshalNoOthers() throws Exception {
    TriggeredItemEntity entity = new TriggeredItemEntity(100, "projectX");

    PatchsetCreated event = Setup.createPatchsetCreated();
    TriggerContext context = new TriggerContext(event);
    context.setThisBuild(entity);
    context.setOthers(new LinkedList<TriggeredItemEntity>());

    TestMarshalClass t =
        new TestMarshalClass(context, "Bobby", new TestMarshalClass(context, "SomeoneElse"));

    XStream xStream = new XStream2();
    xStream.registerConverter(new TriggerContextConverter());
    String xml = xStream.toXML(t);

    TestMarshalClass readT = (TestMarshalClass) xStream.fromXML(xml);

    assertNotNull(readT.getEntity());
    assertNotNull(readT.getEntity().getEvent());
    assertNotNull(readT.getEntity().getThisBuild());

    assertEquals("project", readT.getEntity().getEvent().getChange().getProject());
    assertEquals(100, readT.getEntity().getThisBuild().getBuildNumber().intValue());
    assertEquals("projectX", readT.getEntity().getThisBuild().getProjectId());

    assertSame(readT.getEntity(), readT.getTestClass().getEntity());
  }
  @Override
  public TriggerResult onElement(Object element, long timestamp, W window, TriggerContext ctx)
      throws Exception {

    OperatorState<Boolean> first = ctx.getKeyValueState("first", true);

    if (first.value()) {
      long start = timestamp - (timestamp % interval);
      long nextFireTimestamp = start + interval;

      ctx.registerEventTimeTimer(nextFireTimestamp);

      first.update(false);
      return TriggerResult.CONTINUE;
    }
    return TriggerResult.CONTINUE;
  }
  /**
   * Tests {@link TriggerContextConverter#marshal(Object,
   * com.thoughtworks.xstream.io.HierarchicalStreamWriter,
   * com.thoughtworks.xstream.converters.MarshallingContext)}. With list of "others" containing two
   * items.
   *
   * @throws Exception if so.
   */
  @Test
  public void testMarshalWithOthers() throws Exception {
    TriggeredItemEntity entity = new TriggeredItemEntity(100, "projectX");

    PatchsetCreated event = Setup.createPatchsetCreated();
    TriggerContext context = new TriggerContext(event);
    context.setThisBuild(entity);
    LinkedList<TriggeredItemEntity> otherBuilds = new LinkedList<TriggeredItemEntity>();
    otherBuilds.add(new TriggeredItemEntity(1, "projectY"));
    otherBuilds.add(new TriggeredItemEntity(12, "projectZ"));
    context.setOthers(otherBuilds);

    TestMarshalClass t =
        new TestMarshalClass(context, "Bobby", new TestMarshalClass(context, "SomeoneElse"));

    XStream xStream = new XStream2();
    xStream.registerConverter(new TriggerContextConverter());
    String xml = xStream.toXML(t);

    TestMarshalClass readT = (TestMarshalClass) xStream.fromXML(xml);

    assertNotNull(readT.getEntity());
    assertNotNull(readT.getEntity().getEvent());
    assertNotNull(readT.getEntity().getThisBuild());
    assertNotNull(readT.getEntity().getOthers());

    assertEquals(2, readT.getEntity().getOthers().size());

    TriggeredItemEntity other = readT.getEntity().getOthers().get(0);
    assertEquals(1, other.getBuildNumber().intValue());
    assertEquals("projectY", other.getProjectId());

    other = readT.getEntity().getOthers().get(1);
    assertEquals(12, other.getBuildNumber().intValue());
    assertEquals("projectZ", other.getProjectId());
  }
  /**
   * Tests {@link
   * TriggerContextConverter#unmarshal(com.thoughtworks.xstream.io.HierarchicalStreamReader,
   * com.thoughtworks.xstream.converters.UnmarshallingContext)}. With "retriggerAction_oldData.xml"
   * as input.
   *
   * @throws Exception if so.
   */
  @Test
  public void testUnmarshalOldData1() throws Exception {
    XStream xStream = new XStream2();
    xStream.registerConverter(new TriggerContextConverter());
    Object obj = xStream.fromXML(getClass().getResourceAsStream("retriggerAction_oldData.xml"));
    assertTrue(obj instanceof RetriggerAction);
    RetriggerAction action = (RetriggerAction) obj;
    TriggerContext context = Whitebox.getInternalState(action, "context");
    assertNotNull(context.getEvent());
    assertEquals(
        "semctools/hudson/plugins/gerrit-trigger-plugin",
        context.getEvent().getChange().getProject());
    assertEquals("1", context.getEvent().getPatchSet().getNumber());

    assertNotNull(context.getThisBuild());
    assertEquals(6, context.getThisBuild().getBuildNumber().intValue());
    assertEquals("EXPERIMENTAL_Gerrit_Trigger_1", context.getThisBuild().getProjectId());

    assertNotNull(context.getOthers());
    assertEquals(1, context.getOthers().size());
    TriggeredItemEntity entity = context.getOthers().get(0);
    assertEquals(16, entity.getBuildNumber().intValue());
    assertEquals("EXPERIMENTAL_Gerrit_Trigger_2", entity.getProjectId());
  }
 @Override
 public TriggerResult onEventTime(long time, W window, TriggerContext ctx) {
   ctx.registerEventTimeTimer(time + interval);
   return TriggerResult.FIRE;
 }