You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by ga...@apache.org on 2014/08/28 20:08:10 UTC

[2/2] git commit: JCLOUDS-458: GCS basic object operations

JCLOUDS-458: GCS basic object operations


Project: http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/repo
Commit: http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/commit/155fc112
Tree: http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/tree/155fc112
Diff: http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/diff/155fc112

Branch: refs/heads/master
Commit: 155fc11246705cdce1658beb20182a44d01f080e
Parents: 93c986c
Author: hsbhathiya <hs...@gmail.com>
Authored: Sun Aug 24 15:10:01 2014 +0530
Committer: Andrew Gaul <ga...@apache.org>
Committed: Thu Aug 28 11:07:57 2014 -0700

----------------------------------------------------------------------
 .../GoogleCloudStorageApi.java                  |  16 +-
 .../GoogleCloudStorageApiMetadata.java          |   2 +-
 .../binders/ComposeObjectBinder.java            |  43 ++
 .../binders/UploadBinder.java                   |  41 ++
 .../domain/DomainResourceRefferences.java       |  17 +
 .../googlecloudstorage/domain/DomainUtils.java  |  34 ++
 .../googlecloudstorage/domain/GCSObject.java    | 376 +++++++++++++++
 .../googlecloudstorage/domain/ListPage.java     |  28 +-
 .../googlecloudstorage/domain/Resource.java     |  12 +-
 .../domain/templates/ComposeObjectTemplate.java |  79 ++++
 .../domain/templates/ObjectTemplate.java        | 181 ++++++++
 .../googlecloudstorage/features/ObjectApi.java  | 462 +++++++++++++++++++
 .../options/ComposeObjectOptions.java           |  63 +++
 .../options/CopyObjectOptions.java              | 153 ++++++
 .../options/DeleteObjectOptions.java            |  88 ++++
 .../options/GetObjectOptions.java               |  87 ++++
 .../options/InsertObjectOptions.java            | 115 +++++
 .../options/ListObjectOptions.java              |  82 ++++
 .../options/UpdateObjectOptions.java            | 100 ++++
 .../parser/ParseToPayloadEnclosing.java         |  32 ++
 .../features/ObjectApiLiveTest.java             | 388 ++++++++++++++++
 21 files changed, 2384 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/155fc112/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/GoogleCloudStorageApi.java
----------------------------------------------------------------------
diff --git a/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/GoogleCloudStorageApi.java b/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/GoogleCloudStorageApi.java
index 5381880..e4d3e6d 100644
--- a/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/GoogleCloudStorageApi.java
+++ b/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/GoogleCloudStorageApi.java
@@ -24,6 +24,7 @@ import org.jclouds.googlecloudstorage.features.BucketAccessControlsApi;
 import org.jclouds.googlecloudstorage.features.BucketApi;
 import org.jclouds.googlecloudstorage.features.DefaultObjectAccessControlsApi;
 import org.jclouds.googlecloudstorage.features.ObjectAccessControlsApi;
+import org.jclouds.googlecloudstorage.features.ObjectApi;
 import org.jclouds.rest.annotations.Delegate;
 
 /**
@@ -37,27 +38,34 @@ public interface GoogleCloudStorageApi extends Closeable {
     * Provides access to Default Object Access Control features on bucket
     */
    @Delegate
-   @Path("")
+   @Path("/storage/v1")
    DefaultObjectAccessControlsApi getDefaultObjectAccessControlsApi();
 
    /**
     * Provides access to Bucket Access Control features
     */
    @Delegate
-   @Path("")
+   @Path("/storage/v1")
    BucketAccessControlsApi getBucketAccessControlsApi();
 
    /**
     * Provides access to Bucket features
     */
    @Delegate
-   @Path("")
+   @Path("/storage/v1")
    BucketApi getBucketApi();
 
    /**
     * Provides access to Object Access Control features
     */
    @Delegate
-   @Path("")
+   @Path("/storage/v1")
    ObjectAccessControlsApi getObjectAccessControlsApi();
+
+   /**
+    * Provides access to Google Cloud Storage Object features
+    */
+   @Delegate
+   @Path("")
+   ObjectApi getObjectApi();
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/155fc112/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/GoogleCloudStorageApiMetadata.java
----------------------------------------------------------------------
diff --git a/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/GoogleCloudStorageApiMetadata.java b/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/GoogleCloudStorageApiMetadata.java
index dd6999d..741088c 100644
--- a/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/GoogleCloudStorageApiMetadata.java
+++ b/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/GoogleCloudStorageApiMetadata.java
@@ -70,7 +70,7 @@ public class GoogleCloudStorageApiMetadata extends BaseHttpApiMetadata<GoogleClo
                .credentialName("Private key literal associated with the Google API client_id")
                .documentation(URI.create("https://developers.google.com/storage/docs/json_api"))
                .version("v1")
