@Override
  public DeleteResponse delete(DeleteRequest deleteRequest, Request.Directive directive)
      throws ContentFrameworkException {
    logger.trace("ENTERING: delete");

    DeleteResponse deleteResponse = null;

    // If directive includes processing and there are no ContentPlugins currently installed to
    // support processing, then throw an exception. (Do not want to do the STORE and get the
    // content repository out of sync with the Metadata Catalog.)
    if ((directive == Directive.PROCESS || directive == Directive.STORE_AND_PROCESS)
        && (this.contentPlugins.size() == 0)) {
      throw new ContentFrameworkException(
          "Unable to perform " + directive + " because no ContentPlugins are installed.");
    }

    if (directive == Directive.STORE || directive == Directive.STORE_AND_PROCESS) {
      try {
        deleteResponse = this.provider.delete(deleteRequest);
      } catch (StorageException e) {
        throw new ContentFrameworkException(e);
      } catch (Exception e) {
        logger.warn("Content Provider error during delete", e);
        throw new ContentFrameworkException(
            "Unable to perform delete because no content storage provider is installed or there is a problem with the content storage provider.",
            e);
      }
    }

    if (directive == Directive.PROCESS || directive == Directive.STORE_AND_PROCESS) {
      if (directive == Directive.PROCESS) {
        // No content deletion occurred to return a DeleteResponse. So need to
        // instantiate a DeleteResponse with the original DeleteRequest's ContentItem
        // in it.
        if (deleteResponse == null) {
          deleteResponse =
              new DeleteResponseImpl(deleteRequest, deleteRequest.getContentItem(), false);
        }
      }

      for (final ContentPlugin plugin : contentPlugins) {
        try {
          deleteResponse = plugin.process(deleteResponse);
        } catch (PluginExecutionException e) {
          logger.info(
              "Content Plugin processing failed. This is allowable. Skipping to next plugin.", e);
        }
      }
    }

    logger.trace("EXITING: delete");

    return deleteResponse;
  }
  @Override
  public CreateResponse create(CreateRequest createRequest, Request.Directive directive)
      throws ContentFrameworkException {
    logger.trace("ENTERING: create");

    logger.debug("directive = " + directive);

    CreateResponse createResponse = null;

    // If directive includes processing and there are no ContentPlugins currently installed to
    // support processing, then throw an exception. (Do not want to do the STORE and get the
    // content repository out of sync with the Metadata Catalog.)
    if ((directive == Directive.PROCESS || directive == Directive.STORE_AND_PROCESS)
        && (this.contentPlugins.size() == 0)) {
      throw new ContentFrameworkException(
          "Unable to perform " + directive + " because no ContentPlugins are installed.");
    }

    // Recreate content item so can add GUID to request
    ContentItem incomingContentItem = createRequest.getContentItem();
    String id = UUID.randomUUID().toString().replaceAll("-", "");
    logger.debug("Created GUID: " + id);
    try {
      ContentItem contentItem =
          new IncomingContentItem(
              id,
              incomingContentItem.getInputStream(),
              incomingContentItem.getMimeTypeRawData(),
              incomingContentItem.getFilename());
      contentItem.setUri(incomingContentItem.getUri());
      createRequest = new CreateRequestImpl(contentItem, createRequest.getProperties());
    } catch (IOException e1) {
      throw new ContentFrameworkException("Unable to add ID to IncomingContentItem", e1);
    }

    if (directive == Directive.STORE || directive == Directive.STORE_AND_PROCESS) {
      try {
        createResponse = provider.create(createRequest);
      } catch (StorageException e) {
        throw new ContentFrameworkException(e);
      } catch (Exception e) {
        logger.warn("Content Provider error during create", e);
        throw new ContentFrameworkException(
            "Unable to perform create because no content storage provider is installed or there is a problem with the content storage provider.",
            e);
      }
    }

    if (directive == Directive.PROCESS || directive == Directive.STORE_AND_PROCESS) {
      if (directive == Directive.PROCESS) {
        // No content storage occurred to return a CreateResponse. So need to
        // instantiate a CreateResponse with the original CreateRequest's ContentItem
        // in it.
        if (createResponse == null) {
          createResponse = new CreateResponseImpl(createRequest, createRequest.getContentItem());
        }
      }

      logger.debug("Number of ContentPlugins = " + contentPlugins.size());

      // Execute each ContentPlugin on the content item. If any plugin fails, then
      // assume the entire transaction fails, rolling back the storage of the content
      // item in the content repository (if applicable)
      try {
        for (final ContentPlugin plugin : contentPlugins) {
          createResponse = plugin.process(createResponse);
        }
      } catch (PluginExecutionException e) {
        logger.info("Content Plugin processing failed.", e);

        // If a STORE_AND_PROCESS directive was being done, will need to delete the
        // stored content item from the content repository (similar to a rollback)
        if (directive == Directive.STORE_AND_PROCESS) {
          String contentId = createResponse.getCreatedContentItem().getId();
          logger.debug("Doing storage rollback - Deleting content item " + contentId);

          ContentItem itemToDelete = new IncomingContentItem(contentId, null, null);
          itemToDelete.setUri(incomingContentItem.getUri());
          DeleteRequest deleteRequest = new DeleteRequestImpl(itemToDelete, null);
          try {
            this.provider.delete(deleteRequest);
          } catch (Exception e2) {
            logger.warn(
                "Unable to perform delete because no content storage provider is installed or there is a problem with the content storage provider.",
                e2);
          }

          // Re-throw the exception (this will fail the Camel route that may have
          // started this request)
          throw new ContentFrameworkException(
              "Content Plugin processing failed. Did not store item in content repository and did not create catalog entry.\n"
                  + e.getMessage(),
              e);
        } else {
          // Re-throw the exception (this will fail the Camel route that may have
          // started this request)
          throw new ContentFrameworkException(
              "Content Plugin processing failed. Did not create catalog entry.\n" + e.getMessage(),
              e);
        }
      }
    }

    logger.trace("EXITING: create");

    return createResponse;
  }
  @Override
  public UpdateResponse update(final UpdateRequest updateRequest, Request.Directive directive)
      throws ContentFrameworkException {
    logger.trace("ENTERING: update");

    UpdateResponse updateResponse = null;

    // If directive includes processing and there are no ContentPlugins currently installed to
    // support processing, then throw an exception. (Do not want to do the STORE and get the
    // content repository out of sync with the Metadata Catalog.)
    if ((directive == Directive.PROCESS || directive == Directive.STORE_AND_PROCESS)
        && (this.contentPlugins.size() == 0)) {
      throw new ContentFrameworkException(
          "Unable to perform " + directive + " because no ContentPlugins are installed.");
    }

    ContentItem itemToUpdate = updateRequest.getContentItem();

    if (directive == Directive.STORE || directive == Directive.STORE_AND_PROCESS) {
      // Verify content item exists in content repository before trying to update it
      try {
        ReadRequest readRequest = new ReadRequestImpl(updateRequest.getContentItem().getId(), null);
        this.provider.read(readRequest);
      } catch (StorageException e) {
        logger.info("File does not exist, cannot update, doing a create: ", e);
        throw new ContentFrameworkException(
            "File does not exist, cannot update, doing a create: ", e);
      } catch (Exception e) {
        logger.warn("Content Provider error during update", e);
        throw new ContentFrameworkException(
            "Unable to perform update because no content storage provider is installed or there is a problem with the content storage provider.",
            e);
      }

      logger.info("Updating content repository for content item: " + itemToUpdate.getId());
      try {
        updateResponse = this.provider.update(updateRequest);
        try {
          logger.debug(
              "updated item file length = " + updateResponse.getUpdatedContentItem().getSize());
        } catch (IOException ioe) {
        }
      } catch (StorageException e) {
        throw new ContentFrameworkException(e);
      } catch (Exception e) {
        logger.warn("Content Provider error during update", e);
        throw new ContentFrameworkException(
            "Unable to perform update because no content storage provider is installed or there is a problem with the content storage provider.",
            e);
      }
    }

    if (directive == Directive.PROCESS || directive == Directive.STORE_AND_PROCESS) {
      if (directive == Directive.PROCESS) {
        // No content update occurred to return an UpdateResponse. So need to
        // instantiate an UpdateResponse with the original UpdateRequest's ContentItem
        // in it.
        if (updateResponse == null) {
          updateResponse = new UpdateResponseImpl(updateRequest, updateRequest.getContentItem());
        }
      }

      // Execute each ContentPlugin on the content item. If any plugin fails, then
      // assume the entire transaction fails, rolling back the storage of the content
      // item in the content repository (if applicable)
      try {
        for (final ContentPlugin plugin : contentPlugins) {
          updateResponse = plugin.process(updateResponse);
        }
      } catch (PluginExecutionException e) {

        logger.info("Content Plugin processing failed.", e);

        // Re-throw the exception (this will fail the Camel route that may have
        // started this request)
        throw new ContentFrameworkException(
            "Content Plugin processing failed. " + e.getMessage(), e);
      }
    }

    logger.trace("EXITING: update");

    return updateResponse;
  }