/** Test the Description method. */
 @Test
 public void testDescribe() {
   System.out.println("Asking for description:");
   ServiceDescription desc = dom.describe();
   assertTrue("The ServiceDescription should not be NULL.", desc != null);
   System.out.println("Recieved service description: " + desc.toXmlFormatted());
 }
  /**
   * @param inFile
   * @param outFile
   * @param inExt
   * @param outExt
   * @throws IOException
   */
  private void doMigrate(String inFile, String outFile, String inExt, String outExt)
      throws IOException {
    DigitalObject input =
        new DigitalObject.Builder(Content.byReference(new File(inFile).toURI().toURL()))
            .permanentUri(URI.create("http://some"))
            .build();
    System.out.println("Input: " + input);

    FormatRegistry format = FormatRegistryFactory.getFormatRegistry();
    MigrateResult mr =
        dom.migrate(
            input, format.createExtensionUri(inExt), format.createExtensionUri(outExt), null);

    ServiceReport sr = mr.getReport();
    System.out.println("Got Report: " + sr);

    DigitalObject doOut = mr.getDigitalObject();

    assertTrue("Resulting digital object is null.", doOut != null);

    System.out.println("Output: " + doOut);
    System.out.println("Output.content: " + doOut.getContent());
    System.out.println(
        "Output.content.read().available(): " + doOut.getContent().getInputStream().available());

    File out = new File(outFile);
    writeInStreamToOutStream(doOut.getContent().getInputStream(), new FileOutputStream(out));
  }
  /**
   * @return an URI to the resulting digital object's data registry reference
   * @throws Exception
   */
  public URI runMigration() throws Exception {

    // an object used for documenting the results of a service action
    // document the service type and start-time
    WorkflowResultItem wfResultItem;
    if (endOfRoundtripp) {
      wfResultItem =
          new WorkflowResultItem(
              pedigreeDigoRef,
              WorkflowResultItem.SERVICE_ACTION_FINAL_MIGRATION,
              System.currentTimeMillis(),
              wfi.getWorkflowReportingLogger());
    } else {
      wfResultItem =
          new WorkflowResultItem(
              pedigreeDigoRef,
              WorkflowResultItem.SERVICE_ACTION_MIGRATION,
              System.currentTimeMillis(),
              wfi.getWorkflowReportingLogger());
    }
    wfi.addWFResultItem(wfResultItem);

    try {
      // get all parameters that were added in the configuration file
      List<Parameter> parameterList;
      if (wfi.getServiceCallConfigs(migrationService) != null) {
        parameterList = wfi.getServiceCallConfigs(migrationService).getAllPropertiesAsParameters();
      } else {
        parameterList = new ArrayList<Parameter>();
      }
      wfResultItem.setServiceParameters(parameterList);

      // get from config: migrate_to_fmt for this service
      URI migrateToURI, migrateFromURI;
      if (this.outputFormat != null) {
        // e.g. when using a identification prior to chose the output format
        migrateToURI = this.outputFormat;
      } else {
        // get the ones from the ServiceCallConfigs
        migrateToURI =
            wfi.getServiceCallConfigs(migrationService)
                .getPropertyAsURI(WorkflowTemplate.SER_PARAM_MIGRATE_TO);
      }
      wfResultItem.addLogInfo("set migrate to: " + migrateToURI);

      if (this.inputFormat != null) {
        // e.g. when using a identification prior to chose the input format
        migrateFromURI = this.inputFormat;
      } else {
        // get the ones from the ServiceCallConfigs
        migrateFromURI =
            wfi.getServiceCallConfigs(migrationService)
                .getPropertyAsURI(WorkflowTemplate.SER_PARAM_MIGRATE_FROM);
      }
      wfResultItem.addLogInfo("set migrate from: " + migrateFromURI);

      if ((migrateToURI == null) && (migrateFromURI == null)) {
        String err = "No parameter for: 'migrate_to/from_filetype' specified";
        wfResultItem.addLogInfo(err);
        throw new Exception(err);
      }

      // document
      wfResultItem.setInputDigitalObjectRef(digOToMigrateRef);
      wfResultItem.setServiceParameters(parameterList);
      wfResultItem.setStartTime(System.currentTimeMillis());
      // document the endpoint if available - retrieve from
      // WorkflowContext
      String endpoint =
          wfi.getWorkflowContext()
              .getContextObject(
                  migrationService,
                  WorkflowContext.Property_ServiceEndpoint,
                  java.lang.String.class);
      if (endpoint != null) {
        wfResultItem.setServiceEndpoint(new URL(endpoint));
      }
      ServiceDescription serDescr = migrationService.describe();
      wfResultItem.setServiceDescription(serDescr);

      // retrieve the actual digital object
      DigitalObject digoToMigrate = dataRegistry.retrieve(digOToMigrateRef);

      // now call the migration
      MigrateResult migrateResult =
          migrationService.migrate(digoToMigrate, migrateFromURI, migrateToURI, parameterList);

      // document
      wfResultItem.setEndTime(System.currentTimeMillis());
      ServiceReport report = migrateResult.getReport();
      // report service status and type
      wfResultItem.setServiceReport(report);
      if (report.getType() == Type.ERROR) {
        String s = "Service execution failed: " + report.getMessage();
        wfResultItem.addLogInfo(s);
        throw new Exception(s);
      }

      DigitalObject migOutput = migrateResult.getDigitalObject();

      // add Migration Event to DigitalObject
      Event migrEvent =
          buildMigrationOutputEvent(
              digoToMigrate,
              parameterList,
              wfResultItem.getStartTime(),
              wfResultItem.getDuration(),
              serDescr,
              endpoint);

      List<Event> lEvents = migOutput.getEvents();
      lEvents.add(migrEvent);

      // create an updated DigitalObject containing the Migration-Event
      // note, as the FileSystemDigoManager requires a title != null, we'll use a random one here
      String title = (migOutput.getTitle() == null) ? UUID.randomUUID() + "" : migOutput.getTitle();
      URI suggStorageURI =
          helperCreateDOMURIWithFileExtension(
              wfi.getWorklowInstanceID(), digOToMigrateRef, dataRepositoryID, migrateToURI);
      DigitalObject digoUpdated =
          new DigitalObject.Builder(migOutput.getContent())
              .title(title)
              .permanentUri(migOutput.getPermanentUri())
              .manifestationOf(migOutput.getManifestationOf())
              .format(migOutput.getFormat())
              .metadata((Metadata[]) migOutput.getMetadata().toArray(new Metadata[0]))
              .events((Event[]) lEvents.toArray(new Event[0]))
              .build();

      // decide in which repository to store the received DigitalObject
      URI digoRef;
      if (this.dataRepositoryID != null) {
        digoRef = wfi.storeDigitalObjectInRepository(suggStorageURI, digoUpdated, dataRepositoryID);
      } else {
        // in this case use the default data registry manager location for persisting
        digoRef = wfi.storeDigitalObject(digoUpdated);
      }

      wfResultItem.addLogInfo("storing digital object with permanent URI: " + digoRef);
      wfResultItem.setOutputDigitalObjectRef(digoRef);
      wfResultItem.addLogInfo("migration completed");

      return digoRef;

    } catch (Exception e) {
      wfResultItem.addLogInfo("migration failed " + e);
      throw e;
    }
  }