EMMA Coverage Report (generated Wed Jun 22 19:47:49 EDT 2011)
[all classes][org.jclouds.blobstore.strategy.internal]

COVERAGE SUMMARY FOR SOURCE FILE [MarkersDeleteDirectoryStrategy.java]

nameclass, %method, %block, %line, %
MarkersDeleteDirectoryStrategy.java100% (1/1)67%  (2/3)14%  (21/145)34%  (6.8/20)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class MarkersDeleteDirectoryStrategy100% (1/1)67%  (2/3)14%  (21/145)34%  (6.8/20)
execute (String, String): void 0%   (0/1)0%   (0/122)0%   (0/13)
<static initializer> 100% (1/1)75%  (6/8)75%  (0.8/1)
MarkersDeleteDirectoryStrategy (ExecutorService, AsyncBlobStore, BlobStore): ... 100% (1/1)100% (15/15)100% (6/6)

1/**
2 *
3 * Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
4 *
5 * ====================================================================
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 * ====================================================================
18 */
19package org.jclouds.blobstore.strategy.internal;
20 
21import static org.jclouds.concurrent.FutureIterables.awaitCompletion;
22 
23import java.util.Map;
24import java.util.Set;
25import java.util.concurrent.ExecutorService;
26 
27import javax.annotation.Resource;
28import javax.inject.Named;
29import javax.inject.Singleton;
30 
31import org.jclouds.Constants;
32import org.jclouds.blobstore.AsyncBlobStore;
33import org.jclouds.blobstore.BlobStore;
34import org.jclouds.blobstore.internal.BlobRuntimeException;
35import org.jclouds.blobstore.reference.BlobStoreConstants;
36import org.jclouds.blobstore.strategy.DeleteDirectoryStrategy;
37import org.jclouds.logging.Logger;
38 
39import com.google.common.collect.Maps;
40import com.google.common.collect.Sets;
41import java.util.concurrent.Future;
42import com.google.inject.Inject;
43 
44/**
45 * Key-value implementations of BlobStore, such as S3, do not have directories. In following the
46 * rackspace cloud files project, we use an empty object '#{dirpath}' with content type set to
47 * 'application/directory'.
48 * 
49 * <p/>
50 * To interoperate with other S3 tools, we accept the following ways to tell if the directory
51 * exists:
52 * <ul>
53 * <li>an object named '#{dirpath}_$folder$' or '#{dirpath}/' denoting a directory marker</li>
54 * <li>an object with content type set to 'application/directory' denoting a directory marker</li>
55 * <li>if there exists any objects with the prefix "#{dirpath}/", then the directory is said to
56 * exist</li>
57 * <li>if both a file with the name of a directory and a marker for that directory exists, then the
58 * *file masks the directory*, and the directory is never returned.</li>
59 * </ul>
60 * 
61 * @see MarkerFileMkdirStrategy
62 * @author Adrian Cole
63 */
64@Singleton
65public class MarkersDeleteDirectoryStrategy implements DeleteDirectoryStrategy {
66 
67   private final AsyncBlobStore ablobstore;
68   private final BlobStore blobstore;
69   private final ExecutorService userExecutor;
70   @Resource
71   @Named(BlobStoreConstants.BLOBSTORE_LOGGER)
72   protected Logger logger = Logger.NULL;
73   /**
74    * maximum duration of an blob Request
75    */
76   @Inject(optional = true)
77   @Named(Constants.PROPERTY_REQUEST_TIMEOUT)
78   protected Long maxTime;
79 
80   @Inject
81   MarkersDeleteDirectoryStrategy(
82            @Named(Constants.PROPERTY_USER_THREADS) ExecutorService userExecutor,
83            AsyncBlobStore ablobstore, BlobStore blobstore) {
84      this.userExecutor = userExecutor;
85      this.ablobstore = ablobstore;
86      this.blobstore = blobstore;
87   }
88 
89   public void execute(String containerName, String directory) {
90      Set<String> names = Sets.newHashSet();
91      names.add(directory);
92      for (String suffix : BlobStoreConstants.DIRECTORY_SUFFIXES) {
93         names.add(directory + suffix);
94      }
95      Map<String, Future<?>> responses = Maps.newHashMap();
96      for (String name : names) {
97         responses.put(name, ablobstore.removeBlob(containerName, name));
98      }
99      String message = String.format("deleting directory %s in containerName: %s", directory,
100               containerName);
101      Map<String, Exception> exceptions = awaitCompletion(responses, userExecutor, maxTime, logger,
102               message);
103      if (exceptions.size() > 0)
104         throw new BlobRuntimeException(String.format("error %s: %s", message, exceptions));
105      assert !blobstore.directoryExists(containerName, directory) : String.format(
106               "still exists %s: %s", message, exceptions);
107   }
108}

[all classes][org.jclouds.blobstore.strategy.internal]
EMMA 2.0.5312 (C) Vladimir Roubtsov