/**
   * Executes the workflow for the given representation files.
   *
   * @param workflowFile the workflow File.
   * @param representationID the representation ID.
   * @param fileIDs the file IDs.
   * @return a {@link ReportItem} with details from the execution of the workflow in the
   *     representation.
   */
  private ReportItem executeWorkflowInRepresentation(
      final File workflowFile, final String representationID, final List<String> fileIDs) {

    final ReportItem reportItem = new ReportItem(representationID);
    reportItem.addAttribute(new Attribute("Start datetime", DateParser.getIsoDate(new Date())));

    int fileCount = 0;

    try {

      final Map<String, WorkflowExecutionOutput> outputs =
          new HashMap<String, ExecutePlanPlugin.WorkflowExecutionOutput>();
      for (String fileID : fileIDs) {
        outputs.put(fileID, executeWorkflowInFile(workflowFile, representationID, fileID));
        fileCount++;
      }

      // Create new representation with the outputs
      logger.warn("Need to create new representation from outputs " + outputs);

      String roPID = createDerivedRepresentation(representationID, outputs, reportItem);

      // remove temporary files
      for (String fileID : fileIDs) {

        final WorkflowExecutionOutput output = outputs.get(fileID);

        final File outputDirFile = new File(output.outputDir);

        if (FileUtils.deleteQuietly(outputDirFile)) {
          logger.debug("Deleted temporary directory " + outputDirFile);
        } else {
          logger.warn("Error deleting temporary directory " + outputDirFile);
        }
      }

      reportItem.addAttribute(new Attribute("Successful", "yes"));
      reportItem.addAttribute(
          new Attribute("Files successfuly processed", new Integer(fileCount).toString()));
      reportItem.addAttribute(new Attribute("Finish datetime", DateParser.getIsoDate(new Date())));

    } catch (ExecutePlanException e) {
      logger.error(
          "Error executing workflow on files of representation "
              + representationID
              + " - "
              + e.getMessage());

      reportItem.addAttribute(new Attribute("Successful", "no"));
      reportItem.addAttribute(
          new Attribute("Files successfuly processed", new Integer(fileCount).toString()));
      reportItem.addAttribute(new Attribute("Error", e.getMessage()));
      reportItem.addAttribute(new Attribute("Finish datetime", DateParser.getIsoDate(new Date())));
    }

    return reportItem;
  }
  /**
   * Executes the plugin.
   *
   * @return The execution {@link Report}
   * @throws PluginException if an error occurred during execution.
   * @see Plugin#execute()
   */
  public Report execute() throws PluginException {

    initClientServices();

    final Report report = new Report();
    report.setType(Report.TYPE_PLUGIN_REPORT);
    report.setTitle("Report of plugin " + getName());
    report.setAttributes(
        new Attribute[] {
          new Attribute("Agent name", getName()),
          new Attribute("Agent version", Float.toString(getVersion())),
          new Attribute("Start datetime", DateParser.getIsoDate(new Date()))
        });

    try {

      final Document plan = getPlanDocument(planFile);

      final List<String> fileURLs = getFileURLsFromPlan(plan);
      logger.debug("File URLs from plan: " + fileURLs);

      report.addAttribute(
          new Attribute("Number of files", new Integer(fileURLs.size()).toString()));

      final Map<String, List<String>> representationFiles = groupFileIDsByRepresentation(fileURLs);
      logger.debug("representationFiles: " + representationFiles);

      report.addAttribute(
          new Attribute(
              "Number of representations", new Integer(representationFiles.size()).toString()));

      final File workflowFile = getWorkflowFile(plan);
      logger.debug("Workflow file: " + workflowFile);

      executeWorkflowInAllRepresentations(workflowFile, representationFiles, report);

      report.addAttribute(new Attribute("Successful", "yes"));
      report.addAttribute(new Attribute("Finish datetime", DateParser.getIsoDate(new Date())));

      // Report for the execution of this Plugin
      return report;

    } catch (PluginException e) {
      logger.error("Error executing plugin - " + e.getMessage(), e);
      logger.info("Setting report in exception and re-throwing");

      report.addAttribute(new Attribute("Successful", "no"));
      report.addAttribute(new Attribute("Error", e.getMessage()));
      report.addAttribute(new Attribute("Finish datetime", DateParser.getIsoDate(new Date())));

      e.setReport(report);

      throw e;
    }
  }
