diff --git a/src/main/java/com/google/gcloud/datastore/DatastoreServiceFactory.java b/src/main/java/com/google/gcloud/datastore/DatastoreServiceFactory.java
index b2cd7c8eec11..ce0887792f98 100644
--- a/src/main/java/com/google/gcloud/datastore/DatastoreServiceFactory.java
+++ b/src/main/java/com/google/gcloud/datastore/DatastoreServiceFactory.java
@@ -17,7 +17,9 @@
package com.google.gcloud.datastore;
-
+/**
+ * A base class for DatasoreService factories.
+ */
public abstract class DatastoreServiceFactory {
private static final DatastoreServiceFactory INSTANCE = new DatastoreServiceFactory() {
diff --git a/src/main/java/com/google/gcloud/examples/DatastoreExample.java b/src/main/java/com/google/gcloud/examples/DatastoreExample.java
index e153bb5da85a..3d7feae66e8c 100644
--- a/src/main/java/com/google/gcloud/examples/DatastoreExample.java
+++ b/src/main/java/com/google/gcloud/examples/DatastoreExample.java
@@ -46,7 +46,7 @@
*
compile using maven - {@code mvn compile}
* run using maven - {@code mvn exec:java
* -Dexec.mainClass="com.google.gcloud.examples.DatastoreExample"
- * -Dexec.args="projectId [user] [delete|display|add comment]"}
+ * -Dexec.args="[projectId] [user] [delete|display|add comment]"}
*
*/
public class DatastoreExample {
@@ -174,25 +174,23 @@ public static void main(String... args) {
DatastoreAction action = null;
DatastoreService datastore = null;
Key key = null;
- if (args.length > 0) {
- String projectId = args[0];
- // If you want to access a local Datastore running via the gcd sdk, do
-// DatastoreServiceOptions options = DatastoreServiceOptions.builder()
-// .projectId(projectId)
-// .namespace(NAMESPACE)
-// .host("http://localhost:8080")
-// .build();
- DatastoreServiceOptions options = DatastoreServiceOptions.builder()
- .projectId(projectId)
- .namespace(NAMESPACE)
- .build();
- String name = args.length > 1 ? args[1] : System.getProperty("user.name");
- datastore = DatastoreServiceFactory.instance().get(options);
- KeyFactory keyFactory = datastore.newKeyFactory().kind(USER_KIND);
- key = keyFactory.newKey(name);
- String actionName = args.length > 2 ? args[2].toLowerCase() : DEFAULT_ACTION;
- action = ACTIONS.get(actionName);
- }
+ String projectId = args.length > 0 ? args[0] : null;
+ // If you want to access a local Datastore running via the gcd sdk, do
+ // DatastoreServiceOptions options = DatastoreServiceOptions.builder()
+ // .projectId(projectId)
+ // .namespace(NAMESPACE)
+ // .host("http://localhost:8080")
+ // .build();
+ DatastoreServiceOptions options = DatastoreServiceOptions.builder()
+ .projectId(projectId)
+ .namespace(NAMESPACE)
+ .build();
+ String name = args.length > 1 ? args[1] : System.getProperty("user.name");
+ datastore = DatastoreServiceFactory.instance().get(options);
+ KeyFactory keyFactory = datastore.newKeyFactory().kind(USER_KIND);
+ key = keyFactory.newKey(name);
+ String actionName = args.length > 2 ? args[2].toLowerCase() : DEFAULT_ACTION;
+ action = ACTIONS.get(actionName);
if (action == null) {
StringBuilder actionAndParams = new StringBuilder();
for (Map.Entry entry : ACTIONS.entrySet()) {
@@ -204,7 +202,7 @@ public static void main(String... args) {
actionAndParams.append('|');
}
actionAndParams.setLength(actionAndParams.length() - 1);
- System.out.printf("Usage: %s projectId [user] [%s]%n",
+ System.out.printf("Usage: %s [projectId] [user] [%s]%n",
DatastoreExample.class.getSimpleName(), actionAndParams);
return;
}
diff --git a/src/main/java/com/google/gcloud/examples/StorageExample.java b/src/main/java/com/google/gcloud/examples/StorageExample.java
index 89b5c971e915..442e3b84d13b 100644
--- a/src/main/java/com/google/gcloud/examples/StorageExample.java
+++ b/src/main/java/com/google/gcloud/examples/StorageExample.java
@@ -270,14 +270,15 @@ Tuple parse(String... args) {
if (args.length < 2 || args.length > 3) {
throw new IllegalArgumentException();
}
- Path path = null;
+ Path path;
if (args.length > 2) {
path = Paths.get(args[2]);
if (Files.isDirectory(path)) {
path = path.resolve(Paths.get(args[1]).getFileName());
}
+ } else {
+ path = null;
}
- String blob = args.length < 3 ? path.getFileName().toString() : args[2];
return Tuple.of(Blob.of(args[0], args[1]), path);
}
diff --git a/src/main/java/com/google/gcloud/spi/DefaultStorageRpc.java b/src/main/java/com/google/gcloud/spi/DefaultStorageRpc.java
index ce107815c435..7ebbb1340d0f 100644
--- a/src/main/java/com/google/gcloud/spi/DefaultStorageRpc.java
+++ b/src/main/java/com/google/gcloud/spi/DefaultStorageRpc.java
@@ -1 +1 @@
-/*
* Copyright 2015 Google Inc. All Rights Reserved.
*
* Licensed 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 com.google.gcloud.spi;
import static com.google.gcloud.spi.StorageRpc.Option.DELIMITER;
import static com.google.gcloud.spi.StorageRpc.Option.IF_GENERATION_MATCH;
import static com.google.gcloud.spi.StorageRpc.Option.IF_GENERATION_NOT_MATCH;
import static com.google.gcloud.spi.StorageRpc.Option.IF_METAGENERATION_MATCH;
import static com.google.gcloud.spi.StorageRpc.Option.IF_METAGENERATION_NOT_MATCH;
import static com.google.gcloud.spi.StorageRpc.Option.IF_SOURCE_GENERATION_MATCH;
import static com.google.gcloud.spi.StorageRpc.Option.IF_SOURCE_GENERATION_NOT_MATCH;
import static com.google.gcloud.spi.StorageRpc.Option.IF_SOURCE_METAGENERATION_MATCH;
import static com.google.gcloud.spi.StorageRpc.Option.IF_SOURCE_METAGENERATION_NOT_MATCH;
import static com.google.gcloud.spi.StorageRpc.Option.MAX_RESULTS;
import static com.google.gcloud.spi.StorageRpc.Option.PAGE_TOKEN;
import static com.google.gcloud.spi.StorageRpc.Option.PREDEFINED_ACL;
import static com.google.gcloud.spi.StorageRpc.Option.PREDEFINED_DEFAULT_OBJECT_ACL;
import static com.google.gcloud.spi.StorageRpc.Option.PREFIX;
import static com.google.gcloud.spi.StorageRpc.Option.VERSIONS;
import com.google.api.client.googleapis.batch.json.JsonBatchCallback;
import com.google.api.client.googleapis.json.GoogleJsonError;
import com.google.api.client.googleapis.json.GoogleJsonResponseException;
import com.google.api.client.googleapis.media.MediaHttpDownloader;
import com.google.api.client.http.AbstractInputStreamContent;
import com.google.api.client.http.ByteArrayContent;
import com.google.api.client.http.EmptyContent;
import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpHeaders;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.HttpResponse;
import com.google.api.client.http.HttpResponseException;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.jackson.JacksonFactory;
import com.google.api.services.storage.Storage;
import com.google.api.services.storage.Storage.Objects.Get;
import com.google.api.services.storage.Storage.Objects.Insert;
import com.google.api.services.storage.model.Bucket;
import com.google.api.services.storage.model.Buckets;
import com.google.api.services.storage.model.ComposeRequest;
import com.google.api.services.storage.model.ComposeRequest.SourceObjects.ObjectPreconditions;
import com.google.api.services.storage.model.Objects;
import com.google.api.services.storage.model.StorageObject;
import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import com.google.gcloud.storage.StorageServiceException;
import com.google.gcloud.storage.StorageServiceOptions;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class DefaultStorageRpc implements StorageRpc {
public static final String DEFAULT_PROJECTION = "full";
private final StorageServiceOptions options;
private final Storage storage;
// see: https://cloud.google.com/storage/docs/concepts-techniques#practices
private static final Set RETRYABLE_CODES = ImmutableSet.of(504, 503, 502, 500, 408);
public DefaultStorageRpc(StorageServiceOptions options) {
HttpTransport transport = options.httpTransportFactory().create();
HttpRequestInitializer initializer = options.httpRequestInitializer();
this.options = options;
storage = new Storage.Builder(transport, new JacksonFactory(), initializer)
.setApplicationName("gcloud-java")
.build();
// Todo: make sure nulls are being used as Data.asNull()
// TOdo: consider options
}
private static StorageServiceException translate(IOException exception) {
StorageServiceException translated;
if (exception instanceof GoogleJsonResponseException) {
translated = translate(((GoogleJsonResponseException) exception).getDetails());
} else {
translated = new StorageServiceException(0, exception.getMessage(), false);
}
translated.initCause(exception);
return translated;
}
private static StorageServiceException translate(GoogleJsonError exception) {
boolean retryable = RETRYABLE_CODES.contains(exception.getCode())
|| "InternalError".equals(exception.getMessage());
return new StorageServiceException(exception.getCode(), exception.getMessage(), retryable);
}
@Override
public Bucket create(Bucket bucket, Map