Coverage Report - com.jcabi.s3.Bucket
 
Classes in this File Line Coverage Branch Coverage Complexity
Bucket
N/A
N/A
1.059
Bucket$Prefixed
44%
8/18
0%
0/20
1.059
Bucket$Prefixed$1
80%
4/5
50%
1/2
1.059
Bucket$Prefixed$2
100%
2/2
50%
1/2
1.059
Bucket$Prefixed$AjcClosure1
0%
0/1
N/A
1.059
Bucket$Prefixed$AjcClosure11
100%
1/1
N/A
1.059
Bucket$Prefixed$AjcClosure13
0%
0/1
N/A
1.059
Bucket$Prefixed$AjcClosure3
0%
0/1
N/A
1.059
Bucket$Prefixed$AjcClosure5
0%
0/1
N/A
1.059
Bucket$Prefixed$AjcClosure7
0%
0/1
N/A
1.059
Bucket$Prefixed$AjcClosure9
0%
0/1
N/A
1.059
 
 1  2
 /**
 2  
  * Copyright (c) 2012-2015, jcabi.com
 3  
  * All rights reserved.
 4  
  *
 5  
  * Redistribution and use in source and binary forms, with or without
 6  
  * modification, are permitted provided that the following conditions
 7  
  * are met: 1) Redistributions of source code must retain the above
 8  
  * copyright notice, this list of conditions and the following
 9  
  * disclaimer. 2) Redistributions in binary form must reproduce the above
 10  
  * copyright notice, this list of conditions and the following
 11  
  * disclaimer in the documentation and/or other materials provided
 12  
  * with the distribution. 3) Neither the name of the jcabi.com nor
 13  
  * the names of its contributors may be used to endorse or promote
 14  
  * products derived from this software without specific prior written
 15  
  * permission.
 16  
  *
 17  
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 18  
  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
 19  
  * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 20  
  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
 21  
  * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 22  
  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 23  
  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 24  
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 25  
  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 26  
  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 27  
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 28  
  * OF THE POSSIBILITY OF SUCH DAMAGE.
 29  
  */
 30  
 package com.jcabi.s3;
 31  
 
 32  
 import com.google.common.base.Function;
 33  
 import com.google.common.base.Predicate;
 34  
 import com.google.common.collect.Iterables;
 35  
 import com.jcabi.aspects.Immutable;
 36  
 import com.jcabi.aspects.Loggable;
 37  
 import java.io.IOException;
 38  
 import lombok.EqualsAndHashCode;
 39  
 import lombok.ToString;
 40  
 
 41  
 /**
 42  
  * Amazon S3 bucket.
 43  
  *
 44  
  * <p>You get an instance of this interface from {@link Region}, for example:
 45  
  *
 46  
  * <pre> Region region = new Region.Simple(key, secret);
 47  
  * Bucket bucket = region.bucket("my.example.com");
 48  
  * for (String key : bucket.list("")) {
 49  
  *   System.out.println(
 50  
  *     "key: " + key + ", last modified: "
 51  
  *     + bucket.get(key).meta().getLastModified()
 52  
  *   );
 53  
  * }</pre>
 54  
  *
 55  
  * @author Yegor Bugayenko (yegor@tpc2.com)
 56  
  * @version $Id: 30fb9866dd533b7a8101d9988387abbbdc387676 $
 57  
  * @since 0.1
 58  
  */
 59  
 @Immutable
 60  
 @SuppressWarnings("PMD.TooManyMethods")
 61  
 public interface Bucket extends Comparable<Bucket> {
 62  
 
 63  
     /**
 64  
      * Get region we're in.
 65  
      * @return Region
 66  
      */
 67  
     Region region();
 68  
 
 69  
     /**
 70  
      * Get bucket name.
 71  
      * @return Bucket name
 72  
      */
 73  
     String name();
 74  
 
 75  
     /**
 76  
      * Get object.
 77  
      * @param key Name of it in the bucket
 78  
      * @return Ocket
 79  
      */
 80  
     Ocket ocket(String key);
 81  
 
 82  
     /**
 83  
      * Checks if the bucket exists.
 84  
      * @return If the bucket exists {@code true}, otherwise {@code false}
 85  
      * @throws IOException If any failure happens
 86  
      */
 87  
     boolean exists() throws IOException;
 88  
 
 89  
     /**
 90  
      * Delete object from bucket.
 91  
      * @param key Name of it in the bucket
 92  
      * @throws IOException If not found or any other failure
 93  
      */
 94  
     void remove(String key)
 95  
         throws IOException;
 96  
 
 97  
     /**
 98  
      * List object names with a given prefix.
 99  
      * @param pfx Prefix to use
 100  
      * @return Iterable of names
 101  
      * @throws IOException If fails
 102  
      * @since 0.3
 103  
      */
 104  
     Iterable<String> list(String pfx) throws IOException;
 105  
 
 106  
     /**
 107  
      * Creates bucket with specified origin bucket and prefix.
 108  
      *
 109  
      * <p>Basically this class is used to cut off ocket keys of underlying
 110  
      * bucket by some string known as prefix. If key is not started
 111  
      * with prefix, it will be omitted
 112  
      *
 113  
      * <p>Example of usage:
 114  
      * <pre>
 115  
      * final Region region = new MkRegion(
 116  
      *   new TemporaryFolder().newFolder()
 117  
      * );
 118  
      * final Bucket bucket = region.bucket("test");
 119  
      * new Ocket.Text(bucket.ocket("a/first.txt")).write("");
 120  
      * new Ocket.Text(bucket.ocket("a/b/hello.txt")).write("");
 121  
      * new Ocket.Text(bucket.ocket("a/b/f/2.txt")).write("");
 122  
      * Bucket.Prefixed prefixed = new Bucket.Prefixed(
 123  
      *   bucket, "a/b/"
 124  
      * );
 125  
      * Iterable<String> list = prefixed.list(
 126  
      *   ""
 127  
      * ); // contains "hello.txt" and "f/2.txt"
 128  
      * </pre>
 129  
      */
 130  0
     @Immutable
 131  0
     @ToString
 132  0
     @EqualsAndHashCode(of = { "origin", "prefix" })
 133  
     @Loggable(Loggable.DEBUG)
 134  36
     final class Prefixed implements Bucket {
 135  
         /**
 136  
          * Original encapsulated bucket.
 137  
          */
 138  
         private final transient Bucket origin;
 139  
         /**
 140  
          * Prefix.
 141  
          */
 142  
         private final transient String prefix;
 143  
         /**
 144  
          * Public ctor.
 145  
          * @param bucket Original bucket
 146  
          * @param pfx Prefix
 147  
          */
 148  2
         public Prefixed(final Bucket bucket, final String pfx) {
 149  2
             this.origin = bucket;
 150  2
             this.prefix = pfx;
 151  2
         }
 152  
         @Override
 153  
         public Region region() {
 154  0
             return this.origin.region();
 155  
         }
 156  
         @Override
 157  
         public String name() {
 158  0
             return this.origin.name();
 159  
         }
 160  
         @Override
 161  
         public Ocket ocket(final String key) {
 162  0
             return this.origin.ocket(this.extend(key));
 163  
         }
 164  
         @Override
 165  
         public boolean exists() throws IOException {
 166  0
             return this.origin.exists();
 167  
         }
 168  
         @Override
 169  
         public void remove(final String key) throws IOException {
 170  0
             this.origin.remove(this.extend(key));
 171  0
         }
 172  
         @Override
 173  
         public Iterable<String> list(final String pfx) throws IOException {
 174  4
             return Iterables.filter(
 175  
                 Iterables.transform(
 176  
                     this.origin.list(this.extend(pfx)),
 177  20
                     new Function<String, String>() {
 178  
                         @Override
 179  
                         public String apply(final String input) {
 180  
                             final String name;
 181  18
                             if (input.length()
 182  
                                 < Bucket.Prefixed.this.prefix.length()) {
 183  0
                                 name = input;
 184  
                             } else {
 185  18
                                 name = input.substring(
 186  
                                     Bucket.Prefixed.this.prefix.length()
 187  
                                 );
 188  
                             }
 189  18
                             return name;
 190  
                         }
 191  
                     }
 192  
                 ),
 193  20
                 new Predicate<String>() {
 194  
                     @Override
 195  
                     public boolean apply(final String input) {
 196  18
                         return !input.isEmpty();
 197  
                     }
 198  
                 }
 199  
             );
 200  
         }
 201  
 
 202  
         @Override
 203  
         public int compareTo(final Bucket bucket) {
 204  0
             return this.origin.compareTo(bucket);
 205  
         }
 206  
         /**
 207  
          * Extend name with a prefix.
 208  
          * @param name The name to extend
 209  
          * @return Extended
 210  
          */
 211  
         private String extend(final String name) {
 212  2
             return String.format("%s%s", this.prefix, name);
 213  
         }
 214  
     }
 215  
 
 216  
 }