diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/BaseService.java b/gcloud-java-core/src/main/java/com/google/gcloud/BaseService.java index 982d3058295c..70c0a7792956 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/BaseService.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/BaseService.java @@ -16,17 +16,26 @@ package com.google.gcloud; -public abstract class BaseService> - implements Service { +public abstract class BaseService< + OptionsT extends ServiceOptions, + ServiceFactoryT extends ServiceFactory> + implements Service { private final OptionsT options; + private final ServiceFactoryT factory; - protected BaseService(OptionsT options) { + protected BaseService(OptionsT options, ServiceFactoryT factory) { this.options = options; + this.factory = factory; } @Override public OptionsT options() { return options; } + + @Override + public ServiceFactoryT factory() { + return factory; + } } diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/Service.java b/gcloud-java-core/src/main/java/com/google/gcloud/Service.java index 19759fb20e21..fb541ab9f85b 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/Service.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/Service.java @@ -16,6 +16,9 @@ package com.google.gcloud; -public interface Service> { +public interface Service< + OptionsT extends ServiceOptions, + ServiceFactoryT extends ServiceFactory> { OptionsT options(); + ServiceFactoryT factory(); } diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/ServiceFactory.java b/gcloud-java-core/src/main/java/com/google/gcloud/ServiceFactory.java new file mode 100644 index 000000000000..8387008ff70b --- /dev/null +++ b/gcloud-java-core/src/main/java/com/google/gcloud/ServiceFactory.java @@ -0,0 +1,28 @@ +/* + * 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; + +import java.io.Serializable; + +public interface ServiceFactory< + ServiceT extends Service, + OptionsT extends ServiceOptions> + extends Serializable { + + public ServiceT get(OptionsT options); + +} diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Datastore.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Datastore.java index 870ed8d9474f..61948e544c2d 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Datastore.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Datastore.java @@ -23,7 +23,8 @@ /** * An interface for Google Cloud Datastore. */ -public interface Datastore extends Service, DatastoreReaderWriter { +public interface Datastore extends Service, + DatastoreReaderWriter { /** * Returns a new Datastore transaction. diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreFactory.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreFactory.java index a64fab3715f1..91d9706756f6 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreFactory.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreFactory.java @@ -16,18 +16,29 @@ package com.google.gcloud.datastore; +import com.google.gcloud.ServiceFactory; +import java.io.ObjectStreamException; /** * A base class for Datastore factories. */ -public abstract class DatastoreFactory { +public abstract class DatastoreFactory implements ServiceFactory { + + private static final long serialVersionUID = 5037190305022535983L; private static final DatastoreFactory INSTANCE = new DatastoreFactory() { - @Override - public Datastore get(DatastoreOptions options) { - return new DatastoreImpl(options); - } - }; + + private static final long serialVersionUID = 5893914895344559491L; + + @Override + public Datastore get(DatastoreOptions options) { + return new DatastoreImpl(options, this); + } + + private Object readResolve() throws ObjectStreamException { + return INSTANCE; + } + }; /** * Returns the default factory instance. @@ -39,5 +50,6 @@ public static DatastoreFactory instance() { /** * Returns a {@code Datastore} service for the given options. */ + @Override public abstract Datastore get(DatastoreOptions options); } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java index 6f2454c62167..6fb8d0507433 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java @@ -43,7 +43,7 @@ import java.util.concurrent.Callable; -final class DatastoreImpl extends BaseService +final class DatastoreImpl extends BaseService implements Datastore { private static final Interceptor EXCEPTION_HANDLER_INTERCEPTOR = @@ -72,8 +72,8 @@ public RetryResult beforeEval(Exception exception) { private final DatastoreRpc datastoreRpc; private final RetryParams retryParams; - DatastoreImpl(DatastoreOptions options) { - super(options); + DatastoreImpl(DatastoreOptions options, DatastoreFactory factory) { + super(options, factory); this.datastoreRpc = options.datastoreRpc(); retryParams = MoreObjects.firstNonNull(options.retryParams(), RetryParams.noRetries()); } diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java index 156f9684f8ba..45026d38cb7b 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java @@ -134,6 +134,11 @@ public void testGetOptions() { assertSame(options, datastore.options()); } + @Test + public void testGetFactory() { + assertSame(DatastoreFactory.instance(), datastore.factory()); + } + @Test public void testNewTransactionCommit() { Transaction transaction = datastore.newTransaction(); diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java index 5f3bfc036fa2..410fe07c961f 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java @@ -40,6 +40,7 @@ public class SerializationTest { + private static final DatastoreFactory DATASTORE_FACTORY = DatastoreFactory.instance(); private static final IncompleteKey INCOMPLETE_KEY1 = IncompleteKey.builder("ds", "k").ancestors(PathElement.of("p", 1)).build(); private static final Key KEY1 = Key.builder("ds", "k", "n").build(); @@ -131,6 +132,13 @@ public class SerializationTest { .put(ValueType.RAW_VALUE, RAW_VALUE) .build(); + @Test + public void testStorageFactory() throws Exception { + DatastoreFactory serializedCopy = serializeAndDeserialize(DATASTORE_FACTORY); + assertEquals(DATASTORE_FACTORY, serializedCopy); + assertEquals(DATASTORE_FACTORY.hashCode(), serializedCopy.hashCode()); + } + @Test public void testServiceOptions() throws Exception { DatastoreOptions options = DatastoreOptions.builder() diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java index e3cfbc195860..2586208c5141 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java @@ -38,7 +38,7 @@ * * @see Google Cloud Storage */ -public interface Storage extends Service { +public interface Storage extends Service { enum PredefinedAcl { AUTHENTICATED_READ("authenticatedRead"), diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageFactory.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageFactory.java index e269f0c9d92b..f058079e45e9 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageFactory.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageFactory.java @@ -16,16 +16,27 @@ package com.google.gcloud.storage; +import com.google.gcloud.ServiceFactory; +import java.io.ObjectStreamException; /** * A base class for Storage factories. */ -public abstract class StorageFactory { +public abstract class StorageFactory implements ServiceFactory { + + private static final long serialVersionUID = 1866883249985063753L; private static final StorageFactory INSTANCE = new StorageFactory() { + + private static final long serialVersionUID = -7985210081064222485L; + @Override public Storage get(StorageOptions options) { - return new StorageImpl(options); + return new StorageImpl(options, this); + } + + private Object readResolve() throws ObjectStreamException { + return INSTANCE; } }; @@ -39,5 +50,6 @@ public static StorageFactory instance() { /** * Returns a {@code Storage} service for the given options. */ + @Override public abstract Storage get(StorageOptions options); } diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java index f59c6c670969..56b6b8a20cfc 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java @@ -64,7 +64,7 @@ import java.util.Set; import java.util.concurrent.Callable; -final class StorageImpl extends BaseService implements Storage { +final class StorageImpl extends BaseService implements Storage { private static final Interceptor EXCEPTION_HANDLER_INTERCEPTOR = new Interceptor() { @@ -90,8 +90,8 @@ public RetryResult beforeEval(Exception exception) { private final StorageRpc storageRpc; - StorageImpl(StorageOptions options) { - super(options); + StorageImpl(StorageOptions options, StorageFactory factory) { + super(options, factory); storageRpc = options.storageRpc(); // todo: configure timeouts - https://developers.google.com/api-client-library/java/google-api-java-client/errors // todo: provide rewrite - https://cloud.google.com/storage/docs/json_api/v1/objects/rewrite diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java index 81342e4b5748..8fd6d3d80d7a 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java @@ -35,6 +35,7 @@ public class SerializationTest { + private static final StorageFactory STORAGE_FACTORY = StorageFactory.instance(); private static final Acl.Domain ACL_DOMAIN = new Acl.Domain("domain"); private static final Acl.Group ACL_GROUP = new Acl.Group("group"); private static final Acl.Project ACL_PROJECT_ = new Acl.Project(ProjectRole.VIEWERS, "pid"); @@ -65,6 +66,13 @@ public class SerializationTest { private static final Storage.BucketTargetOption BUCKET_TARGET_OPTIONS = Storage.BucketTargetOption.metagenerationNotMatch(); + @Test + public void testStorageFactory() throws Exception { + StorageFactory serializedCopy = serializeAndDeserialize(STORAGE_FACTORY); + assertEquals(STORAGE_FACTORY, serializedCopy); + assertEquals(STORAGE_FACTORY.hashCode(), serializedCopy.hashCode()); + } + @Test public void testServiceOptions() throws Exception { StorageOptions options = StorageOptions.builder()