/**
   * Get the binary content of a datastream
   *
   * @param rangeValue the range value
   * @return Binary blob
   * @throws IOException if io exception occurred
   */
  protected Response getBinaryContent(final String rangeValue) throws IOException {
    final FedoraBinary binary = (FedoraBinary) resource();

    // we include an explicit etag, because the default behavior is to use the JCR node's etag, not
    // the jcr:content node digest. The etag is only included if we are not within a transaction.
    final String txId = TransactionServiceImpl.getCurrentTransactionId(session());
    if (txId == null) {
      checkCacheControlHeaders(request, servletResponse, binary, session());
    }
    final CacheControl cc = new CacheControl();
    cc.setMaxAge(0);
    cc.setMustRevalidate(true);
    Response.ResponseBuilder builder;

    if (rangeValue != null && rangeValue.startsWith("bytes")) {

      final Range range = Range.convert(rangeValue);

      final long contentSize = binary.getContentSize();

      final String endAsString;

      if (range.end() == -1) {
        endAsString = Long.toString(contentSize - 1);
      } else {
        endAsString = Long.toString(range.end());
      }

      final String contentRangeValue =
          String.format("bytes %s-%s/%s", range.start(), endAsString, contentSize);

      if (range.end() > contentSize || (range.end() == -1 && range.start() > contentSize)) {

        builder =
            status(REQUESTED_RANGE_NOT_SATISFIABLE).header("Content-Range", contentRangeValue);
      } else {
        final RangeRequestInputStream rangeInputStream =
            new RangeRequestInputStream(binary.getContent(), range.start(), range.size());

        builder =
            status(PARTIAL_CONTENT)
                .entity(rangeInputStream)
                .header("Content-Range", contentRangeValue);
      }

    } else {
      final InputStream content = binary.getContent();
      builder = ok(content);
    }

    // we set the content-type explicitly to avoid content-negotiation from getting in the way
    return builder.type(binary.getMimeType()).cacheControl(cc).build();
  }
  protected void replaceResourceBinaryWithStream(
      final FedoraBinary result,
      final InputStream requestBodyStream,
      final ContentDisposition contentDisposition,
      final MediaType contentType,
      final String checksum)
      throws InvalidChecksumException {
    final URI checksumURI = checksumURI(checksum);
    final String originalFileName =
        contentDisposition != null ? contentDisposition.getFileName() : "";
    final String originalContentType = contentType != null ? contentType.toString() : "";

    result.setContent(
        requestBodyStream,
        originalContentType,
        checksumURI,
        originalFileName,
        storagePolicyDecisionPoint);
  }
  /**
   * Add any resource-specific headers to the response
   *
   * @param resource the resource
   */
  protected void addResourceHttpHeaders(final FedoraResource resource) {
    if (resource instanceof FedoraBinary) {

      final FedoraBinary binary = (FedoraBinary) resource;
      final ContentDisposition contentDisposition =
          ContentDisposition.type("attachment")
              .fileName(binary.getFilename())
              .creationDate(binary.getCreatedDate())
              .modificationDate(binary.getLastModifiedDate())
              .size(binary.getContentSize())
              .build();

      servletResponse.addHeader("Content-Type", binary.getMimeType());
      servletResponse.addHeader("Content-Length", String.valueOf(binary.getContentSize()));
      servletResponse.addHeader("Accept-Ranges", "bytes");
      servletResponse.addHeader("Content-Disposition", contentDisposition.toString());
    }

    servletResponse.addHeader("Link", "<" + LDP_NAMESPACE + "Resource>;rel=\"type\"");

    if (resource instanceof NonRdfSource) {
      servletResponse.addHeader("Link", "<" + LDP_NAMESPACE + "NonRDFSource>;rel=\"type\"");
    } else if (resource instanceof Container) {
      servletResponse.addHeader("Link", "<" + CONTAINER.getURI() + ">;rel=\"type\"");
      if (resource.hasType(LDP_BASIC_CONTAINER)) {
        servletResponse.addHeader("Link", "<" + BASIC_CONTAINER.getURI() + ">;rel=\"type\"");
      } else if (resource.hasType(LDP_DIRECT_CONTAINER)) {
        servletResponse.addHeader("Link", "<" + DIRECT_CONTAINER.getURI() + ">;rel=\"type\"");
      } else if (resource.hasType(LDP_INDIRECT_CONTAINER)) {
        servletResponse.addHeader("Link", "<" + INDIRECT_CONTAINER.getURI() + ">;rel=\"type\"");
      } else {
        servletResponse.addHeader("Link", "<" + BASIC_CONTAINER.getURI() + ">;rel=\"type\"");
      }
    } else {
      servletResponse.addHeader("Link", "<" + LDP_NAMESPACE + "RDFSource>;rel=\"type\"");
    }
    if (httpHeaderInject != null) {
      httpHeaderInject.addHttpHeaderToResponseStream(servletResponse, uriInfo, resource());
    }
  }