/** We use the provided test workflow model form the AbstractWorkflowServiceTest */
  @Before
  public void setup() throws PluginException {

    super.setup();

    splitAndJoinPlugin = new SplitAndJoinPlugin();
    try {
      splitAndJoinPlugin.init(workflowService);
    } catch (PluginException e) {

      e.printStackTrace();
    }

    // prepare test workitem
    documentContext = new ItemCollection();
    logger.info("[TestAccessPlugin] setup test data...");
    Vector<String> list = new Vector<String>();
    list.add("manfred");
    list.add("anna");
    documentContext.replaceItemValue("namTeam", list);
    documentContext.replaceItemValue("namCreator", "ronny");
    documentContext.replaceItemValue(WorkflowKernel.MODELVERSION, "1.0.0");
    documentContext.replaceItemValue(WorkflowKernel.PROCESSID, 100);
    documentContext.replaceItemValue(WorkflowKernel.UNIQUEID, WorkflowKernel.generateUniqueID());
    entityService.save(documentContext);
  }
  /**
   * store history only if no error has occurred
   *
   * @throws
   */
  public void close(int status) throws PluginException {

    // restore changes if OK or WARNING
    if (status < Plugin.PLUGIN_ERROR) {
      if (vOldProt != null) documentContext.replaceItemValue("txtworkflowhistorylog", vOldProt);

      if (vOldProtRev != null)
        documentContext.replaceItemValue("txtworkflowhistorylogrev", vOldProtRev);
      Date date = new Date();
      // set timWorkflowLastAccess
      documentContext.replaceItemValue("timworkflowlastaccess", date);
    }
  }
  // @Ignore
  @Test
  public void testCreateSubProcessParsingError() {

    // create test result with a wrong end tag....
    String activityResult =
        "<item name=\"subprocess_create\"> "
            + "<modelversion>1.0.0</modelversion>"
            + "<processid>1000</processid>"
            + "<activityid>10</acttyid>"
            + "<items>namTeam</items>"
            + "</item>";
    try {
      documentActivity = this.getActivityEntity(100, 10);
      documentActivity.replaceItemValue("txtActivityResult", activityResult);
      splitAndJoinPlugin.run(documentContext, documentActivity);

      Assert.fail();
    } catch (PluginException e) {
      // Plugin exception is expected
      logger.info("Exprected exception message: " + e.getMessage());
      Assert.assertTrue(e.getMessage().startsWith("Parsing item content failed:"));
    }

    Assert.assertNotNull(documentContext);
  }
  /** Test update of an existing subprocess * */
  @SuppressWarnings("unchecked")
  @Test
  public void testUpdateSubProcess() {

    // 1.) create test subprocess.....
    String activityResult =
        "<item name=\"subprocess_create\"> "
            + "<modelversion>1.0.0</modelversion>"
            + "<processid>100</processid>"
            + "<activityid>10</activityid>"
            + "<items>namTeam</items>"
            + "</item>";
    try {
      documentActivity = this.getActivityEntity(100, 10);
      documentActivity.replaceItemValue("txtActivityResult", activityResult);
      splitAndJoinPlugin.run(documentContext, documentActivity);
    } catch (PluginException e) {

      e.printStackTrace();
      Assert.fail();
    }

    Assert.assertNotNull(documentContext);

    // load the new subprocess....
    List<String> workitemRefList = documentContext.getItemValue(SplitAndJoinPlugin.LINK_PROPERTY);
    Assert.assertEquals(1, workitemRefList.size());
    String subprocessUniqueid = workitemRefList.get(0);
    ItemCollection subprocess = this.entityService.load(subprocessUniqueid);
    Assert.assertNotNull(subprocess);
    Assert.assertEquals(100, subprocess.getProcessID());

    // 2.) now update the subprocess
    activityResult =
        "<item name=\"subprocess_update\"> "
            + "<modelversion>1.0.0</modelversion>"
            + "<processid>100</processid>"
            + "<activityid>30</activityid>"
            + "<items>namTeam</items>"
            + "</item>";
    try {
      documentActivity = this.getActivityEntity(100, 10);
      documentActivity.replaceItemValue("txtActivityResult", activityResult);
      splitAndJoinPlugin.run(documentContext, documentActivity);
    } catch (PluginException e) {

      e.printStackTrace();
      Assert.fail();
    }

    // now we load the subprocess and test if it was updated (new processiD
    // expected is 300)

    Assert.assertNotNull(documentContext);

    subprocess = this.entityService.load(subprocessUniqueid);
    Assert.assertNotNull(subprocess);
    Assert.assertEquals(300, subprocess.getProcessID());
  }
  /**
   * Test multi creation of subprocesses
   *
   * <p>*
   */
  @SuppressWarnings("unchecked")
  @Test
  public void testCreateMultiSubProcess() {

    // create test result with two subprocess creations.....
    String activityResult =
        "<item name=\"subprocess_create\"> "
            + "<modelversion>1.0.0</modelversion>"
            + "<processid>100</processid>"
            + "<activityid>10</activityid>"
            + "<items>namTeam</items>"
            + "</item>";

    // second subprocess....
    activityResult +=
        "<item name=\"subprocess_create\"> "
            + "<modelversion>1.0.0</modelversion>"
            + "<processid>100</processid>"
            + "<activityid>20</activityid>"
            + "<items>namTeam</items>"
            + "</item>";

    try {
      documentActivity = this.getActivityEntity(100, 10);
      documentActivity.replaceItemValue("txtActivityResult", activityResult);
      splitAndJoinPlugin.run(documentContext, documentActivity);
    } catch (PluginException e) {

      e.printStackTrace();
      Assert.fail();
    }

    Assert.assertNotNull(documentContext);

    List<String> workitemRefList = documentContext.getItemValue(SplitAndJoinPlugin.LINK_PROPERTY);

    // two subprocesses should be created...
    Assert.assertEquals(2, workitemRefList.size());

    // test first subprocess instance...
    String subprocessUniqueid = workitemRefList.get(0);
    ItemCollection subprocess = this.entityService.load(subprocessUniqueid);
    Assert.assertNotNull(subprocess);
    Assert.assertEquals(100, subprocess.getProcessID());
    logger.info("Created Subprocess UniqueID=" + subprocess.getUniqueID());

    // test second subprocess instance... 100.20 -> $processId=200
    subprocessUniqueid = workitemRefList.get(1);
    subprocess = this.entityService.load(subprocessUniqueid);
    Assert.assertNotNull(subprocess);
    Assert.assertEquals(200, subprocess.getProcessID());
    logger.info("Created Subprocess UniqueID=" + subprocess.getUniqueID());
  }
  /** Test creation of subprocess * */
  @SuppressWarnings("unchecked")
  @Test
  public void testCreateSubProcess() {

    // create test result.....
    String activityResult =
        "<item name=\"subprocess_create\"> "
            + "<modelversion>1.0.0</modelversion>"
            + "<processid>100</processid>"
            + "<activityid>10</activityid>"
            + "<items>namTeam</items>"
            + "</item>";

    try {
      documentActivity = this.getActivityEntity(100, 10);
      documentActivity.replaceItemValue("txtActivityResult", activityResult);
      splitAndJoinPlugin.run(documentContext, documentActivity);
    } catch (PluginException e) {

      e.printStackTrace();
      Assert.fail();
    }

    Assert.assertNotNull(documentContext);

    List<String> workitemRefList = documentContext.getItemValue(SplitAndJoinPlugin.LINK_PROPERTY);

    Assert.assertEquals(1, workitemRefList.size());

    String subprocessUniqueid = workitemRefList.get(0);

    // get the subprocess...
    ItemCollection subprocess = this.entityService.load(subprocessUniqueid);

    // test data in subprocess
    Assert.assertNotNull(subprocess);

    Assert.assertEquals(100, subprocess.getProcessID());

    logger.info("Created Subprocess UniqueID=" + subprocess.getUniqueID());

    // test if the field namTeam is available
    List<String> team = subprocess.getItemValue("namTeam");
    Assert.assertEquals(2, team.size());
    Assert.assertTrue(team.contains("manfred"));
    Assert.assertTrue(team.contains("anna"));
  }
  @SuppressWarnings("unchecked")
  public int run(ItemCollection adocumentContext, ItemCollection adocumentActivity)
      throws PluginException {
    String rtfItemResult;

    documentContext = adocumentContext;
    documentActivity = adocumentActivity;

    // Logtext aus Resultdocument lesen
    rtfItemResult = documentActivity.getItemValueString("rtfresultlog");
    String aProtokoll = rtfItemResult;

    String sDatumsFormat = documentActivity.getItemValueString("keyLogDateFormat");

    if (sDatumsFormat == null || "".equals(sDatumsFormat)) sDatumsFormat = "1";
    String sZeitFormat = documentActivity.getItemValueString("keylogtimeformat");
    if (sZeitFormat == null || "".equals(sZeitFormat)) sZeitFormat = "2";

    logger.fine("[HistoryPlugin] logtimeformat=" + sZeitFormat);
    logger.fine("[HistoryPlugin] logdateformat=" + sDatumsFormat);

    // get Time Date format...
    int iDatumsFormat = -1;
    int iZeitFormat = -1;
    try {
      iDatumsFormat = Integer.parseInt(sDatumsFormat);
      iZeitFormat = Integer.parseInt(sZeitFormat);
    } catch (NumberFormatException nfe) {
      // invalid DateTime format found
      logger.fine("[HistoryPlugin] undefined logtimeformat " + nfe.toString());
    }

    String sTim = "";
    if ((iZeitFormat > -1) && (iDatumsFormat > -1)) {
      sTim = DateFormat.getDateTimeInstance(iDatumsFormat, iZeitFormat).format(new Date());
    } else {
      if ((iZeitFormat == -1) && (iDatumsFormat > -1))
        sTim = DateFormat.getDateInstance(iDatumsFormat).format(new Date());
      else if ((iZeitFormat > -1) && (iDatumsFormat == -1))
        sTim = DateFormat.getTimeInstance(iZeitFormat).format(new Date());
    }

    // Check if a text was found. Protocol will only be added if text
    // was defined
    if (!"".equals(aProtokoll)) {
      String sDoppelpunkt = "";
      if ((!"".equals(sTim)) && (!"".equals(aProtokoll))) sDoppelpunkt = " : ";
      aProtokoll = sTim + sDoppelpunkt + aProtokoll;

      aProtokoll = replaceDynamicValues(aProtokoll, documentContext);

      vOldProt = documentContext.getItemValue("txtworkflowhistorylog");
      vOldProtRev = documentContext.getItemValue("txtworkflowhistorylogrev");

      vOldProt.add(aProtokoll);
      vOldProtRev.add(0, aProtokoll);

      // check if maximum length of log is defined
      int iMaxLogLength = documentContext.getItemValueInteger("numworkflowhistoryLength");
      if (iMaxLogLength > 0) {
        while (vOldProt.size() > iMaxLogLength) vOldProt.remove(0);

        while (vOldProtRev.size() > iMaxLogLength) vOldProtRev.remove(vOldProtRev.size() - 1);
      }
    }

    return Plugin.PLUGIN_OK;
  }
  /**
   * Test update origin
   *
   * <p>First we create a subprocess and in a secon step we test if the subprocess can update the
   * origin workitem.
   */
  @SuppressWarnings("unchecked")
  @Test
  public void testUpdateOriginProcess() {

    String orignUniqueID = documentContext.getUniqueID();

    /*
     * 1.) create test result for new subprcoess.....
     */
    String activityResult =
        "<item name=\"subprocess_create\"> "
            + "<modelversion>1.0.0</modelversion>"
            + "<processid>100</processid>"
            + "<activityid>10</activityid>"
            + "<items>namTeam</items>"
            + "</item>";
    try {
      documentActivity = this.getActivityEntity(100, 10);
      documentActivity.replaceItemValue("txtActivityResult", activityResult);

      splitAndJoinPlugin.run(documentContext, documentActivity);
    } catch (PluginException e) {
      e.printStackTrace();
      Assert.fail();
    }
    Assert.assertNotNull(documentContext);

    // now load the subprocess
    List<String> workitemRefList = documentContext.getItemValue(SplitAndJoinPlugin.LINK_PROPERTY);
    String subprocessUniqueid = workitemRefList.get(0);
    ItemCollection subprocess = this.entityService.load(subprocessUniqueid);

    // test data in subprocess
    Assert.assertNotNull(subprocess);
    Assert.assertEquals(100, subprocess.getProcessID());

    /*
     * 2.) process the subprocess to test if the origin process will be
     * updated correctly
     */
    activityResult =
        "<item name=\"origin_update\"> "
            + "<modelversion>1.0.0</modelversion>"
            + "<processid>100</processid>"
            + "<activityid>20</activityid>"
            + "<items>namTeam,_sub_data</items>"
            + "</item>";

    // add some custom data
    subprocess.replaceItemValue("_sub_data", "some test data");
    // now we process the subprocess
    try {
      documentActivity = this.getActivityEntity(100, 10);
      documentActivity.replaceItemValue("txtActivityResult", activityResult);
      splitAndJoinPlugin.run(subprocess, documentActivity);
    } catch (PluginException e) {
      e.printStackTrace();
      Assert.fail();
    }

    // load origin document
    documentContext = entityService.load(orignUniqueID);
    Assert.assertNotNull(documentContext);

    // test data.... (new $processId=200 and _sub_data from subprocess
    Assert.assertEquals(200, documentContext.getProcessID());
    Assert.assertEquals("some test data", documentContext.getItemValueString("_sub_data"));
  }