示例#3
0
 private void writeTaskProperties(
     TransformerHandler handler, CustomPropertyManager customPropertyManager) throws SAXException {
   writeTaskProperty(handler, "tpd0", "type", "default", "icon");
   writeTaskProperty(handler, "tpd1", "priority", "default", "icon");
   writeTaskProperty(handler, "tpd2", "info", "default", "icon");
   writeTaskProperty(handler, "tpd3", "name", "default", "text");
   writeTaskProperty(handler, "tpd4", "begindate", "default", "date");
   writeTaskProperty(handler, "tpd5", "enddate", "default", "date");
   writeTaskProperty(handler, "tpd6", "duration", "default", "int");
   writeTaskProperty(handler, "tpd7", "completion", "default", "int");
   writeTaskProperty(handler, "tpd8", "coordinator", "default", "text");
   writeTaskProperty(handler, "tpd9", "predecessorsr", "default", "text");
   for (CustomPropertyDefinition cc : customPropertyManager.getDefinitions()) {
     Object defVal = cc.getDefaultValue();
     final Class<?> cla = cc.getType();
     final String valueType = encodeFieldType(cla);
     if (valueType == null) {
       continue;
     }
     if ("date".equals(valueType) && defVal != null) {
       if (defVal instanceof GanttCalendar) {
         defVal = DateParser.getIsoDate(((GanttCalendar) defVal).getTime());
       } else if (defVal instanceof Date) {
         defVal = DateParser.getIsoDate((Date) defVal);
       } else {
         assert false
             : "Default value is expected to be either GanttCalendar or Date instance, while it is "
                 + defVal.getClass();
       }
     }
     String idcStr = cc.getID();
     writeTaskProperty(
         handler,
         idcStr,
         cc.getName(),
         "custom",
         valueType,
         defVal == null ? null : String.valueOf(defVal));
   }
 }
  /**
   * @throws Exception
   * @see DescriptionTraverserAgent#apply(SimpleDescriptionObject, List)
   */
  public AccessRestrictNotifierResult apply(
      SimpleDescriptionObject sdo, List<AccessRestrictNotifierResult> childResults)
      throws Exception {

    AccessRestrictNotifierResult result = new AccessRestrictNotifierResult();

    if (childResults != null) {
      // Add the results from the children
      for (AccessRestrictNotifierResult childResult : childResults) {
        if (childResult.getDescriptionObjects().size() > 0) {
          result.addDescriptionObjects(childResult.getDescriptionObjects());
        }
      }
    }

    if (sdo.getSubElementsCount() == 0
        && (sdo.getLevel().equals(DescriptionLevel.FILE)
            || sdo.getLevel().equals(DescriptionLevel.ITEM))) {

      DescriptionObject descriptionObject = browserService.getDescriptionObject(sdo.getPid());

      String accessrestrict = descriptionObject.getAccessrestrict();

      if (!StringUtils.isBlank(accessrestrict)) {

        Date currentDate = new Date();

        Date representationDate = DateParser.parse(descriptionObject.getDateFinal());

        Calendar representationCalendar = Calendar.getInstance();
        representationCalendar.setTime(representationDate);

        if (accessrestrict.toLowerCase().startsWith("segredo de estado")) {

          // segredo de estado => 25 years
          representationCalendar.add(Calendar.YEAR, 25);

        } else if (accessrestrict.equalsIgnoreCase("Dados pessoais")) {

          // Dados pessoais => 75 years
          representationCalendar.add(Calendar.YEAR, 75);

        } else if (accessrestrict.equalsIgnoreCase("Dados sensíveis de pessoas colectivas")) {

          // Dados sensíveis de pessoas colectivas => 50 years
          representationCalendar.add(Calendar.YEAR, 50);

        } else {
          logger.warn(
              "DO "
                  + sdo.getPid()
                  + " accessrestrict '"
                  + accessrestrict
                  + "' is not a recognized value.");
          representationCalendar = null;
        }

        if (representationCalendar != null
            && currentDate.compareTo(representationCalendar.getTime()) > 0) {
          result.addDescriptionObject(descriptionObject);
        }

      } else {
        // DO doesn't have accessrestrict value
      }
    }

    return result;
  }
  private ReportItem executeOn(String representationPID) throws PluginException {

    ReportItem reportItem = new ReportItem("Convertion of representation " + representationPID);
    reportItem.addAttribute(new Attribute("start datetime", DateParser.getIsoDate(new Date())));

    RepresentationObject originalRObject = null;
    try {

      reportItem.addAttribute(
          new Attribute(
              "Download original representation - start datetime",
              DateParser.getIsoDate(new Date())));

      // Get original representation from RODA Core
      originalRObject = this.browserService.getRepresentationObject(representationPID);

      logger.info("Original representation is " + originalRObject);

      reportItem.addAttribute(
          new Attribute(
              "Download original representation - finnish datetime",
              DateParser.getIsoDate(new Date())));

    } catch (BrowserException e) {
      logger.debug(
          "Error accessing representation " + representationPID + " - " + e.getMessage(), e);
      throw new PluginException(
          "Error accessing representation " + representationPID + " - " + e.getMessage(),
          e,
          reportItem);
    } catch (NoSuchRODAObjectException e) {
      logger.debug(
          "Error accessing representation " + representationPID + " - " + e.getMessage(), e);
      throw new PluginException(
          "Error accessing representation " + representationPID + " - " + e.getMessage(),
          e,
          reportItem);
    } catch (RemoteException e) {
      logger.debug(
          "Error accessing representation " + representationPID + " - " + e.getMessage(), e);
      throw new PluginException(
          "Error accessing representation " + representationPID + " - " + e.getMessage(),
          e,
          reportItem);
    }

    // Download representation files and verify if the files are already
    // normalised

    if (isRepresentationConverted(originalRObject)) {
      // No need to call the convert plugin

      try {

        String normalizedROPID =
            this.ingestService.setDONormalizedRepresentation(
                originalRObject.getDescriptionObjectPID(), originalRObject.getPid());

        logger.info(
            "Marked representation "
                + normalizedROPID //$NON-NLS-1$
                + " as normalized"); //$NON-NLS-1$

        reportItem.addAttributes(
            new Attribute("Action", "Representation was marked as normalized"));

      } catch (NoSuchRODAObjectException e) {
        reportItem.addAttributes(
            new Attribute(
                "Error",
                "Error setting representation status to normalized (" + e.getMessage() + ")"));
        throw new PluginException(
            "Error setting representation status to normalized - " + e.getMessage(), e, reportItem);
      } catch (IngestException e) {
        reportItem.addAttributes(
            new Attribute(
                "Error",
                "Error setting representation status to normalized (" + e.getMessage() + ")"));
        throw new PluginException(
            "Error setting representation status to normalized - " + e.getMessage(), e, reportItem);
      } catch (RemoteException e) {
        RODAException exception = RODAClient.parseRemoteException(e);
        reportItem.addAttributes(
            new Attribute(
                "Error",
                "Error setting representation status to normalized (" + e.getMessage() + ")"));
        throw new PluginException(
            "Error setting representation status to normalized - " + exception.getMessage(),
            exception,
            reportItem);
      }

      reportItem.addAttributes(
          new Attribute("finnish datetime", DateParser.getIsoDate(new Date())));

      return reportItem;

    } else {

      // Representation is not normalized and we need to call the
      // converter. Continue...

    }

    ConversionResult convertResult = null;
    RepresentationObject convertedRObject = null;
    try {

      reportItem.addAttribute(
          new Attribute("Conversion - start datetime", DateParser.getIsoDate(new Date())));

      logger.info("Converting representation " + originalRObject.getPid());

      // Calling converter
      convertResult = convert(originalRObject);
      convertedRObject = convertResult.getRepresentation();

      logger.info("Convert " + originalRObject.getPid() + " finished");

      reportItem.addAttribute(
          new Attribute("Conversion - finnish datetime", DateParser.getIsoDate(new Date())));
      reportItem.addAttribute(
          new Attribute(
              "Conversion - converted representation",
              convertResult.getRepresentation().toString()));

      if (convertResult.getMigrationEvent() == null) {

        logger.warn("Migration event is null");

      } else {

        logger.info(
            "Conversion outcome is "
                + convertResult.getMigrationEvent().getOutcomeDetailExtension());

        logger.info("Converted representation is " + convertedRObject);

        reportItem.addAttribute(
            new Attribute(
                "Conversion - outcome details",
                convertResult.getMigrationEvent().getOutcomeDetailExtension()));
      }

    } catch (RepresentationConverterException e) {
      logger.debug(
          "Error converting representation " + representationPID + " - " + e.getMessage(), e);
      e.setReportItem(reportItem);
      throw e;
    }

    RepresentationObject writtenRO = null;
    String roPID = null;
    try {

      // Create temporary directory
      File temporaryDirectory = TempDir.createUniqueTemporaryDirectory("rep");

      reportItem.addAttributes(
          new Attribute(
              "Download converted representation - temporary directory",
              temporaryDirectory.toString()),
          new Attribute(
              "Download converted representation - start datetime",
              DateParser.getIsoDate(new Date())));

      logger.info("Writting converted representation to " + temporaryDirectory);

      // Write representation to temporary directory
      writtenRO =
          this.migratorClient.writeRepresentationObject(convertedRObject, temporaryDirectory);

      logger.info("Representation written");

      reportItem.addAttribute(
          new Attribute(
              "Download converted representation - finnish datetime",
              DateParser.getIsoDate(new Date())));

      reportItem.addAttribute(
          new Attribute("Ingest - start datetime", DateParser.getIsoDate(new Date())));

      logger.info("Ingesting converted representation");

      if (isNormalization()) {
        logger.info(
            "This is a normalization process. Setting representation status to "
                + RepresentationObject.STATUS_NORMALIZED);
        writtenRO.setStatuses(new String[] {RepresentationObject.STATUS_NORMALIZED});
      } else {
        logger.info(
            "This is NOT a normalization process. Setting representation status to "
                + RepresentationObject.STATUS_ALTERNATIVE);
        writtenRO.setStatuses(new String[] {RepresentationObject.STATUS_ALTERNATIVE});
      }

      // Ingest converted representation
      roPID = ingestRepresentation(writtenRO);

      logger.info("Representation ingested with PID " + roPID);

      reportItem.addAttribute(
          new Attribute("Ingest - finnish datetime", DateParser.getIsoDate(new Date())));
      reportItem.addAttribute(new Attribute("Ingest - ingested representation PID", roPID));

    } catch (MigratorClientException e) {
      logger.debug("Error downloading converted representation - " + e.getMessage(), e);
      throw new PluginException(
          "Error downloading converted representation  - " + e.getMessage(), e, reportItem);
    } catch (IOException e) {
      logger.debug("Error downloading converted representation - " + e.getMessage(), e);
      throw new PluginException(
          "Error downloading converted representation  - " + e.getMessage(), e, reportItem);
    } catch (IngestException e) {
      logger.debug("Error downloading converted representation - " + e.getMessage(), e);
      throw new PluginException(
          "Error downloading converted representation  - " + e.getMessage(), e, reportItem);
    }

    AgentPreservationObject agentPO = null;
    try {

      logger.info("Registering derivation event");

      reportItem.addAttribute(
          new Attribute("Register event - start datetime", DateParser.getIsoDate(new Date())));

      // Getting converter Agent
      AgentPreservationObject migratorAgent = getConverter().getAgent();

      reportItem.addAttribute(
          new Attribute("Register event - converter agent", migratorAgent.toString()));

      agentPO = new AgentPreservationObject();
      agentPO.setAgentType(AgentPreservationObject.PRESERVATION_AGENT_TYPE_MIGRATOR);
      agentPO.setAgentName(getName() + "/" + getVersion() + " - " + migratorAgent.getAgentName());

      logger.info("Agent is " + agentPO);

      reportItem.addAttribute(new Attribute("Register event - event agent", agentPO.toString()));

    } catch (Exception e) {
      // getConverter().getAgent();
      logger.debug("Error getting converter agent - " + e.getMessage(), e);

      // Delete roPID
      // delete(roPID);
      // try {
      // logger
      // .warn("Ingest of new representation failed. Removing created object "
      // + roPID);
      //
      // this.ingestService.removeObjects(new String[] { roPID });
      //
      // } catch (RemoteException e1) {
      // logger.warn("Error removing representation " + roPID + " - "
      // + e1.getMessage() + ". IGNORING", e1);
      // }

      throw new PluginException("Error getting converter agent - " + e.getMessage(), e, reportItem);
    }

    try {

      EventPreservationObject eventPO = convertResult.getMigrationEvent();

      if (eventPO == null) {
        eventPO = new EventPreservationObject();
      }

      if (isNormalization()) {
        eventPO.setEventType(EventPreservationObject.PRESERVATION_EVENT_TYPE_NORMALIZATION);
      } else {
        eventPO.setEventType(EventPreservationObject.PRESERVATION_EVENT_TYPE_MIGRATION);
      }
      if (StringUtils.isBlank(eventPO.getOutcome())) {
        eventPO.setOutcome("success");
      }
      if (StringUtils.isBlank(eventPO.getOutcomeDetailNote())) {
        eventPO.setOutcomeDetailNote("Converter details");
      }
      if (StringUtils.isBlank(eventPO.getOutcomeDetailExtension())) {
        eventPO.setOutcomeDetailExtension("no details");
      }

      logger.info("Event is " + eventPO);

      // reportItem.addAttribute(new Attribute(
      // "Register event - event outcome details", eventPO
      // .getOutcomeDetailExtension()));

      logger.info("Calling registerDerivationEvent(...)");

      // Register derivation event
      String epoPID =
          this.ingestService.registerDerivationEvent(
              originalRObject.getPid(), roPID, eventPO, agentPO, getParameterMakeObjectsActive());

      logger.info("Event registration finnished. Derivation event is " + epoPID);

      reportItem.addAttributes(
          new Attribute("Register event - event PID", epoPID),
          new Attribute("finnish datetime", DateParser.getIsoDate(new Date())));

      return reportItem;

    } catch (NoSuchRODAObjectException e) {
      // registerDerivationEvent(...)
      logger.debug("Error registering convertion event - " + e.getMessage(), e);
      throw new PluginException(
          "Error registering convertion event - " + e.getMessage(), e, reportItem);
    } catch (IngestException e) {
      // registerDerivationEvent(...)
      logger.debug("Error registering convertion event - " + e.getMessage(), e);
      throw new PluginException(
          "Error registering convertion event - " + e.getMessage(), e, reportItem);
    } catch (RemoteException e) {
      // registerDerivationEvent(...)
      logger.debug("Error registering convertion event - " + e.getMessage(), e);
      throw new PluginException(
          "Error registering convertion event - " + e.getMessage(), e, reportItem);
    }
  }
  /** @see Plugin#execute() */
  public Report execute() throws PluginException {

    Report executionReport = new Report();
    executionReport.setType(Report.TYPE_PLUGIN_REPORT);
    executionReport.setTitle(
        "Plugin " + getName() + " (version " + getVersion() + ") execution report.");
    executionReport.addAttribute(
        new Attribute("Start datetime", DateParser.getIsoDate(new Date())));

    // Creates RODAClient, Uploader Browser and Ingest
    initClientServices();

    boolean terminated = false;
    String representationPID;
    try {

      representationPID = getNextRepresentationPID();
      terminated = representationPID == null;

      logger.info("next representation is " + representationPID + ". terminated=" + terminated);

    } catch (RODAException e) {
      logger.debug("Error getting next representation PID - " + e.getMessage(), e);

      executionReport.addAttribute(new Attribute("Error", e.getMessage()));
      executionReport.addAttribute(
          new Attribute("Finish datetime", DateParser.getIsoDate(new Date())));

      throw new PluginException(
          "Error getting next representation PID - " + e.getMessage(), e, executionReport);
    }

    while (!terminated) {

      try {

        ReportItem reportItem = executeOn(representationPID);

        logger.info("adding ReportItem for representation " + representationPID + " " + reportItem);

        executionReport.addItem(reportItem);

      } catch (PluginException e) {

        logger.debug(
            "Error converting representation " + representationPID + " - " + e.getMessage(), e);

        if (e.getReportItem() != null) {

          ReportItem reportItem = e.getReportItem();

          reportItem.addAttribute(new Attribute("Error", e.getMessage()));

          reportItem.addAttribute(
              new Attribute("Finish datetime", DateParser.getIsoDate(new Date())));

          executionReport.addItem(e.getReportItem());
        }

        if (getParameterFailAtFirstError()) {

          throw new MigratorPluginException(
              "Error executing migration - " + e.getMessage(), e, executionReport);
        }
      }

      addConvertedRepresentationPID(representationPID);

      try {

        representationPID = getNextRepresentationPID();
        terminated = representationPID == null;

        logger.info("next representation is " + representationPID + ". terminated=" + terminated);

      } catch (RODAException e) {
        logger.debug("Error getting next representation PID - " + e.getMessage(), e);

        executionReport.addAttribute(new Attribute("Error", e.getMessage()));
        executionReport.addAttribute(
            new Attribute("Finish datetime", DateParser.getIsoDate(new Date())));

        throw new PluginException(
            "Error getting next representation PID - " + e.getMessage(), e, executionReport);
      }
    }

    executionReport.addAttribute(
        new Attribute("Finish datetime", DateParser.getIsoDate(new Date())));

    return executionReport;
  }
