/**
  * Retrieves the blob metadata. An inventory will be retrieved to obtain the blob list and the
  * method will iterate through it. This operation will take several hours and the result may be
  * inaccurate (Inventories are updated every 24 hours).
  *
  * @param container container name
  * @param key blob name
  * @return null if the blob doesn't exist, the blob metadata otherwise
  * @see <a href="http://aws.amazon.com/glacier/faqs/#data-inventories" />
  */
 @Override
 public BlobMetadata blobMetadata(String container, String key) {
   PageSet<? extends StorageMetadata> blobMetadataSet = list(container, null);
   for (StorageMetadata blob : blobMetadataSet) {
     if (blob.getName().equals(key)) {
       return (BlobMetadata) blob;
     }
   }
   return null;
 }
  /** http://code.google.com/p/jclouds/issues/detail?id=992 */
  public void testUseBucketWithUpperCaseName() throws Exception {
    String bucketName = CONTAINER_PREFIX + "-TestBucket";
    String blobName = "TestBlob.txt";
    StorageMetadata container = null;
    BlobStore store = view.getBlobStore();

    // Create and use a valid bucket name with uppercase characters in the bucket name (US regions
    // only)
    try {
      store.createContainerInLocation(null, bucketName);

      for (StorageMetadata metadata : store.list()) {
        if (metadata.getName().equals(bucketName)) {
          container = metadata;
          break;
        }
      }

      assertNotNull(container);

      store.putBlob(
          bucketName,
          store.blobBuilder(blobName).payload("This is a test!").contentType("text/plain").build());

      assertNotNull(store.getBlob(bucketName, blobName));
    } finally {
      if (container != null) {
        store.deleteContainer(bucketName);
      }
    }

    // Try to create the same bucket successfully created above in one of the non-US regions to
    // ensure an error is
    // encountered as expected.
    Location location = null;

    for (Location pLocation : store.listAssignableLocations()) {
      if (!ImmutableSet.of(Region.US_STANDARD, Region.US_EAST_1, Region.US_WEST_1, Region.US_WEST_2)
          .contains(pLocation.getId())) {
        location = pLocation;
        break;
      }
    }

    try {
      store.createContainerInLocation(location, bucketName);
      fail("Should had failed because in non-US regions, mixed-case bucket names are invalid.");
    } catch (AWSResponseException e) {
      assertEquals("InvalidBucketName", e.getError().getCode());
    }
  }
 public boolean apply(StorageMetadata metadata) {
   if (prefix == null) return metadata.getName().indexOf(delimiter) == -1;
   // ensure we don't accidentally append twice
   String toMatch = prefix.endsWith("/") ? prefix : prefix + delimiter;
   if (metadata.getName().startsWith(toMatch)) {
     String unprefixedName = metadata.getName().replaceFirst(toMatch, "");
     if (unprefixedName.equals("")) {
       // we are the prefix in this case, return false
       return false;
     }
     return unprefixedName.indexOf(delimiter) == -1;
   }
   return false;
 }
  private void checkForContainerContent(
      final String containerName, String inDirectory, Set<String> expectedBlobKeys) {
    ListContainerOptions options = ListContainerOptions.Builder.recursive();
    if (null != inDirectory && !"".equals(inDirectory)) options.inDirectory(inDirectory);

    PageSet<? extends StorageMetadata> blobsRetrieved = blobStore.list(containerName, options);
    for (Iterator<? extends StorageMetadata> it = blobsRetrieved.iterator(); it.hasNext(); ) {
      // TODO: FluentIterable
      if (it.next().getType() != StorageType.BLOB) {
        it.remove();
      }
    }

    // nothing expected
    if (null == expectedBlobKeys || 0 == expectedBlobKeys.size()) {
      assertTrue(
          blobsRetrieved.isEmpty(),
          "Wrong blob number retrieved in the container [" + containerName + "]");
      return;
    }

    // copies values
    Set<String> expectedBlobKeysCopy = Sets.newHashSet();
    for (String value : expectedBlobKeys) {
      expectedBlobKeysCopy.add(value);
    }
    assertEquals(
        blobsRetrieved.size(),
        expectedBlobKeysCopy.size(),
        "Wrong blob number retrieved in the container [" + containerName + "]");
    for (StorageMetadata data : blobsRetrieved) {
      String blobName = data.getName();
      if (!expectedBlobKeysCopy.remove(blobName)) {
        fail(
            "List for container ["
                + containerName
                + "] contains unexpected value ["
                + blobName
                + "]");
      }
    }
    assertTrue(
        expectedBlobKeysCopy.isEmpty(),
        "List operation for container [" + containerName + "] doesn't return all values.");
  }
 public String apply(StorageMetadata metadata) {
   String working = metadata.getName();
   if (prefix != null) {
     // ensure we don't accidentally append twice
     String toMatch = prefix.endsWith("/") ? prefix : prefix + delimiter;
     if (working.startsWith(toMatch)) {
       working = working.replaceFirst(toMatch, "");
     }
   }
   if (working.contains(delimiter)) {
     return working.substring(0, working.indexOf(delimiter));
   }
   return NO_PREFIX;
 }
  /** Test of list method of the root context */
  public void testList_Root() throws IOException {
    PageSet<? extends StorageMetadata> containersRetrieved;
    Set<String> containersCreated = Sets.newHashSet();

    // Testing list with no containers
    containersRetrieved = blobStore.list();
    assertTrue(
        containersRetrieved.isEmpty(), "List operation returns a not empty set of container");

    // Testing list with some containers
    String[] containerNames = {"34343", "aaaa", "bbbbb"};
    containersCreated = Sets.newHashSet();
    for (String containerName : containerNames) {
      blobStore.createContainerInLocation(null, containerName);
      containersCreated.add(containerName);
    }

    containersRetrieved = blobStore.list();
    assertEquals(
        containersCreated.size(), containersRetrieved.size(), "Different numbers of container");

    for (StorageMetadata data : containersRetrieved) {
      String containerName = data.getName();
      if (!containersCreated.remove(containerName)) {
        fail("Container list contains unexpected value [" + containerName + "]");
      }
    }
    assertTrue(containersCreated.isEmpty(), "List operation doesn't return all values.");

    for (String containerName : containerNames) {
      // delete all creaded containers
      blobStore.deleteContainer(containerName);
    }
    containersRetrieved = blobStore.list();
    assertTrue(
        containersRetrieved.isEmpty(), "List operation returns a not empty set of container");
  }
 @Override
 public String execute(StorageMetadata metadata) {
   switch (metadata.getType()) {
     case CONTAINER:
     case FOLDER:
     case RELATIVE_PATH:
       return metadata.getName();
     case BLOB:
       BlobMetadata blobMd = (BlobMetadata) metadata;
       for (String suffix : BlobStoreConstants.DIRECTORY_SUFFIXES) {
         if (metadata.getName().endsWith(suffix)) {
           return metadata.getName().substring(0, metadata.getName().lastIndexOf(suffix));
         }
       }
       // It is important that this is last, in case there is a file with a known directory
       // suffix who also has content type set to application/directory
       if (blobMd.getContentMetadata().getContentType() != null
           && blobMd.getContentMetadata().getContentType().equals("application/directory"))
         return metadata.getName();
   }
   return null;
 }
  /** default maxResults is 1000 */
  @Override
  public ListenableFuture<PageSet<? extends StorageMetadata>> list(
      final String container, ListContainerOptions options) {

    // Check if the container exists
    if (!containerExistsSyncImpl(container)) {
      return immediateFailedFuture(cnfe(container));
    }

    // Loading blobs from container
    Iterable<String> blobBelongingToContainer = null;
    try {
      blobBelongingToContainer = storageStrategy.getBlobKeysInsideContainer(container);
    } catch (IOException e) {
      logger.error(e, "An error occurred loading blobs contained into container %s", container);
      Throwables.propagate(e);
    }

    SortedSet<StorageMetadata> contents =
        newTreeSet(
            transform(
                blobBelongingToContainer,
                new Function<String, StorageMetadata>() {
                  public StorageMetadata apply(String key) {
                    Blob oldBlob = loadFileBlob(container, key);

                    checkState(
                        oldBlob != null,
                        "blob "
                            + key
                            + " is not present although it was in the list of "
                            + container);
                    checkState(
                        oldBlob.getMetadata() != null,
                        "blob " + container + "/" + key + " has no metadata");
                    MutableBlobMetadata md = copy(oldBlob.getMetadata());
                    String directoryName = ifDirectoryReturnName.execute(md);
                    if (directoryName != null) {
                      md.setName(directoryName);
                      md.setType(StorageType.RELATIVE_PATH);
                    }
                    return md;
                  }
                }));

    String marker = null;
    if (options != null) {
      if (options.getMarker() != null) {
        final String finalMarker = options.getMarker();
        StorageMetadata lastMarkerMetadata =
            find(
                contents,
                new Predicate<StorageMetadata>() {
                  public boolean apply(StorageMetadata metadata) {
                    return metadata.getName().equals(finalMarker);
                  }
                });
        contents = contents.tailSet(lastMarkerMetadata);
        contents.remove(lastMarkerMetadata);
      }

      final String prefix = options.getDir();
      if (prefix != null) {
        contents =
            newTreeSet(
                filter(
                    contents,
                    new Predicate<StorageMetadata>() {
                      public boolean apply(StorageMetadata o) {
                        return (o != null
                            && o.getName().startsWith(prefix)
                            && !o.getName().equals(prefix));
                      }
                    }));
      }

      Integer maxResults = options.getMaxResults() != null ? options.getMaxResults() : 1000;
      if (contents.size() > 0) {
        SortedSet<StorageMetadata> contentsSlice = firstSliceOfSize(contents, maxResults);
        if (!contentsSlice.contains(contents.last())) {
          // Partial listing
          marker = contentsSlice.last().getName();
        } else {
          marker = null;
        }
        contents = contentsSlice;
      }

      final String delimiter = options.isRecursive() ? null : File.separator;
      if (delimiter != null) {
        SortedSet<String> commonPrefixes = null;
        Iterable<String> iterable =
            transform(contents, new CommonPrefixes(prefix != null ? prefix : null, delimiter));
        commonPrefixes = iterable != null ? newTreeSet(iterable) : new TreeSet<String>();
        commonPrefixes.remove(CommonPrefixes.NO_PREFIX);

        contents =
            newTreeSet(
                filter(contents, new DelimiterFilter(prefix != null ? prefix : null, delimiter)));

        Iterables.<StorageMetadata>addAll(
            contents,
            transform(
                commonPrefixes,
                new Function<String, StorageMetadata>() {
                  public StorageMetadata apply(String o) {
                    MutableStorageMetadata md = new MutableStorageMetadataImpl();
                    md.setType(StorageType.RELATIVE_PATH);
                    md.setName(o);
                    return md;
                  }
                }));
      }

      // trim metadata, if the response isn't supposed to be detailed.
      if (!options.isDetailed()) {
        for (StorageMetadata md : contents) {
          md.getUserMetadata().clear();
        }
      }
    }

    return Futures.<PageSet<? extends StorageMetadata>>immediateFuture(
        new PageSetImpl<StorageMetadata>(contents, marker));
  }