/**
  * Retrieves the properties of a piece of content.
  *
  * @param spaceID
  * @param contentID
  * @return Map of content properties
  */
 @Override
 public Map<String, String> getContentProperties(String spaceID, String contentID, String storeID)
     throws ResourceException {
   try {
     StorageProvider storage = storageProviderFactory.getStorageProvider(storeID);
     return storage.getContentProperties(spaceID, contentID);
   } catch (NotFoundException e) {
     throw new ResourceNotFoundException("get properties for content", spaceID, contentID, e);
   } catch (Exception e) {
     storageProviderFactory.expireStorageProvider(storeID);
     throw new ResourceException("get properties for content", spaceID, contentID, e);
   }
 }
  /**
   * Adds content to a space.
   *
   * @return the checksum of the content as computed by the storage provider
   */
  @Override
  public String addContent(
      String spaceID,
      String contentID,
      InputStream content,
      String contentMimeType,
      Map<String, String> userProperties,
      long contentSize,
      String checksum,
      String storeID)
      throws ResourceException, InvalidIdException {
    IdUtil.validateContentId(contentID);

    try {
      StorageProvider storage = storageProviderFactory.getStorageProvider(storeID);

      try {
        // overlay new properties on top of older extended properties
        // so that old tags and custom properties are preserved.
        // c.f. https://jira.duraspace.org/browse/DURACLOUD-757
        Map<String, String> oldUserProperties = storage.getContentProperties(spaceID, contentID);
        // remove all non extended properties
        if (userProperties != null) {
          oldUserProperties.putAll(userProperties);
          // use old mimetype if none specified.
          String oldMimetype =
              oldUserProperties.remove(StorageProvider.PROPERTIES_CONTENT_MIMETYPE);
          if (contentMimeType == null || contentMimeType.trim() == "") {
            contentMimeType = oldMimetype;
          }

          oldUserProperties = StorageProviderUtil.removeCalculatedProperties(oldUserProperties);
        }

        userProperties = oldUserProperties;
      } catch (NotFoundException ex) {
        // do nothing - no properties to update
        // since file did not previous exist.
      }

      return storage.addContent(
          spaceID, contentID, contentMimeType, userProperties, contentSize, checksum, content);
    } catch (NotFoundException e) {
      throw new ResourceNotFoundException("add content", spaceID, contentID, e);
    } catch (ChecksumMismatchException e) {
      throw new ResourceChecksumException("add content", spaceID, contentID, e);
    } catch (Exception e) {
      storageProviderFactory.expireStorageProvider(storeID);
      throw new ResourceException("add content", spaceID, contentID, e);
    }
  }
  /**
   * Removes a piece of content.
   *
   * @param spaceID
   * @param contentID
   * @return success
   */
  @Override
  public void deleteContent(String spaceID, String contentID, String storeID)
      throws ResourceException {
    try {
      StorageProvider storage = storageProviderFactory.getStorageProvider(storeID);

      storage.deleteContent(spaceID, contentID);
    } catch (NotFoundException e) {
      throw new ResourceNotFoundException("delete content", spaceID, contentID, e);
    } catch (Exception e) {
      storageProviderFactory.expireStorageProvider(storeID);
      throw new ResourceException("delete content", spaceID, contentID, e);
    }
  }
 /**
  * Retrieves content from a space.
  *
  * @param spaceID
  * @param contentID
  * @return InputStream which can be used to read content.
  */
 @Override
 public InputStream getContent(String spaceID, String contentID, String storeID)
     throws ResourceException {
   try {
     StorageProvider storage = storageProviderFactory.getStorageProvider(storeID);
     return storage.getContent(spaceID, contentID);
   } catch (NotFoundException e) {
     throw new ResourceNotFoundException("get content", spaceID, contentID, e);
   } catch (StorageStateException e) {
     throw new ResourceStateException("get content", spaceID, contentID, e);
   } catch (Exception e) {
     storageProviderFactory.expireStorageProvider(storeID);
     throw new ResourceException("get content", spaceID, contentID, e);
   }
 }
  /**
   * Updates the properties of a piece of content.
   *
   * @return success
   */
  @Override
  public void updateContentProperties(
      String spaceID,
      String contentID,
      String contentMimeType,
      Map<String, String> userProperties,
      String storeID)
      throws ResourceException {
    try {
      StorageProvider storage = storageProviderFactory.getStorageProvider(storeID);

      // Update content properties
      if (userProperties != null) {
        storage.setContentProperties(spaceID, contentID, userProperties);
      }
    } catch (NotFoundException e) {
      throw new ResourceNotFoundException("update properties for content", spaceID, contentID, e);
    } catch (StorageStateException e) {
      throw new ResourceStateException("update properties for content", spaceID, contentID, e);
    } catch (Exception e) {
      storageProviderFactory.expireStorageProvider(storeID);
      throw new ResourceException("update properties for content", spaceID, contentID, e);
    }
  }
  private String copyContent(
      StorageProvider storage,
      String srcSpaceID,
      String srcContentID,
      String destSpaceID,
      String destContentID,
      String storeID)
      throws ResourceException {

    try {
      return storage.copyContent(srcSpaceID, srcContentID, destSpaceID, destContentID);

    } catch (NotFoundException e) {
      throw new ResourceNotFoundException(
          "copy content", srcSpaceID, srcContentID, destSpaceID, destContentID, e);
    } catch (StorageStateException e) {
      throw new ResourceStateException(
          "copy content", srcSpaceID, srcContentID, destSpaceID, destContentID, e);
    } catch (Exception e) {
      storageProviderFactory.expireStorageProvider(storeID);
      throw new ResourceException(
          "copy content", srcSpaceID, srcContentID, destSpaceID, destContentID, e);
    }
  }