示例#7
0
  private void writeTask(
      TransformerHandler handler, GanttTask task, CustomPropertyManager customPropertyManager)
      throws SAXException, IOException {
    if (task.getTaskID() == -1) {
      throw new IllegalArgumentException("Is it a fake root task? Task=" + task);
    }
    AttributesImpl attrs = new AttributesImpl();
    addAttribute("id", String.valueOf(task.getTaskID()), attrs);
    addAttribute("name", task.getName(), attrs);
    if (task.colorDefined()) {
      addAttribute("color", ColorConvertion.getColor(task.getColor()), attrs);
    }
    if (task.shapeDefined()) {
      addAttribute("shape", task.getShape().getArray(), attrs);
    }
    addAttribute("meeting", Boolean.valueOf(task.isLegacyMilestone()).toString(), attrs);
    if (task.isProjectTask()) {
      addAttribute("project", Boolean.TRUE.toString(), attrs);
    }
    addAttribute("start", task.getStart().toXMLString(), attrs);
    addAttribute("duration", String.valueOf(task.getLength()), attrs);
    addAttribute("complete", String.valueOf(task.getCompletionPercentage()), attrs);
    if (task.getThird() != null) {
      addAttribute("thirdDate", task.getThird().toXMLString(), attrs);
      addAttribute("thirdDate-constraint", String.valueOf(task.getThirdDateConstraint()), attrs);
    }
    if (task.getPriority() != Task.DEFAULT_PRIORITY) {
      addAttribute("priority", task.getPriority().getPersistentValue(), attrs);
    }
    final String sWebLink = task.getWebLink();
    if (sWebLink != null && !sWebLink.equals("") && !sWebLink.equals("http://")) {
      addAttribute("webLink", URLEncoder.encode(sWebLink, "ISO-8859-1"), attrs);
    }
    addAttribute("expand", String.valueOf(task.getExpand()), attrs);

    startElement("task", attrs, handler);

    if (task.getNotes() != null && task.getNotes().length() > 0) {
      cdataElement("notes", task.getNotes(), attrs, handler);
      // fout.write(space2 + "<notes>");
      // fout.write("\n"
      // + space2
      // + s
      // + correct(replaceAll(task.getNotes(), "\n", "\n"
      // + space2 + s)));
      // fout.write("\n" + space2 + "</notes>\n");
    }
    // use successors to write depends information
    final TaskDependency[] depsAsDependee = task.getDependenciesAsDependee().toArray();
    for (int i = 0; i < depsAsDependee.length; i++) {
      TaskDependency next = depsAsDependee[i];
      addAttribute("id", String.valueOf(next.getDependant().getTaskID()), attrs);
      addAttribute("type", next.getConstraint().getType().getPersistentValue(), attrs);
      addAttribute("difference", String.valueOf(next.getDifference()), attrs);
      addAttribute("hardness", next.getHardness().getIdentifier(), attrs);
      emptyElement("depend", attrs, handler);
    }

    CustomColumnsValues ccv = task.getCustomValues();
    for (CustomPropertyDefinition def : customPropertyManager.getDefinitions()) {
      final String idc = def.getID();
      if (ccv.hasOwnValue(def)) {
        Object value = ccv.getValue(def);
        if (GregorianCalendar.class.isAssignableFrom(def.getType()) && value != null) {
          value = DateParser.getIsoDate(((GanttCalendar) value).getTime());
        }
        addAttribute("taskproperty-id", idc, attrs);
        addAttribute("value", value == null ? null : String.valueOf(value), attrs);
        emptyElement("customproperty", attrs, handler);
      }
    }

    // Write the child of the task
    if (task.getManager().getTaskHierarchy().hasNestedTasks(task)) {
      Task[] nestedTasks = task.getManager().getTaskHierarchy().getNestedTasks(task);
      for (int i = 0; i < nestedTasks.length; i++) {
        writeTask(handler, (GanttTask) nestedTasks[i], customPropertyManager);
      }
    }

    // end of task section
    endElement("task", handler);
  }
  private String createDerivedRepresentation(
      final String roPID,
      final Map<String, WorkflowExecutionOutput> outputs,
      final ReportItem reportItem)
      throws ExecutePlanException {

    logger.trace(String.format("createNewRepresentation(%s, %s)", roPID, outputs));

    RepresentationObject roOriginal = null;
    LocalRepresentationObject roLocalDerived = null;
    final StringBuilder sbExecDetails = new StringBuilder();

    try {

      roOriginal = rodaClient.getBrowserService().getRepresentationObject(roPID);

      roLocalDerived = downloadRepresentationToLocalDisk(roOriginal);
      roLocalDerived.setId(DateParser.getIsoDate(new Date()));
      roLocalDerived.setStatuses(new String[] {RepresentationObject.STATUS_NORMALIZED});

      sbExecDetails.append(
          String.format("<planExecutionDetails plan=\"%s\">%n", planFile.getName()));

      // Check if root file was changed
      if (outputs.containsKey(roLocalDerived.getRootFile().getId())) {
        final WorkflowExecutionOutput output = outputs.get(roLocalDerived.getRootFile().getId());
        updateFile(roLocalDerived.getRootFile(), output);
        sbExecDetails.append(
            getPlanExecutionDetailsForFile(roLocalDerived.getRootFile().getId(), output));
      }

      if (roLocalDerived.getPartFiles() != null) {
        for (RepresentationFile rFile : roLocalDerived.getPartFiles()) {
          if (outputs.containsKey(rFile.getId())) {
            final WorkflowExecutionOutput output = outputs.get(rFile.getId());
            updateFile(rFile, output);
            sbExecDetails.append(getPlanExecutionDetailsForFile(rFile.getId(), output));
          }
        }
      }

      sbExecDetails.append(String.format("</planExecutionDetails>%n"));

      roLocalDerived.setType(RepresentationObject.DIGITALIZED_WORK);
      final String subtype = RepresentationBuilder.getRepresentationSubtype(roLocalDerived);
      roLocalDerived.setSubType(subtype);

    } catch (RODAException e) {
      deleteTemporaryLocalRepresentation(roLocalDerived);
      logger.error(e.getMessage(), e);
      throw new ExecutePlanException(e.getMessage(), e);
    } catch (RemoteException e) {
      deleteTemporaryLocalRepresentation(roLocalDerived);
      logger.error(e.getMessage(), e);
      throw new ExecutePlanException(e.getMessage(), e);
    } catch (IOException e) {
      deleteTemporaryLocalRepresentation(roLocalDerived);
      logger.error(e.getMessage(), e);
      throw new ExecutePlanException(e.getMessage(), e);
    }

    String derivedROPID = null;
    try {

      derivedROPID = ingestRepresentation(roLocalDerived);
      reportItem.addAttribute(new Attribute("Derived representation PID", derivedROPID));

    } catch (IngestException e) {

      logger.error("Error ingesting new representation - " + e.getMessage(), e);
      throw new ExecutePlanException("Error ingesting new representation - " + e.getMessage(), e);

    } finally {

      deleteTemporaryLocalRepresentation(roLocalDerived);
    }

    try {

      final String epoPID =
          createPreservationEvent(
              roOriginal.getPid(), derivedROPID, sbExecDetails.toString(), reportItem);
      reportItem.addAttribute(new Attribute("Derivation event PID", epoPID));

    } catch (ExecutePlanException e) {
      logger.debug("Error registering convertion event - " + e.getMessage(), e);

      try {
        logger.warn("Error registering convertion event. Removing created object " + derivedROPID);

        this.rodaClient.getIngestService().removeObjects(new String[] {derivedROPID});

      } catch (RODAClientException e1) {
        logger.warn(
            "Error removing representation " + roPID + " - " + e1.getMessage() + ". IGNORING", e1);
      } catch (RemoteException e1) {
        logger.warn(
            "Error removing representation " + roPID + " - " + e1.getMessage() + ". IGNORING", e1);
      } catch (IngestException e1) {
        logger.warn(
            "Error removing representation " + roPID + " - " + e1.getMessage() + ". IGNORING", e1);
      }

      throw new ExecutePlanException(
          "Error registering convertion event - " + e.getMessage(), e, reportItem);
    }

    return derivedROPID;
  }