-               .defaultEndpoint("https://www.googleapis.com/storage/v1")
+               .defaultEndpoint("https://www.googleapis.com")
                .defaultProperties(GoogleCloudStorageApiMetadata.defaultProperties())
                .view(typeToken(BlobStoreContext.class))
                .defaultModules(

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/155fc112/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/binders/ComposeObjectBinder.java
----------------------------------------------------------------------
diff --git a/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/binders/ComposeObjectBinder.java b/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/binders/ComposeObjectBinder.java
new file mode 100644
index 0000000..9401ad6
--- /dev/null
+++ b/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/binders/ComposeObjectBinder.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.googlecloudstorage.binders;
+
+import java.util.Map;
+
+import javax.inject.Inject;
+
+import org.jclouds.googlecloudstorage.domain.templates.ComposeObjectTemplate;
+import org.jclouds.http.HttpRequest;
+import org.jclouds.rest.MapBinder;
+import org.jclouds.rest.binders.BindToJsonPayload;
+
+public class ComposeObjectBinder implements MapBinder {
+
+   @Inject
+   private BindToJsonPayload jsonBinder;
+
+   @Override
+   public <R extends HttpRequest> R bindToRequest(R request, Map<String, Object> postParams) throws IllegalArgumentException{
+      ComposeObjectTemplate postCompose = (ComposeObjectTemplate) postParams.get("template");
+      return bindToRequest(request, postCompose);
+   }
+
+   @Override
+   public <R extends HttpRequest> R bindToRequest(R request, Object input) {
+      return jsonBinder.bindToRequest(request, input);
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/155fc112/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/binders/UploadBinder.java
----------------------------------------------------------------------
diff --git a/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/binders/UploadBinder.java b/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/binders/UploadBinder.java
new file mode 100644
index 0000000..a218ec0
--- /dev/null
+++ b/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/binders/UploadBinder.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.googlecloudstorage.binders;
+
+import java.util.Map;
+
+import org.jclouds.http.HttpRequest;
+import org.jclouds.io.Payload;
+import org.jclouds.rest.MapBinder;
+
+public class UploadBinder implements MapBinder {
+
+   @Override
+   public <R extends HttpRequest> R bindToRequest(R request, Map<String, Object> postParams)
+            throws IllegalArgumentException {
+      Payload payload = (Payload) postParams.get("payload");
+
+      request.getPayload().getContentMetadata().setContentType(payload.getContentMetadata().getContentType());
+      request.setPayload(payload);
+      return bindToRequest(request, payload);
+   }
+
+   @Override
+   public <R extends HttpRequest> R bindToRequest(R request, Object input) {
+      return request;
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/155fc112/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/domain/DomainResourceRefferences.java
----------------------------------------------------------------------
diff --git a/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/domain/DomainResourceRefferences.java b/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/domain/DomainResourceRefferences.java
index dcb6910..82b3442 100644
--- a/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/domain/DomainResourceRefferences.java
+++ b/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/domain/DomainResourceRefferences.java
@@ -85,4 +85,21 @@ public final class DomainResourceRefferences {
          return valueOf(CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, predefinedAcl));
       }
    }
+
+   public enum DestinationPredefinedAcl {
+      AUTHENTICATED_READ, BUCKET_OWNER_FULLCONTROL, BUCKET_OWNER_READ, PRIVATE, PROJECT_PRIVATE, PUBLIC_READ;
+
+      public String value() {
+         return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, name());
+      }
+
+      @Override
+      public String toString() {
+         return value();
+      }
+
+      public static DestinationPredefinedAcl fromValue(String destinationPredefinedAcl) {
+         return valueOf(CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, destinationPredefinedAcl));
+      }
+   }
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/155fc112/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/domain/DomainUtils.java
----------------------------------------------------------------------
diff --git a/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/domain/DomainUtils.java b/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/domain/DomainUtils.java
new file mode 100644
index 0000000..d028e7b
--- /dev/null
+++ b/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/domain/DomainUtils.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.googlecloudstorage.domain;
+
+import java.util.List;
+
+import com.google.common.collect.Lists;
+import com.google.common.primitives.Bytes;
+
+public final class DomainUtils {
+
+   private DomainUtils() {
+   }
+
+   public static byte[] reverse(byte[] b) {
+      List<Byte> hashByte = Bytes.asList(b);
+      List<Byte> reversedList = Lists.reverse(hashByte);
+      return Bytes.toArray(reversedList);
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/155fc112/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/domain/GCSObject.java
----------------------------------------------------------------------
diff --git a/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/domain/GCSObject.java b/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/domain/GCSObject.java
new file mode 100644
index 0000000..6eb4b77
--- /dev/null
+++ b/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/domain/GCSObject.java
@@ -0,0 +1,376 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jclouds.googlecloudstorage.domain;
+
+import static com.google.common.base.Objects.equal;
+
+import java.net.URI;
+import java.util.Date;
+import java.util.Map;
+import java.util.Set;
+
+import org.jclouds.googlecloudstorage.domain.DomainResourceRefferences.StorageClass;
+import org.jclouds.googlecloudstorage.domain.internal.Owner;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.hash.HashCode;
+import com.google.common.io.BaseEncoding;
+import com.google.inject.Inject;
+
+/**
+ * This class represent an object in a Google Cloud Storage Bucket.
+ *
+ * @see <a href = "https://developers.google.com/storage/docs/json_api/v1/Objects"/>
+ */
+public class GCSObject extends Resource {
+
+   private final String name;
+   private final String bucket;
+   private final Long generation;
+   private final Long metageneration;
+   private final String contentType;
+   private final Date updated;
+   private final Date timeDeleted;
+   private final StorageClass storageClass;
+   private final Long size;
+   private final String md5Hash;
+   private final URI mediaLink;
+   private final Map<String, String> metadata;
+   private final String contentEncoding;
+   private final String contentDisposition;
+   private final String contentLanguage;
+   private final String cacheControl;
+   private final Set<ObjectAccessControls> acl;
+   private final Owner owner;
+   private final String crc32c;
+   private final Integer componentCount;
+
+   @Inject
+   private GCSObject(String id, URI selfLink, String etag, String name, String bucket, Long generation,
+            Long metageneration, String contentType, Date updated, Date timeDeleted, StorageClass storageClass,
+            Long size, String md5Hash, URI mediaLink, Map<String, String> metadata, String contentEncoding,
+            String contentDisposition, String contentLanguage, String cacheControl, Set<ObjectAccessControls> acl,
+            Owner owner, String crc32c, Integer componentCount) {
+      super(Kind.OBJECT, id, selfLink, etag);
+      this.name = name;
+      this.bucket = bucket;
+      this.generation = generation;
+      this.metageneration = metageneration;
+      this.contentType = contentType;
+      this.updated = updated;
+      this.timeDeleted = timeDeleted;
+      this.storageClass = storageClass;
+      this.size = size;
+      this.md5Hash = md5Hash;
+      this.mediaLink = mediaLink;
+      this.metadata = (metadata == null) ? ImmutableMap.<String, String> of() : metadata;
+      this.contentEncoding = contentEncoding;
+      this.contentDisposition = contentDisposition;
+      this.contentLanguage = contentLanguage;
+      this.cacheControl = cacheControl;
+      this.acl = acl;
+      this.owner = owner;
+      this.crc32c = crc32c;
+      this.componentCount = componentCount;
+   }
+
+   public String getName() {
+      return name;
+   }
+
+   public String getBucket() {
+      return bucket;
+   }
+
+   public Long getGeneration() {
+      return generation;
+   }
+
+   public Long getMetageneration() {
+      return metageneration;
+   }
+
+   public String getContentType() {
+      return contentType;
+   }
+
+   public Date getUpdated() {
+      return updated;
+   }
+
+   public Date getTimeDeleted() {
+      return timeDeleted;
+   }
+
+   public StorageClass getStorageClass() {
+      return storageClass;
+   }
+
+   public Long getSize() {
+      return size;
+   }
+
+   private String getMd5Hash() {
+      return md5Hash;
+   }
+
+   public HashCode getMd5HashCode() {
+      HashCode hc = HashCode.fromBytes(BaseEncoding.base64().decode(md5Hash));
+      return hc;
+   }
+
+   public URI getMediaLink() {
+      return mediaLink;
+   }
+
+   public Map<String, String> getAllMetadata() {
+      return this.metadata;
+   }
+
+   public String getContentEncoding() {
+      return contentEncoding;
+   }
+
+   public String getContentDisposition() {
+      return contentDisposition;
+   }
+
+   public String getContentLanguage() {
+      return contentLanguage;
+   }
+
+   public String getCacheControl() {
+      return cacheControl;
+   }
+
+   public Set<ObjectAccessControls> getAcl() {
+      return acl;
+   }
+
+   public Owner getOwner() {
+      return owner;
+   }
+
+   private String getCrc32c() {
+      return crc32c;
+   }
+
+   public HashCode getCrc32cHashcode() {
+      HashCode hc = HashCode.fromBytes(DomainUtils.reverse(BaseEncoding.base64().decode(crc32c)));
+      return hc;
+   }
+
+   public Integer getComponentCount() {
+      return componentCount;
+   }
+
+   @Override
+   public boolean equals(Object obj) {
+      if (this == obj)
+         return true;
+      if (obj == null || getClass() != obj.getClass())
+         return false;
+      GCSObject that = GCSObject.class.cast(obj);
+      return equal(this.kind, that.kind) && equal(this.name, that.name) && equal(this.bucket, that.bucket);
+
+   }
+
+   protected MoreObjects.ToStringHelper string() {
+      return super.string().omitNullValues().add("name", name).add("bucket", bucket).add("generation", generation)
+               .add("metageneration", metageneration).add("timeDeleted", timeDeleted).add("updated", updated)
+               .add("storageClass", storageClass).add("size", size).add("md5Hash", md5Hash).add("mediaLink", mediaLink)
+               .add("metadata", metadata).add("contentEncoding", contentEncoding)
+               .add("contentDisposition", contentDisposition).add("contentLanguage", contentLanguage)
+               .add("cacheControl", cacheControl).add("crc32c", crc32c).add("componentCount", componentCount)
+               .add("acl", acl).add("owner", owner);
+
+   }
+
+   @Override
+   public String toString() {
+      return string().toString();
+   }
+
+   public static Builder builder() {
+      return new Builder();
+   }
+
+   public Builder toBuilder() {
+      return new Builder().fromGCSObject(this);
+   }
+
+   protected static final class Builder extends Resource.Builder<Builder> {
+
+      private String name;
+      private String bucket;
+      private Long generation;
+      private Long metageneration;
+      private String contentType;
+      private Date updated;
+      private Date timeDeleted;
+      private StorageClass storageClass;
+      private Long size;
+      private String md5Hash;
+      private URI mediaLink;
+      private ImmutableMap.Builder<String, String> metadata = ImmutableMap.builder();
+      private String contentEncoding;
+      private String contentDisposition;
+      private String contentLanguage;
+      private String cacheControl;
+      private ImmutableSet.Builder<ObjectAccessControls> acl = ImmutableSet.builder();
+      private Owner owner;
+      private String crc32c;
+      private Integer componentCount;
+
+      protected Builder name(String name) {
+         this.name = name;
+         return this;
+      }
+
+      protected Builder bucket(String bucket) {
+         this.bucket = bucket;
+         return this;
+      }
+
+      protected Builder generation(Long generation) {
+         this.generation = generation;
+         return this;
+      }
+
+      protected Builder metageneration(Long metageneration) {
+         this.metageneration = metageneration;
+         return this;
+      }
+
+      protected Builder customMetadata(Map<String, String> metadata) {
+         this.metadata.putAll(metadata);
+         return this;
+      }
+
+      protected Builder addCustomMetadata(String key, String value) {
+         this.metadata.put(key, value);
+         return this;
+      }
+
+      protected Builder size(Long size) {
+         this.size = size;
+         return this;
+      }
+
+      protected Builder componentCount(Integer componentCount) {
+         this.componentCount = componentCount;
+         return this;
+      }
+
+      protected Builder contentType(String contentType) {
+         this.contentType = contentType;
+         return this;
+      }
+
+      /** Requires base64 encoded crc32c string */
+      protected Builder md5Hash(String md5Hash) {
+         this.md5Hash = md5Hash;
+         return this;
+      }
+
+      protected Builder mediaLink(URI mediaLink) {
+         this.mediaLink = mediaLink;
+         return this;
+      }
+
+      protected Builder contentEncoding(String contentEncoding) {
+         this.contentEncoding = contentEncoding;
+         return this;
+      }
+
+      protected Builder contentDisposition(String contentDisposition) {
+         this.contentDisposition = contentDisposition;
+         return this;
+      }
+
+      protected Builder contentLanguage(String contentLanguage) {
+         this.contentLanguage = contentLanguage;
+         return this;
+      }
+
+      protected Builder cacheControl(String cacheControl) {
+         this.cacheControl = cacheControl;
+         return this;
+      }
+
+      protected Builder updated(Date updated) {
+         this.updated = updated;
+         return this;
+      }
+
+      protected Builder timeDeleted(Date timeDeleted) {
+         this.timeDeleted = timeDeleted;
+         return this;
+      }
+
+      protected Builder owner(Owner owner) {
+         this.owner = owner;
+         return this;
+      }
+
+      protected Builder storageClass(StorageClass storageClass) {
+         this.storageClass = storageClass;
+         return this;
+      }
+
+      protected Builder addAcl(ObjectAccessControls bucketAccessControls) {
+         this.acl.add(bucketAccessControls);
+         return this;
+      }
+
+      protected Builder acl(Set<ObjectAccessControls> acl) {
+         this.acl.addAll(acl);
+         return this;
+      }
+
+      /** Requires base64 encoded crc32c string */
+      protected Builder crc32c(String crc32c) {
+         this.crc32c = crc32c;
+         return this;
+      }
+
+      @Override
+      protected Builder self() {
+         return this;
+      }
+
+      public GCSObject build() {
+         return new GCSObject(super.id, super.selfLink, super.etag, name, bucket, generation, metageneration,
+                  contentType, updated, timeDeleted, storageClass, size, md5Hash, mediaLink, metadata.build(),
+                  contentEncoding, contentDisposition, contentLanguage, cacheControl, acl.build(), owner, crc32c,
+                  componentCount);
+      }
+
+      protected Builder fromGCSObject(GCSObject in) {
+         return super.fromResource(in).name(in.getName()).bucket(in.getBucket()).generation(in.getGeneration())
+                  .metageneration(in.getMetageneration()).contentEncoding(in.getContentEncoding())
+                  .contentDisposition(in.getContentDisposition()).contentLanguage(in.getContentLanguage())
+                  .md5Hash(in.getMd5Hash()).mediaLink(in.getMediaLink()).timeDeleted(in.getTimeDeleted())
+                  .cacheControl(in.getCacheControl()).crc32c(in.getCrc32c()).size(in.getSize())
+                  .contentType(in.getContentType()).acl(in.getAcl()).owner(in.getOwner())
+                  .storageClass(in.getStorageClass()).customMetadata(in.getAllMetadata());
+      }
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/155fc112/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/domain/ListPage.java
----------------------------------------------------------------------
diff --git a/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/domain/ListPage.java b/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/domain/ListPage.java
index c10a13e..30b43f9 100644
--- a/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/domain/ListPage.java
+++ b/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/domain/ListPage.java
@@ -22,6 +22,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
 
 import java.beans.ConstructorProperties;
 import java.util.Iterator;
+import java.util.Set;
 
 import org.jclouds.collect.IterableWithMarker;
 import org.jclouds.googlecloudstorage.domain.Resource.Kind;
@@ -39,19 +40,29 @@ public class ListPage<T> extends IterableWithMarker<T> {
    private final Kind kind;
    private final String nextPageToken;
    private final Iterable<T> items;
+   private final Set<String> prefixes;
 
-   @ConstructorProperties({ "kind", "nextPageToken", "items" })
-   protected ListPage(Kind kind, String nextPageToken, Iterable<T> items) {
+   @ConstructorProperties({ "kind", "nextPageToken", "items", "prefixes" })
+   protected ListPage(Kind kind, String nextPageToken, Iterable<T> items, Set<String> prefixes) {
 
       this.kind = checkNotNull(kind, "kind");
       this.nextPageToken = nextPageToken;
       this.items = items != null ? ImmutableSet.copyOf(items) : ImmutableSet.<T> of();
-   }
+      this.prefixes = prefixes != null ? prefixes : ImmutableSet.<String> of();
+    }
 
    public Kind getKind() {
       return kind;
    }
 
+   public String getNextPageToken() {
+      return nextPageToken;
+   }
+
+   public Set<String> getPrefixes() {
+      return prefixes;
+   }
+
    @Override
    public Optional<Object> nextMarker() {
       return Optional.<Object> fromNullable(nextPageToken);
@@ -100,6 +111,7 @@ public class ListPage<T> extends IterableWithMarker<T> {
       private Kind kind;
       private String nextPageToken;
       private ImmutableSet.Builder<T> items = ImmutableSet.builder();
+      private ImmutableSet.Builder<String> prefixes = ImmutableSet.builder();
 
       public Builder<T> kind(Kind kind) {
          this.kind = kind;
@@ -116,17 +128,23 @@ public class ListPage<T> extends IterableWithMarker<T> {
          return this;
       }
 
+      public Builder<T> prefixes(Set<String> prefixes) {
+         this.prefixes.addAll(prefixes);
+         return this;
+      }
+
       public Builder<T> nextPageToken(String nextPageToken) {
          this.nextPageToken = nextPageToken;
          return this;
       }
 
       public ListPage<T> build() {
-         return new ListPage<T>(kind, nextPageToken, items.build());
+         return new ListPage<T>(kind, nextPageToken, items.build(), prefixes.build());
       }
 
       public Builder<T> fromPagedList(ListPage<T> in) {
-         return this.kind(in.getKind()).nextPageToken((String) in.nextMarker().orNull()).items(in);
+         return this.kind(in.getKind()).nextPageToken((String) in.nextMarker().orNull()).items(in)
+                  .prefixes(in.getPrefixes());
 
       }
    }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/155fc112/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/domain/Resource.java
----------------------------------------------------------------------
diff --git a/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/domain/Resource.java b/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/domain/Resource.java
index c8d559b..196f831 100644
--- a/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/domain/Resource.java
+++ b/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/domain/Resource.java
@@ -39,7 +39,11 @@ import com.google.common.collect.Iterables;
 public class Resource {
 
    public enum Kind {
-      BUCKET_ACCESS_CONTROL, BUCKET_ACCESS_CONTROLS, BUCKET, BUCKETS, OBJECT_ACCESS_CONTROL, OBJECT_ACCESS_CONTROLS, OBJECT;
+      BUCKET_ACCESS_CONTROL, BUCKET_ACCESS_CONTROLS,
+      BUCKET, BUCKETS,
+      OBJECT_ACCESS_CONTROL, OBJECT_ACCESS_CONTROLS,
+      OBJECT, OBJECTS,
+      COMPOSE_REQUEST;
 
       public String value() {
          return Joiner.on("#").join("storage", CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, name()));
@@ -51,10 +55,8 @@ public class Resource {
       }
 
       public static Kind fromValue(String kind) {
-         return valueOf(CaseFormat.LOWER_CAMEL.to(CaseFormat
-                 .UPPER_UNDERSCORE,
-                 Iterables.getLast(Splitter.on("#").split(checkNotNull(kind,
-                         "kind")))));
+         return valueOf(CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE,
+                  Iterables.getLast(Splitter.on("#").split(checkNotNull(kind, "kind")))));
       }
    }
 

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/155fc112/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/domain/templates/ComposeObjectTemplate.java
----------------------------------------------------------------------
diff --git a/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/domain/templates/ComposeObjectTemplate.java b/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/domain/templates/ComposeObjectTemplate.java
new file mode 100644
index 0000000..b4d1e47
--- /dev/null
+++ b/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/domain/templates/ComposeObjectTemplate.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jclouds.googlecloudstorage.domain.templates;
+
+import java.util.Set;
+
+import org.jclouds.googlecloudstorage.domain.GCSObject;
+import org.jclouds.googlecloudstorage.domain.Resource.Kind;
+
+import com.google.common.collect.Sets;
+
+public class ComposeObjectTemplate {
+
+   protected Kind kind;
+   protected ObjectTemplate destination;
+   protected Set<GCSObject> sourceObjects = Sets.newHashSet();
+
+   public ComposeObjectTemplate() {
+      this.kind = Kind.COMPOSE_REQUEST;
+   }
+
+   public ComposeObjectTemplate destination(ObjectTemplate destination) {
+      this.destination = destination;
+      return this;
+   }
+
+   public ComposeObjectTemplate addsourceObject(GCSObject sourceObject) {
+      this.sourceObjects.add(sourceObject);
+      return this;
+   }
+
+   public ComposeObjectTemplate sourceObjects(Set<GCSObject> sourceObjects) {
+      this.sourceObjects.addAll(sourceObjects);
+      return this;
+   }
+
+   public Kind getKind() {
+      return kind;
+   }
+
+   public ObjectTemplate getDestination() {
+      return destination;
+   }
+
+   public Set<GCSObject> getSourceObjects() {
+      return sourceObjects;
+   }
+
+   public static Builder builder() {
+      return new Builder();
+   }
+
+   public static ComposeObjectTemplate fromComposeObjectTemplate(ComposeObjectTemplate composeTemplate) {
+      return Builder.fromComposeObjectTemplate(composeTemplate);
+   }
+
+   public static class Builder {
+
+      public static ComposeObjectTemplate fromComposeObjectTemplate(ComposeObjectTemplate in) {
+         return new ComposeObjectTemplate().sourceObjects(in.getSourceObjects()).destination(in.getDestination());
+
+      }
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/155fc112/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/domain/templates/ObjectTemplate.java
----------------------------------------------------------------------
diff --git a/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/domain/templates/ObjectTemplate.java b/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/domain/templates/ObjectTemplate.java
new file mode 100644
index 0000000..84e69fd
--- /dev/null
+++ b/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/domain/templates/ObjectTemplate.java
@@ -0,0 +1,181 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jclouds.googlecloudstorage.domain.templates;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.jclouds.googlecloudstorage.domain.DomainUtils;
+import org.jclouds.googlecloudstorage.domain.ObjectAccessControls;
+
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import com.google.common.hash.HashCode;
+import com.google.common.io.BaseEncoding;
+import com.google.common.net.MediaType;
+
+public class ObjectTemplate {
+
+   protected String name;
+   protected Long size;
+   protected String cacheControl;
+   protected String contentDisposition;
+   protected String contentEncoding;
+   protected String contentLanguage;
+   protected String contentType;
+   protected String crc32c;
+   protected String md5Hash;
+   private Map<String, String> metadata = Maps.newHashMap();
+   protected Set<ObjectAccessControls> acl = Sets.newHashSet();
+
+   public ObjectTemplate name(String name) {
+      this.name = name;
+      return this;
+   }
+
+   public ObjectTemplate size(Long size) {
+      this.size = size;
+      return this;
+   }
+
+   public ObjectTemplate cacheControl(String cacheControl) {
+      this.cacheControl = cacheControl;
+      return this;
+   }
+
+   public ObjectTemplate contentDisposition(String contentDisposition) {
+      this.contentDisposition = contentDisposition;
+      return this;
+   }
+
+   public ObjectTemplate contentEncoding(String contentEncoding) {
+      this.contentEncoding = contentEncoding;
+      return this;
+   }
+
+   public ObjectTemplate contentLanguage(String contentLanguage) {
+      this.contentLanguage = contentLanguage;
+      return this;
+   }
+
+   public ObjectTemplate contentType(MediaType contentType) {
+      this.contentType = contentType.toString();
+      return this;
+   }
+
+   public ObjectTemplate contentType(String contentType) {
+      this.contentType = contentType;
+      return this;
+   }
+
+   public ObjectTemplate customMetadata(Map<String, String> metadata) {
+      this.metadata.putAll(metadata);
+      return this;
+   }
+
+   public ObjectTemplate customMetadata(String key, String value) {
+      this.metadata.put(key, value);
+      return this;
+   }
+
+   public ObjectTemplate crc32c(HashCode crc32c) {
+      this.crc32c = BaseEncoding.base64().encode(DomainUtils.reverse(crc32c.asBytes()));
+      return this;
+   }
+
+   public ObjectTemplate md5Hash(HashCode md5Hash) {
+      this.md5Hash = BaseEncoding.base64().encode(md5Hash.asBytes());
+      return this;
+   }
+
+   public ObjectTemplate addAcl(ObjectAccessControls acl) {
+      this.acl.add(acl);
+      return this;
+   }
+
+   public ObjectTemplate acl(Set<ObjectAccessControls> acl) {
+      this.acl.addAll(acl);
+      return this;
+   }
+
+   public String getCacheControl() {
+      return cacheControl;
+   }
+
+   public String getContentDisposition() {
+      return contentDisposition;
+   }
+
+   public String getContentEncoding() {
+      return contentEncoding;
+   }
+
+   public String getContentLanguage() {
+      return contentLanguage;
+   }
+
+   public String getContentType() {
+      return contentType;
+   }
+
+   public HashCode getCrc32cHashcode() {
+      HashCode hc = HashCode.fromBytes(DomainUtils.reverse(BaseEncoding.base64().decode(crc32c)));
+      return hc;
+   }
+
+   public HashCode getMd5HashCode() {
+      HashCode hc = HashCode.fromBytes(BaseEncoding.base64().decode(md5Hash));
+      return hc;
+   }
+
+   public Map<String, String> getAllCustomMetadata() {
+      return metadata;
+   }
+
+   public String getName() {
+      return name;
+   }
+
+   public Long getSize() {
+      return size;
+   }
+
+   public Set<ObjectAccessControls> getAcl() {
+      return acl;
+   }
+
+   public static Builder builder() {
+      return new Builder();
+   }
+
+   public static ObjectTemplate fromObjectTemplate(ObjectTemplate objectTemplate) {
+      return Builder.fromObjectTemplate(objectTemplate);
+   }
+
+   public static class Builder {
+
+      public static ObjectTemplate fromObjectTemplate(ObjectTemplate in) {
+         return new ObjectTemplate().name(in.getName()).size(in.getSize()).acl(in.getAcl())
+                  .cacheControl(in.getCacheControl()).contentDisposition(in.getContentDisposition())
+                  .contentEncoding(in.getContentEncoding()).contentLanguage(in.getContentLanguage())
+                  .contentType(in.getContentType()).md5Hash(in.getMd5HashCode())
+                  .customMetadata(in.getAllCustomMetadata()).crc32c(in.getCrc32cHashcode());
+
+      }
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/155fc112/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/features/ObjectApi.java
----------------------------------------------------------------------
diff --git a/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/features/ObjectApi.java b/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/features/ObjectApi.java
new file mode 100644
index 0000000..a04d9ba
--- /dev/null
+++ b/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/features/ObjectApi.java
@@ -0,0 +1,462 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.googlecloudstorage.features;
+
+import static org.jclouds.googlecloudstorage.reference.GoogleCloudStorageConstants.STORAGE_FULLCONTROL_SCOPE;
+import static org.jclouds.googlecloudstorage.reference.GoogleCloudStorageConstants.STORAGE_WRITEONLY_SCOPE;
+
+import javax.inject.Named;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.HeaderParam;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+import org.jclouds.Fallbacks.FalseOnNotFoundOr404;
+import org.jclouds.Fallbacks.NullOnNotFoundOr404;
+import org.jclouds.Fallbacks.TrueOnNotFoundOr404;
+import org.jclouds.googlecloudstorage.binders.ComposeObjectBinder;
+import org.jclouds.googlecloudstorage.binders.UploadBinder;
+import org.jclouds.googlecloudstorage.domain.GCSObject;
+import org.jclouds.googlecloudstorage.domain.ListPage;
+import org.jclouds.googlecloudstorage.domain.templates.ComposeObjectTemplate;
+import org.jclouds.googlecloudstorage.domain.templates.ObjectTemplate;
+import org.jclouds.googlecloudstorage.options.ComposeObjectOptions;
+import org.jclouds.googlecloudstorage.options.CopyObjectOptions;
+import org.jclouds.googlecloudstorage.options.DeleteObjectOptions;
+import org.jclouds.googlecloudstorage.options.GetObjectOptions;
+import org.jclouds.googlecloudstorage.options.InsertObjectOptions;
+import org.jclouds.googlecloudstorage.options.ListObjectOptions;
+import org.jclouds.googlecloudstorage.options.UpdateObjectOptions;
+import org.jclouds.googlecloudstorage.parser.ParseToPayloadEnclosing;
+import org.jclouds.http.internal.PayloadEnclosingImpl;
+import org.jclouds.io.Payload;
+import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.oauth.v2.config.OAuthScopes;
+import org.jclouds.oauth.v2.filters.OAuthAuthenticator;
+import org.jclouds.rest.annotations.BinderParam;
+import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.annotations.MapBinder;
+import org.jclouds.rest.annotations.PATCH;
+import org.jclouds.rest.annotations.PayloadParam;
+import org.jclouds.rest.annotations.RequestFilters;
+import org.jclouds.rest.annotations.ResponseParser;
+import org.jclouds.rest.annotations.SkipEncoding;
+import org.jclouds.rest.annotations.QueryParams;
+import org.jclouds.rest.binders.BindToJsonPayload;
+
+/**
+ * Provides access to Object entities via their REST API.
+ *
+ * @see <a href="https://developers.google.com/storage/docs/json_api/v1/objects"/>
+ */
+
+@SkipEncoding({ '/', '=' })
+@RequestFilters(OAuthAuthenticator.class)
+public interface ObjectApi {
+
+   /**
+    * Check the existence of an object
+    *
+    * @param bucketName
+    *           Name of the bucket in which the object resides
+    * @param objectName
+    *           Name of the object
+    *
+    * @return a {@link Object} true if object exists
+    */
+   @Named("Object:Exist")
+   @GET
+   @Consumes(MediaType.APPLICATION_JSON)
+   @Path("storage/v1/b/{bucket}/o/{object}")
+   @OAuthScopes(STORAGE_FULLCONTROL_SCOPE)
+   @Fallback(FalseOnNotFoundOr404.class)
+   @Nullable
+   boolean objectExist(@PathParam("bucket") String bucketName, @PathParam("object") String objectName);
+
+   /**
+    * Retrieve an object metadata
+    *
+    * @param bucketName
+    *           Name of the bucket in which the object resides
+    * @param objectName
+    *           Name of the object
+    *
+    * @return a {@link Object} resource
+    */
+   @Named("Object:get")
+   @GET
+   @Consumes(MediaType.APPLICATION_JSON)
+   @Produces(MediaType.APPLICATION_JSON)
+   @Path("storage/v1/b/{bucket}/o/{object}")
+   @OAuthScopes(STORAGE_FULLCONTROL_SCOPE)
+   @Fallback(NullOnNotFoundOr404.class)
+   @Nullable
+   GCSObject getObject(@PathParam("bucket") String bucketName, @PathParam("object") String objectName);
+
+   /**
+    * Retrieves objects metadata
+    *
+    * @param bucketName
+    *           Name of the bucket in which the object resides
+    * @param objectName
+    *           Name of the object
+    * @param options
+    *           Supply {@link GetObjectOptions} with optional query parameters
+    *
+    * @return a {@link GCSObject}
+    */
+   @Named("Object:get")
+   @GET
+   @Consumes(MediaType.APPLICATION_JSON)
+   @Produces(MediaType.APPLICATION_JSON)
+   @Path("storage/v1/b/{bucket}/o/{object}")
+   @OAuthScopes(STORAGE_FULLCONTROL_SCOPE)
+   @Fallback(NullOnNotFoundOr404.class)
+   @Nullable
+   GCSObject getObject(@PathParam("bucket") String bucketName, @PathParam("object") String objectName,
+            GetObjectOptions options);
+
+   /**
+    * Retrieve an object or their metadata
+    *
+    * @param bucketName
+    *           Name of the bucket in which the object resides
+    * @param objectName
+    *           Name of the object
+    *
+    * @return a {@link Object} resource
+    */
+   @Named("Object:get")
+   @GET
+   @QueryParams(keys = "alt", values = "media")
+   @Path("storage/v1/b/{bucket}/o/{object}")
+   @OAuthScopes(STORAGE_FULLCONTROL_SCOPE)
+   @ResponseParser(ParseToPayloadEnclosing.class)
+   @Fallback(NullOnNotFoundOr404.class)
+   @Nullable
+   PayloadEnclosingImpl download(@PathParam("bucket") String bucketName, @PathParam("object") String objectName);
+
+   /**
+    * Retrieves objects
+    *
+    * @param bucketName
+    *           Name of the bucket in which the object resides
+    * @param objectName
+    *           Name of the object
+    * @param options
+    *           Supply {@link GetObjectOptions} with optional query parameters
+    *
+    * @return a {@link GCSObject}
+    */
+   @Named("Object:get")
+   @GET
+   @QueryParams(keys = "alt", values = "media")
+   @Consumes(MediaType.APPLICATION_JSON)
+   @Produces(MediaType.APPLICATION_JSON)
+   @Path("storage/v1/b/{bucket}/o/{object}")
+   @ResponseParser(ParseToPayloadEnclosing.class)
+   @OAuthScopes(STORAGE_FULLCONTROL_SCOPE)
+   @Fallback(NullOnNotFoundOr404.class)
+   @Nullable
+   PayloadEnclosingImpl download(@PathParam("bucket") String bucketName, @PathParam("object") String objectName,
+            GetObjectOptions options);
+
+   /**
+    * Stores a new object.Bject metadata setting is not supported with simple uploads
+    *
+    * @see https://developers.google.com/storage/docs/json_api/v1/how-tos/upload#simple
+    *
+    * @param bucketName
+    *           Name of the bucket in which the object to be stored
+    * @param options
+    *           Supply an {@link InsertObjectOptions}. 'name' should not null.
+    *
+    * @return a {@link GCSObject}
+    */
+   @Named("Object:simpleUpload")
+   @POST
+   @QueryParams(keys = "uploadType", values = "media")
+   @Consumes(MediaType.APPLICATION_JSON)
+   @Path("/upload/storage/v1/b/{bucket}/o")
+   @OAuthScopes(STORAGE_FULLCONTROL_SCOPE)
+   @MapBinder(UploadBinder.class)
+   GCSObject simpleUpload(@PathParam("bucket") String bucketName, @HeaderParam("Content-Type") String contentType,
+            @HeaderParam("Content-Length") Long contentLength, @PayloadParam("payload") Payload payload,
+            InsertObjectOptions Options);
+
+   /**
+    * Deletes an object and its metadata. Deletions are permanent if versioning is not enabled.
+    *
+    * @param bucketName
+    *           Name of the bucket in which the object to be deleted resides
+    * @param objectName
+    *           Name of the object
+    */
+   @Named("Object:delete")
+   @DELETE
+   @Consumes(MediaType.APPLICATION_JSON)
+   @Path("storage/v1/b/{bucket}/o/{object}")
+   @Fallback(TrueOnNotFoundOr404.class)
+   @OAuthScopes(STORAGE_WRITEONLY_SCOPE)
+    boolean deleteObject(@PathParam("bucket") String bucketName, @PathParam("object") String objectName);
+
+   /**
+    * Deletes an object and its metadata. Deletions are permanent if versioning is not enabled for the bucket, or if the
+    * generation parameter is used.
+    *
+    * @param bucketName
+    *           Name of the bucket in which the object to be deleted resides
+    * @param objectName
+    *           Name of the object
+    * @param options
+    *           Supply {@link DeletObjectOptions} with optional query parameters
+    */
+   @Named("Object:delete")
+   @DELETE
+   @Consumes(MediaType.APPLICATION_JSON)
+   @Path("storage/v1/b/{bucket}/o/{object}")
+   @Fallback(TrueOnNotFoundOr404.class)
+   @OAuthScopes(STORAGE_WRITEONLY_SCOPE)
+   boolean deleteObject(@PathParam("bucket") String bucketName, @PathParam("object") String objectName,
+            DeleteObjectOptions options);
+
+   /**
+    * Retrieves a list of objects matching the criteria.
+    *
+    * @param bucketName
+    *           Name of the bucket in which to look for objects.
+    *
+    * @return a {@link ListPage<Object>}
+    */
+   @Named("Object:list")
+   @GET
+   @Consumes(MediaType.APPLICATION_JSON)
+   @Produces(MediaType.APPLICATION_JSON)
+   @Path("storage/v1/b/{bucket}/o")
+   @OAuthScopes(STORAGE_FULLCONTROL_SCOPE)
+   ListPage<GCSObject> listObjects(@PathParam("bucket") String bucketName);
+
+   /**
+    * Retrieves a list of objects matching the criteria.
+    *
+    * @param bucketName
+    *           Name of the bucket in which to look for objects.
+    * @param options
+    *          Supply {@link ListObjectOptions}
+    * @return a {@link ListPage<GCSObject>}
+    */
+   @Named("Object:list")
+   @GET
+   @Consumes(MediaType.APPLICATION_JSON)
+   @Produces(MediaType.APPLICATION_JSON)
+   @Path("storage/v1/b/{bucket}/o")
+   @OAuthScopes(STORAGE_FULLCONTROL_SCOPE)
+   ListPage<GCSObject> listObjects(@PathParam("bucket") String bucketName, ListObjectOptions options);
+
+   /**
+    * Updates an object metadata
+    *
+    * @param bucketName
+    *           Name of the bucket in which the object resides
+    * @param objectName
+    *           Name of the object
+    * @param objectTemplate
+    *           Supply  an {@link ObjectTemplate}
+    *
+    * @return a {@link GCSObject}
+    */
+   @Named("Object:update")
+   @PUT
+   @Consumes(MediaType.APPLICATION_JSON)
+   @Produces(MediaType.APPLICATION_JSON)
+   @Path("storage/v1/b/{bucket}/o/{object}")
+   @OAuthScopes(STORAGE_FULLCONTROL_SCOPE)
+   @Fallback(NullOnNotFoundOr404.class)
+   GCSObject updateObject(@PathParam("bucket") String bucketName, @PathParam("object") String objectName,
+            @BinderParam(BindToJsonPayload.class) ObjectTemplate objectTemplate);
+
+   /**
+    * Updates an object
+    *
+    * @param bucketName
+    *           Name of the bucket in which the object resides
+    * @param objectName
+    *           Name of the object
+    * @param objectTemplate
+    *           Supply an{@link ObjectTemplate}
+    * @param options
+    *           Supply {@link UpdateObjectOptions} with optional query parameters
+    *
+    * @return a {@link GCSObject} .
+    */
+   @Named("Object:update")
+   @PUT
+   @Consumes(MediaType.APPLICATION_JSON)
+   @Produces(MediaType.APPLICATION_JSON)
+   @Path("storage/v1/b/{bucket}/o/{object}")
+   @OAuthScopes(STORAGE_FULLCONTROL_SCOPE)
+   @Fallback(NullOnNotFoundOr404.class)
+   GCSObject updateObject(@PathParam("bucket") String bucketName, @PathParam("object") String objectName,
+            @BinderParam(BindToJsonPayload.class) ObjectTemplate objectTemplate, UpdateObjectOptions options);
+
+   /**
+    * Updates an object according to patch semantics
+    *
+    * @param bucketName
+    *           Name of the bucket in which the object resides
+    * @param objectName
+    *           Name of the object
+    * @param objectTemplate
+    *           Supply {@link ObjectTemplate} with optional query parameters
+    *
+    * @return  a {@link GCSObject}
+    */
+   @Named("Object:patch")
+   @PATCH
+   @Consumes(MediaType.APPLICATION_JSON)
+   @Produces(MediaType.APPLICATION_JSON)
+   @Path("storage/v1/b/{bucket}/o/{object}")
+   @OAuthScopes(STORAGE_FULLCONTROL_SCOPE)
+   @Fallback(NullOnNotFoundOr404.class)
+   GCSObject patchObject(@PathParam("bucket") String bucketName, @PathParam("object") String objectName,
+            @BinderParam(BindToJsonPayload.class) ObjectTemplate objectTemplate);
+
+   /**
+    * Updates an object according to patch semantics
+    *
+    * @param bucketName
+    *           Name of the bucket in which the object resides
+    * @param objectName
+    *           Name of the object
+    * @param objectTemplate
+    *           Supply {@link ObjectTemplate} with optional query parameters
+    * @param options
+    *           Supply {@link UpdateObjectOptions} with optional query parameters
+    *
+    * @return a {@link GCSObject}
+    */
+   @Named("Object:patch")
+   @PUT
+   @Consumes(MediaType.APPLICATION_JSON)
+   @Produces(MediaType.APPLICATION_JSON)
+   @Path("storage/v1/b/{bucket}/o/{object}")
+   @OAuthScopes(STORAGE_FULLCONTROL_SCOPE)
+   @Fallback(NullOnNotFoundOr404.class)
+   GCSObject patchObject(@PathParam("bucket") String bucketName, @PathParam("object") String objectName,
+            @BinderParam(BindToJsonPayload.class) ObjectTemplate objectTemplate, UpdateObjectOptions options);
+
+   /**
+    * Concatenates a list of existing objects into a new object in the same bucket.
+    *
+    * @param destinationBucket
+    *           Name of the bucket in which the object to be stored
+    * @param destinationObject
+    *           The type of upload request.
+    * @param composeObjectTemplate
+    *           Supply a {@link ComposeObjectTemplate}
+    *
+    * @return a {@link GCSObject}
+    */
+   @Named("Object:compose")
+   @POST
+   @Consumes(MediaType.APPLICATION_JSON)
+   @Path("storage/v1/b/{destinationBucket}/o/{destinationObject}/compose")
+   @OAuthScopes(STORAGE_FULLCONTROL_SCOPE)
+   @MapBinder(ComposeObjectBinder.class)
+   GCSObject composeObjects(@PathParam("destinationBucket") String destinationBucket,
+            @PathParam("destinationObject") String destinationObject,
+            @PayloadParam("template") ComposeObjectTemplate composeObjectTemplate);
+
+   /**
+    * Concatenates a list of existing objects into a new object in the same bucket.
+    *
+    * @param destinationBucket
+    *           Name of the bucket in which the object to be stored
+    * @param destinationObject
+    *           The type of upload request.
+    * @param composeObjectTemplate
+    *           Supply a {@link ComposeObjectTemplate}
+    * @param options
+    *           Supply an {@link ComposeObjectOptions}
+    *
+    * @return a {@link GCSObject}
+    */
+   @Named("Object:compose")
+   @POST
+   @Consumes(MediaType.APPLICATION_JSON)
+   @Path("storage/v1/b/{destinationBucket}/o/{destinationObject}/compose")
+   @OAuthScopes(STORAGE_FULLCONTROL_SCOPE)
+   @MapBinder(ComposeObjectBinder.class)
+   GCSObject composeObjects(@PathParam("destinationBucket") String destinationBucket,
+            @PathParam("destinationObject") String destinationObject,
+            @PayloadParam("template") ComposeObjectTemplate composeObjectTemplate, ComposeObjectOptions options);
+
+   /**
+    * Copies an object to a specified location. Optionally overrides metadata.
+    *
+    * @param destinationBucket
+    *           Name of the bucket in which to store the new object
+    * @param destinationObject
+    *           Name of the new object.
+    * @param sourceBucket
+    *           Name of the bucket in which to find the source object
+    * @param sourceObject
+    *           Name of the source object
+    *
+    * @return a {@link GCSObject}
+    */
+   @Named("Object:copy")
+   @POST
+   @Consumes(MediaType.APPLICATION_JSON)
+   @Path("/storage/v1/b/{sourceBucket}/o/{sourceObject}/copyTo/b/{destinationBucket}/o/{destinationObject}")
+   @OAuthScopes(STORAGE_FULLCONTROL_SCOPE)
+   GCSObject copyObject(@PathParam("destinationBucket") String destinationBucket,
+            @PathParam("destinationObject") String destinationObject, @PathParam("sourceBucket") String sourceBucket,
+            @PathParam("sourceObject") String sourceObject);
+
+   /**
+    * Copies an object to a specified location. Optionally overrides metadata.
+    *
+    * @param destinationBucket
+    *           Name of the bucket in which to store the new object
+    * @param destinationObject
+    *           Name of the new object.
+    * @param sourceBucket
+    *           Name of the bucket in which to find the source object
+    * @param sourceObject
+    *           Name of the source object
+    * @param options
+    *           Supply a {@link CopyObjectOptions}
+    *
+    * @return a {@link GCSObject}
+    */
+   @Named("Object:copy")
+   @POST
+   @Consumes(MediaType.APPLICATION_JSON)
+   @Path("/storage/v1/b/{sourceBucket}/o/{sourceObject}/copyTo/b/{destinationBucket}/o/{destinationObject}")
+   @OAuthScopes(STORAGE_FULLCONTROL_SCOPE)
+   GCSObject copyObject(@PathParam("destinationBucket") String destinationBucket,
+            @PathParam("destinationObject") String destinationObject, @PathParam("sourceBucket") String sourceBucket,
+            @PathParam("sourceObject") String sourceObject, CopyObjectOptions options);
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/155fc112/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/options/ComposeObjectOptions.java
----------------------------------------------------------------------
diff --git a/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/options/ComposeObjectOptions.java b/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/options/ComposeObjectOptions.java
new file mode 100644
index 0000000..584470d
--- /dev/null
+++ b/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/options/ComposeObjectOptions.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.googlecloudstorage.options;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import org.jclouds.googlecloudstorage.domain.DomainResourceRefferences.DestinationPredefinedAcl;
+import org.jclouds.http.options.BaseHttpRequestOptions;
+
+/**
+ * Allows to optionally specify ifMetagenerationMatch,ifMetagenerationNotMatch and destinationPredefinedAcl when
+ * ComposingObjects operation.
+ */
+public class ComposeObjectOptions extends BaseHttpRequestOptions {
+
+   public ComposeObjectOptions ifMetagenerationMatch(Long ifMetagenerationMatch) {
+      this.queryParameters.put("ifMetagenerationMatch", checkNotNull(ifMetagenerationMatch, "ifMetagenerationMatch")
+               + "");
+      return this;
+   }
+
+   public ComposeObjectOptions ifMetagenerationNotMatch(Long ifMetagenerationNotMatch) {
+      this.queryParameters.put("ifMetagenerationNotMatch",
+               checkNotNull(ifMetagenerationNotMatch, "ifMetagenerationNotMatch") + "");
+      return this;
+   }
+
+   public ComposeObjectOptions destinationPredefinedAcl(DestinationPredefinedAcl destinationPredefinedAcl) {
+      this.queryParameters.put("destinationPredefinedAcl",
+               checkNotNull(destinationPredefinedAcl, "destinationPredefinedAcl").toString());
+      return this;
+   }
+
+   public static class Builder {
+
+      public ComposeObjectOptions ifMetagenerationMatch(Long ifMetagenerationMatch) {
+         return new ComposeObjectOptions().ifMetagenerationMatch(ifMetagenerationMatch);
+      }
+
+      public ComposeObjectOptions ifMetagenerationNotMatch(Long ifMetagenerationNotMatch) {
+         return new ComposeObjectOptions().ifMetagenerationNotMatch(ifMetagenerationNotMatch);
+      }
+
+      public ComposeObjectOptions destinationPredefinedAcl(DestinationPredefinedAcl destinationPredefinedAcl) {
+         return new ComposeObjectOptions().destinationPredefinedAcl(destinationPredefinedAcl);
+      }
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/155fc112/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/options/CopyObjectOptions.java
----------------------------------------------------------------------
diff --git a/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/options/CopyObjectOptions.java b/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/options/CopyObjectOptions.java
new file mode 100644
index 0000000..1c6bcd9
--- /dev/null
+++ b/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/options/CopyObjectOptions.java
@@ -0,0 +1,153 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.googlecloudstorage.options;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import org.jclouds.googlecloudstorage.domain.DomainResourceRefferences.PredefinedAcl;
+import org.jclouds.googlecloudstorage.domain.DomainResourceRefferences.Projection;
+import org.jclouds.http.options.BaseHttpRequestOptions;
+
+/**
+ * Allows to optionally specify ifMetagenerationMatch,ifMetagenerationNotMatch and projection which used in Bucket
+ */
+public class CopyObjectOptions extends BaseHttpRequestOptions {
+
+   public CopyObjectOptions contentEncoding(String contentEncoding) {
+      this.queryParameters.put("contentEncoding", checkNotNull(contentEncoding, "contentEncoding") + "");
+      return this;
+   }
+
+   public CopyObjectOptions name(String name) {
+      this.queryParameters.put("name", checkNotNull(name, "name") + "");
+      return this;
+   }
+
+   public CopyObjectOptions ifGenerationMatch(Long ifGenerationMatch) {
+      this.queryParameters.put("ifGenerationMatch", checkNotNull(ifGenerationMatch, "ifGenerationMatch") + "");
+      return this;
+   }
+
+   public CopyObjectOptions ifGenerationNotMatch(Long ifGenerationNotMatch) {
+      this.queryParameters.put("ifGenerationNotMatch", checkNotNull(ifGenerationNotMatch, "ifGenerationNotMatch") + "");
+      return this;
+   }
+
+   public CopyObjectOptions ifMetagenerationMatch(Long ifMetagenerationMatch) {
+      this.queryParameters.put("ifMetagenerationMatch", checkNotNull(ifMetagenerationMatch, "ifMetagenerationMatch")
+               + "");
+      return this;
+   }
+
+   public CopyObjectOptions ifMetagenerationNotMatch(Long ifMetagenerationNotMatch) {
+      this.queryParameters.put("ifMetagenerationNotMatch",
+               checkNotNull(ifMetagenerationNotMatch, "ifMetagenerationNotMatch") + "");
+      return this;
+   }
+   public CopyObjectOptions ifSourceGenerationMatch(Long ifSourceGenerationMatch) {
+      this.queryParameters.put("ifSourceGenerationMatch", checkNotNull(ifSourceGenerationMatch, "ifSourceGenerationMatch") + "");
+      return this;
+   }
+
+   public CopyObjectOptions ifSourceGenerationNotMatch(Long ifSourceGenerationNotMatch) {
+      this.queryParameters.put("ifSourceGenerationNotMatch", checkNotNull(ifSourceGenerationNotMatch, "ifSourceGenerationNotMatch") + "");
+      return this;
+   }
+
+   public CopyObjectOptions ifSourceMetagenerationMatch(Long ifSourceMetagenerationMatch) {
+      this.queryParameters.put("ifSourceMetagenerationMatch", checkNotNull(ifSourceMetagenerationMatch, "ifSourceMetagenerationMatch")
+               + "");
+      return this;
+   }
+
+   public CopyObjectOptions ifSourceMetagenerationNotMatch(Long ifSourceMetagenerationNotMatch) {
+      this.queryParameters.put("ifSourceMetagenerationNotMatch",
+               checkNotNull(ifSourceMetagenerationNotMatch, "ifSourceMetagenerationNotMatch") + "");
+      return this;
+   }
+
+   public CopyObjectOptions sourceGeneration(Long sourceGeneration) {
+      this.queryParameters.put("sourceGeneration", checkNotNull(sourceGeneration, "sourceGeneration") + "");
+      return this;
+   }
+
+   public CopyObjectOptions predefinedAcl(PredefinedAcl predefinedAcl) {
+      this.queryParameters.put("predefinedAcl", checkNotNull(predefinedAcl, "predefinedAcl").toString());
+      return this;
+   }
+
+   public CopyObjectOptions projection(Projection projection) {
+      this.queryParameters.put("projection", checkNotNull(projection, "projection").toString());
+      return this;
+   }
+
+   public static class Builder {
+
+      public CopyObjectOptions contentEncoding(String contentEncoding) {
+         return new CopyObjectOptions().contentEncoding(contentEncoding);
+      }
+
+      public CopyObjectOptions name(String name) {
+         return new CopyObjectOptions().name(name);
+      }
+
+      public CopyObjectOptions ifGenerationMatch(Long ifGenerationMatch) {
+         return new CopyObjectOptions().ifGenerationMatch(ifGenerationMatch);
+      }
+
+      public CopyObjectOptions ifGenerationNotMatch(Long ifGenerationNotMatch) {
+         return new CopyObjectOptions().ifGenerationNotMatch(ifGenerationNotMatch);
+      }
+
+      public CopyObjectOptions ifMetagenerationMatch(Long ifMetagenerationMatch) {
+         return new CopyObjectOptions().ifMetagenerationMatch(ifMetagenerationMatch);
+      }
+
+      public CopyObjectOptions ifMetagenerationNotMatch(Long ifMetagenerationNotMatch) {
+         return new CopyObjectOptions().ifMetagenerationNotMatch(ifMetagenerationNotMatch);
+      }
+
+      public CopyObjectOptions ifSourceGenerationMatch(Long ifSourceGenerationMatch) {
+         return new CopyObjectOptions().ifSourceGenerationMatch(ifSourceGenerationMatch);
+      }
+
+      public CopyObjectOptions ifSourceGenerationNotMatch(Long ifSourceGenerationNotMatch) {
+         return new CopyObjectOptions().ifSourceGenerationNotMatch(ifSourceGenerationNotMatch);
+      }
+
+      public CopyObjectOptions ifSourceMetagenerationMatch(Long ifSourceMetagenerationMatch) {
+         return new CopyObjectOptions().ifSourceMetagenerationMatch(ifSourceMetagenerationMatch);
+      }
+
+      public CopyObjectOptions ifSourceMetagenerationNotMatch(Long ifSourceMetagenerationNotMatch) {
+         return new CopyObjectOptions().ifSourceMetagenerationNotMatch(ifSourceMetagenerationNotMatch);
+      }
+
+
+      public CopyObjectOptions sourceGeneration(Long sourceGeneration) {
+         return new CopyObjectOptions().sourceGeneration(sourceGeneration);
+      }
+
+      public CopyObjectOptions predefinedAcl(PredefinedAcl predefinedAcl) {
+         return new CopyObjectOptions().predefinedAcl(predefinedAcl);
+      }
+
+      public UpdateObjectOptions projection(Projection projection) {
+         return new UpdateObjectOptions().projection(projection);
+      }
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/155fc112/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/options/DeleteObjectOptions.java
----------------------------------------------------------------------
diff --git a/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/options/DeleteObjectOptions.java b/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/options/DeleteObjectOptions.java
new file mode 100644
index 0000000..c0c7776
--- /dev/null
+++ b/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/options/DeleteObjectOptions.java
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.googlecloudstorage.options;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import org.jclouds.googlecloudstorage.domain.DomainResourceRefferences.PredefinedAcl;
+import org.jclouds.http.options.BaseHttpRequestOptions;
+
+/**
+ * Allows to optionally specify ifMetagenerationMatch,ifMetagenerationNotMatch and projection which used in Bucket
+ */
+public class DeleteObjectOptions extends BaseHttpRequestOptions {
+
+   public DeleteObjectOptions ifGenerationMatch(Long ifGenerationMatch) {
+      this.queryParameters.put("ifGenerationMatch", checkNotNull(ifGenerationMatch, "ifGenerationMatch") + "");
+      return this;
+   }
+
+   public DeleteObjectOptions ifGenerationNotMatch(Long ifGenerationNotMatch) {
+      this.queryParameters.put("ifGenerationNotMatch", checkNotNull(ifGenerationNotMatch, "ifGenerationNotMatch") + "");
+      return this;
+   }
+
+   public DeleteObjectOptions ifMetagenerationMatch(Long ifMetagenerationMatch) {
+      this.queryParameters.put("ifMetagenerationMatch", checkNotNull(ifMetagenerationMatch, "ifMetagenerationMatch")
+               + "");
+      return this;
+   }
+
+   public DeleteObjectOptions ifMetagenerationNotMatch(Long ifMetagenerationNotMatch) {
+      this.queryParameters.put("ifMetagenerationNotMatch",
+               checkNotNull(ifMetagenerationNotMatch, "ifMetagenerationNotMatch") + "");
+      return this;
+   }
+
+   public DeleteObjectOptions generation(Long generation) {
+      this.queryParameters.put("generation", checkNotNull(generation, "generation").toString());
+      return this;
+   }
+
+   public DeleteObjectOptions predefinedAcl(PredefinedAcl predefinedAcl) {
+      this.queryParameters.put("predefinedAcl", checkNotNull(predefinedAcl, "predefinedAcl").toString());
+      return this;
+   }
+
+   public static class Builder {
+
+      public DeleteObjectOptions ifGenerationMatch(Long ifGenerationMatch) {
+         return new DeleteObjectOptions().ifGenerationMatch(ifGenerationMatch);
+      }
+
+      public DeleteObjectOptions ifGenerationNotMatch(Long ifGenerationNotMatch) {
+         return new DeleteObjectOptions().ifGenerationNotMatch(ifGenerationNotMatch);
+      }
+
+      public DeleteObjectOptions ifMetagenerationMatch(Long ifMetagenerationMatch) {
+         return new DeleteObjectOptions().ifMetagenerationMatch(ifMetagenerationMatch);
+      }
+
+      public DeleteObjectOptions ifMetagenerationNotMatch(Long ifMetagenerationNotMatch) {
+         return new DeleteObjectOptions().ifMetagenerationNotMatch(ifMetagenerationNotMatch);
+      }
+
+      public DeleteObjectOptions generation(Long generation) {
+         return new DeleteObjectOptions().generation(generation);
+      }
+
+      public DeleteObjectOptions predefinedAcl(PredefinedAcl predefinedAcl) {
+         return new DeleteObjectOptions().predefinedAcl(predefinedAcl);
+      }
+
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/155fc112/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/options/GetObjectOptions.java
----------------------------------------------------------------------
diff --git a/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/options/GetObjectOptions.java b/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/options/GetObjectOptions.java
new file mode 100644
index 0000000..8fb22b8
--- /dev/null
+++ b/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/options/GetObjectOptions.java
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.googlecloudstorage.options;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import org.jclouds.googlecloudstorage.domain.DomainResourceRefferences.Projection;
+import org.jclouds.http.options.BaseHttpRequestOptions;
+
+/**
+ * Allows to optionally specify generation,ifGenerationMatch,ifGenerationNotMatch, ifMetagenerationMatch,ifMetagenerationNotMatch and projection which used in Bucket
+ */
+public class GetObjectOptions extends BaseHttpRequestOptions {
+
+   public GetObjectOptions ifGenerationMatch(Long ifGenerationMatch) {
+      this.queryParameters.put("ifGenerationMatch", checkNotNull(ifGenerationMatch, "ifGenerationMatch") + "");
+      return this;
+   }
+
+   public GetObjectOptions ifGenerationNotMatch(Long ifGenerationNotMatch) {
+      this.queryParameters.put("ifGenerationNotMatch", checkNotNull(ifGenerationNotMatch, "ifGenerationNotMatch") + "");
+      return this;
+   }
+
+   public GetObjectOptions ifMetagenerationMatch(Long ifMetagenerationMatch) {
+      this.queryParameters.put("ifMetagenerationMatch", checkNotNull(ifMetagenerationMatch, "ifMetagenerationMatch")
+               + "");
+      return this;
+   }
+
+   public GetObjectOptions ifMetagenerationNotMatch(Long ifMetagenerationNotMatch) {
+      this.queryParameters.put("ifMetagenerationNotMatch",
+               checkNotNull(ifMetagenerationNotMatch, "ifMetagenerationNotMatch") + "");
+      return this;
+   }
+
+   public GetObjectOptions generation(Long generation) {
+      this.queryParameters.put("generation", checkNotNull(generation, "generation").toString());
+      return this;
+   }
+
+   public GetObjectOptions projection(Projection projection) {
+      this.queryParameters.put("projection", checkNotNull(projection, "projection").toString());
+      return this;
+   }
+
+   public static class Builder {
+
+      public GetObjectOptions ifGenerationMatch(Long ifGenerationMatch) {
+         return new GetObjectOptions().ifGenerationMatch(ifGenerationMatch);
+      }
+
+      public GetObjectOptions ifGenerationNotMatch(Long ifGenerationNotMatch) {
+         return new GetObjectOptions().ifGenerationNotMatch(ifGenerationNotMatch);
+      }
+
+      public GetObjectOptions ifMetagenerationMatch(Long ifMetagenerationMatch) {
+         return new GetObjectOptions().ifMetagenerationMatch(ifMetagenerationMatch);
+      }
+
+      public GetObjectOptions ifMetagenerationNotMatch(Long ifMetagenerationNotMatch) {
+         return new GetObjectOptions().ifMetagenerationNotMatch(ifMetagenerationNotMatch);
+      }
+
+      public GetObjectOptions generation(Long generation) {
+         return new GetObjectOptions().generation(generation);
+      }
+
+      public GetObjectOptions projection(Projection projection) {
+         return new GetObjectOptions().projection(projection);
+      }
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/155fc112/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/options/InsertObjectOptions.java
----------------------------------------------------------------------
diff --git a/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/options/InsertObjectOptions.java b/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/options/InsertObjectOptions.java
new file mode 100644
index 0000000..a1d5554
--- /dev/null
+++ b/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/options/InsertObjectOptions.java
@@ -0,0 +1,115 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.googlecloudstorage.options;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import org.jclouds.googlecloudstorage.domain.DomainResourceRefferences.PredefinedAcl;
+import org.jclouds.googlecloudstorage.domain.DomainResourceRefferences.Projection;
+import org.jclouds.http.options.BaseHttpRequestOptions;
+
+/**
+ * Allows to optionally specify ifMetagenerationMatch,ifMetagenerationNotMatch and projection which used in Bucket
+ */
+public class InsertObjectOptions extends BaseHttpRequestOptions {
+
+   public InsertObjectOptions contentEncoding(String contentEncoding) {
+      this.queryParameters.put("contentEncoding", checkNotNull(contentEncoding, "contentEncoding") + "");
+      return this;
+   }
+
+   public InsertObjectOptions name(String name) {
+      this.queryParameters.put("name", checkNotNull(name, "name") + "");
+      return this;
+   }
+
+   public InsertObjectOptions ifGenerationMatch(Long ifGenerationMatch) {
+      this.queryParameters.put("ifGenerationMatch", checkNotNull(ifGenerationMatch, "ifGenerationMatch") + "");
+      return this;
+   }
+
+   public InsertObjectOptions ifGenerationNotMatch(Long ifGenerationNotMatch) {
+      this.queryParameters.put("ifGenerationNotMatch", checkNotNull(ifGenerationNotMatch, "ifGenerationNotMatch") + "");
+      return this;
+   }
+
+   public InsertObjectOptions ifMetagenerationMatch(Long ifMetagenerationMatch) {
+      this.queryParameters.put("ifMetagenerationMatch", checkNotNull(ifMetagenerationMatch, "ifMetagenerationMatch")
+               + "");
+      return this;
+   }
+
+   public InsertObjectOptions ifMetagenerationNotMatch(Long ifMetagenerationNotMatch) {
+      this.queryParameters.put("ifMetagenerationNotMatch",
+               checkNotNull(ifMetagenerationNotMatch, "ifMetagenerationNotMatch") + "");
+      return this;
+   }
+
+   public InsertObjectOptions generation(Long generation) {
+      this.queryParameters.put("generation", checkNotNull(generation, "generation").toString());
+      return this;
+   }
+
+   public InsertObjectOptions predefinedAcl(PredefinedAcl predefinedAcl) {
+      this.queryParameters.put("predefinedAcl", checkNotNull(predefinedAcl, "predefinedAcl").toString());
+      return this;
+   }
+
+   public InsertObjectOptions projection(Projection projection) {
+      this.queryParameters.put("projection", checkNotNull(projection, "projection").toString());
+      return this;
+   }
+
+   public static class Builder {
+
+      public InsertObjectOptions contentEncoding(String contentEncoding) {
+         return new InsertObjectOptions().contentEncoding(contentEncoding);
+      }
+
+      public InsertObjectOptions name(String name) {
+         return new InsertObjectOptions().name(name);
+      }
+
+      public InsertObjectOptions ifGenerationMatch(Long ifGenerationMatch) {
+         return new InsertObjectOptions().ifGenerationMatch(ifGenerationMatch);
+      }
+
+      public InsertObjectOptions ifGenerationNotMatch(Long ifGenerationNotMatch) {
+         return new InsertObjectOptions().ifGenerationNotMatch(ifGenerationNotMatch);
+      }
+
+      public InsertObjectOptions ifMetagenerationMatch(Long ifMetagenerationMatch) {
+         return new InsertObjectOptions().ifMetagenerationMatch(ifMetagenerationMatch);
+      }
+
+      public InsertObjectOptions ifMetagenerationNotMatch(Long ifMetagenerationNotMatch) {
+         return new InsertObjectOptions().ifMetagenerationNotMatch(ifMetagenerationNotMatch);
+      }
+
+      public InsertObjectOptions generation(Long generation) {
+         return new InsertObjectOptions().generation(generation);
+      }
+
+      public InsertObjectOptions predefinedAcl(PredefinedAcl predefinedAcl) {
+         return new InsertObjectOptions().predefinedAcl(predefinedAcl);
+      }
+
+      public UpdateObjectOptions projection(Projection projection) {
+         return new UpdateObjectOptions().projection(projection);
+      }
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/155fc112/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/options/ListObjectOptions.java
----------------------------------------------------------------------
diff --git a/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/options/ListObjectOptions.java b/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/options/ListObjectOptions.java
new file mode 100644
index 0000000..d3cb523
--- /dev/null
+++ b/google-cloud-storage/src/main/java/org/jclouds/googlecloudstorage/options/ListObjectOptions.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.googlecloudstorage.options;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import org.jclouds.googlecloudstorage.domain.DomainResourceRefferences.Projection;
+import org.jclouds.http.options.BaseHttpRequestOptions;
+
+public class ListObjectOptions extends BaseHttpRequestOptions {
+
+   public ListObjectOptions delimiter(String delimiter) {
+      this.queryParameters.put("delimiter", checkNotNull(delimiter, "delimiter"));
+      return this;
+   }
+
+   public ListObjectOptions prefix(String prefix) {
+      this.queryParameters.put("prefix", checkNotNull(prefix, "delimeter"));
+      return this;
+   }
+
+   public ListObjectOptions versions(Boolean versions) {
+      this.queryParameters.put("versions", checkNotNull(versions, "versions") + "");
+      return this;
+   }
+
+   public ListObjectOptions pageToken(String pageToken) {
+      this.queryParameters.put("pageToken", checkNotNull(pageToken, "pageToken"));
+      return this;
+   }
+
+   public ListObjectOptions maxResults(Integer maxResults) {
+      this.queryParameters.put("maxResults", checkNotNull(maxResults, "maxResults") + "");
+      return this;
+   }
+
+   public ListObjectOptions projection(Projection projection) {
+      this.queryParameters.put("projection", checkNotNull(projection, "projection").toString());
+      return this;
+   }
+
+   public static class Builder {
+
+      public ListObjectOptions delimiter(String delimiter) {
+         return new ListObjectOptions().delimiter(delimiter);
+      }
+
+      public ListObjectOptions prefix(String prefix) {
+         return new ListObjectOptions().prefix(prefix);
+      }
+
+      public ListObjectOptions versions(Boolean versions) {
+         return new ListObjectOptions().versions(versions);
+      }
+
+      public ListObjectOptions pageToken(String pageToken) {
+         return new ListObjectOptions().pageToken(pageToken);
+      }
+
+      public ListObjectOptions maxResults(Integer maxResults) {
+         return new ListObjectOptions().maxResults(maxResults);
+      }
+
+      public ListObjectOptions projection(Projection projection) {
+         return new ListObjectOptions().projection(projection);
+      }
+   }
+}