diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQuery.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQuery.java index a0724b2026b2..c23ee2844762 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQuery.java +++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQuery.java @@ -22,6 +22,7 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import com.google.gcloud.FieldSelector; +import com.google.gcloud.FieldSelector.SelectorHelper; import com.google.gcloud.Page; import com.google.gcloud.Service; import com.google.gcloud.bigquery.spi.BigQueryRpc; @@ -192,7 +193,7 @@ private DatasetOption(BigQueryRpc.Option option, Object value) { */ public static DatasetOption fields(DatasetField... fields) { return new DatasetOption(BigQueryRpc.Option.FIELDS, - selector(DatasetField.REQUIRED_FIELDS, fields)); + SelectorHelper.selector(DatasetField.REQUIRED_FIELDS, fields)); } } @@ -262,7 +263,7 @@ private TableOption(BigQueryRpc.Option option, Object value) { */ public static TableOption fields(TableField... fields) { return new TableOption(BigQueryRpc.Option.FIELDS, - selector(TableField.REQUIRED_FIELDS, fields)); + SelectorHelper.selector(TableField.REQUIRED_FIELDS, fields)); } } @@ -359,10 +360,9 @@ public static JobListOption pageToken(String pageToken) { * listing jobs. */ public static JobListOption fields(JobField... fields) { - StringBuilder builder = - selector(new StringBuilder().append("etag,jobs("), JobField.REQUIRED_FIELDS, fields) - .append(",state,errorResult),nextPageToken"); - return new JobListOption(BigQueryRpc.Option.FIELDS, builder.toString()); + return new JobListOption(BigQueryRpc.Option.FIELDS, + SelectorHelper.selector("jobs", JobField.REQUIRED_FIELDS, fields, "state", + "errorResult")); } } @@ -386,7 +386,7 @@ private JobOption(BigQueryRpc.Option option, Object value) { */ public static JobOption fields(JobField... fields) { return new JobOption(BigQueryRpc.Option.FIELDS, - Option.selector(JobField.REQUIRED_FIELDS, fields)); + SelectorHelper.selector(JobField.REQUIRED_FIELDS, fields)); } } diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Option.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Option.java index 9b123fc1c89c..e7ac0d0a8cc4 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Option.java +++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Option.java @@ -18,21 +18,16 @@ import static com.google.common.base.Preconditions.checkNotNull; -import com.google.common.base.Joiner; import com.google.common.base.MoreObjects; -import com.google.common.collect.Sets; -import com.google.gcloud.FieldSelector; import com.google.gcloud.bigquery.spi.BigQueryRpc; import java.io.Serializable; -import java.util.List; import java.util.Objects; -import java.util.Set; /** * Base class for BigQuery operation option. */ -class Option implements Serializable { +abstract class Option implements Serializable { private static final long serialVersionUID = -6647817677804099207L; @@ -73,20 +68,4 @@ public String toString() { .add("value", value) .toString(); } - - static String selector(List required, FieldSelector... others) { - Set fieldStrings = Sets.newHashSetWithExpectedSize(required.size() + others.length); - for (FieldSelector field : required) { - fieldStrings.add(field.selector()); - } - for (FieldSelector field : others) { - fieldStrings.add(field.selector()); - } - return Joiner.on(',').join(fieldStrings); - } - - static StringBuilder selector(StringBuilder partialSelector, List required, - FieldSelector... others) { - return partialSelector.append(selector(required, others)); - } } diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/BigQueryImplTest.java b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/BigQueryImplTest.java index a6f512800024..c7d7cf846ef2 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/BigQueryImplTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/BigQueryImplTest.java @@ -886,12 +886,14 @@ public com.google.api.services.bigquery.model.Job apply(Job job) { assertEquals(cursor, page.nextPageCursor()); assertArrayEquals(jobList.toArray(), Iterables.toArray(page.values(), Job.class)); String selector = (String) capturedOptions.getValue().get(JOB_OPTION_FIELDS.rpcOption()); - assertTrue(selector.contains("etag,jobs(")); + assertTrue(selector.contains("nextPageToken,jobs(")); assertTrue(selector.contains("configuration")); assertTrue(selector.contains("jobReference")); assertTrue(selector.contains("statistics")); - assertTrue(selector.contains("state,errorResult),nextPageToken")); - assertEquals(80, selector.length()); + assertTrue(selector.contains("state")); + assertTrue(selector.contains("errorResult")); + assertTrue(selector.contains(")")); + assertEquals(75, selector.length()); } @Test diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/OptionTest.java b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/OptionTest.java index 2c89ececedb8..42f19830fb6c 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/OptionTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/OptionTest.java @@ -17,22 +17,49 @@ package com.google.gcloud.bigquery; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNull; import com.google.gcloud.bigquery.spi.BigQueryRpc; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; public class OptionTest { + private static final BigQueryRpc.Option RPC_OPTION = BigQueryRpc.Option.PAGE_TOKEN; + private static final BigQueryRpc.Option ANOTHER_RPC_OPTION = BigQueryRpc.Option.FIELDS; + private static final String VALUE = "some value"; + private static final String OTHER_VALUE = "another value"; + private static final Option OPTION = new Option(RPC_OPTION, VALUE) {}; + private static final Option OPTION_EQUALS = new Option(RPC_OPTION, VALUE) {}; + private static final Option OPTION_NOT_EQUALS1 = new Option(RPC_OPTION, OTHER_VALUE) {}; + private static final Option OPTION_NOT_EQUALS2 = new Option(ANOTHER_RPC_OPTION, VALUE) {}; + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Test + public void testEquals() { + assertEquals(OPTION, OPTION_EQUALS); + assertNotEquals(OPTION, OPTION_NOT_EQUALS1); + assertNotEquals(OPTION, OPTION_NOT_EQUALS2); + } + @Test - public void testOption() { - Option option = new Option(BigQueryRpc.Option.PAGE_TOKEN, "token"); - assertEquals(BigQueryRpc.Option.PAGE_TOKEN, option.rpcOption()); - assertEquals("token", option.value()); + public void testHashCode() { + assertEquals(OPTION.hashCode(), OPTION_EQUALS.hashCode()); } - @Test(expected = NullPointerException.class) - public void testNullRpcOption() { - new Option(null, "token"); + @Test + public void testConstructor() { + assertEquals(RPC_OPTION, OPTION.rpcOption()); + assertEquals(VALUE, OPTION.value()); + Option option = new Option(RPC_OPTION, null) {}; + assertEquals(RPC_OPTION, option.rpcOption()); + assertNull(option.value()); + thrown.expect(NullPointerException.class); + new Option(null, VALUE) {}; } } diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/FieldSelector.java b/gcloud-java-core/src/main/java/com/google/gcloud/FieldSelector.java index 358c4d4798f6..343f67e3381b 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/FieldSelector.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/FieldSelector.java @@ -16,9 +16,18 @@ package com.google.gcloud; +import com.google.common.base.Function; +import com.google.common.base.Joiner; +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; + +import java.util.Arrays; +import java.util.List; +import java.util.Set; + /** * Interface for Google Cloud resource's fields. Implementations of this interface can be used to - * select only desired fields when getting or listing Google Cloud resources. + * select only desired fields from a returned Google Cloud resource. */ public interface FieldSelector { @@ -27,4 +36,61 @@ public interface FieldSelector { * other field selectors) to specify which resource fields should be returned by an API call. */ String selector(); + + /** + * A helper class used to build composite selectors given a number of fields. This class is not + * supposed to be used directly by users. + */ + class SelectorHelper { + + private SelectorHelper() {} + + private static final Function FIELD_TO_STRING_FUNCTION = + new Function() { + @Override + public String apply(FieldSelector fieldSelector) { + return fieldSelector.selector(); + } + }; + + private static String selector(List required, FieldSelector[] others, + String... extraResourceFields) { + Set fieldStrings = Sets.newHashSetWithExpectedSize(required.size() + others.length); + fieldStrings.addAll(Lists.transform(required, FIELD_TO_STRING_FUNCTION)); + fieldStrings.addAll(Lists.transform(Arrays.asList(others), FIELD_TO_STRING_FUNCTION)); + fieldStrings.addAll(Arrays.asList(extraResourceFields)); + return Joiner.on(',').join(fieldStrings); + } + + /** + * Returns a composite selector given a number of fields. The string selector returned by this + * method can be used for field selection in API calls that return a single resource. This + * method is not supposed to be used directly by users. + */ + public static String selector(List required, FieldSelector... others) { + return selector(required, others, new String[]{}); + } + + /** + * Returns a composite selector given a number of fields and a container name. The string + * selector returned by this method can be used for field selection in API calls that return a + * list of resources. This method is not supposed to be used directly by users. + */ + public static String selector(String containerName, List required, + FieldSelector... others) { + return "nextPageToken," + containerName + '(' + selector(required, others) + ')'; + } + + /** + * Returns a composite selector given a number of fields and a container name. This methods also + * takes an {@code extraResourceFields} parameter to specify some extra fields as strings. The + * string selector returned by this method can be used for field selection in API calls that + * return a list of resources. This method is not supposed to be used directly by users. + */ + public static String selector(String containerName, List required, + FieldSelector[] others, String... extraResourceFields) { + return "nextPageToken," + containerName + '(' + + selector(required, others, extraResourceFields) + ')'; + } + } } diff --git a/gcloud-java-core/src/test/java/com/google/gcloud/SelectorHelperTest.java b/gcloud-java-core/src/test/java/com/google/gcloud/SelectorHelperTest.java new file mode 100644 index 000000000000..2279205539cc --- /dev/null +++ b/gcloud-java-core/src/test/java/com/google/gcloud/SelectorHelperTest.java @@ -0,0 +1,71 @@ +/* + * Copyright 2016 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 static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import com.google.common.collect.ImmutableList; +import com.google.gcloud.FieldSelector.SelectorHelper; + +import org.junit.Test; + +import java.util.List; + +public class SelectorHelperTest { + + private static final FieldSelector FIELD1 = new FieldSelector() { + @Override + public String selector() { + return "field1"; + } + }; + private static final FieldSelector FIELD2 = new FieldSelector() { + @Override + public String selector() { + return "field2"; + } + }; + private static final FieldSelector FIELD3 = new FieldSelector() { + @Override + public String selector() { + return "field3"; + } + }; + private static final List REQUIRED_FIELDS = ImmutableList.of(FIELD1, FIELD2); + private static final String CONTAINER = "container"; + + @Test + public void testSelector() { + String selector = SelectorHelper.selector(REQUIRED_FIELDS, FIELD3); + assertTrue(selector.contains("field1")); + assertTrue(selector.contains("field2")); + assertTrue(selector.contains("field3")); + assertEquals(20, selector.length()); + } + + @Test + public void testListSelector() { + String selector = SelectorHelper.selector(CONTAINER, REQUIRED_FIELDS, FIELD3); + assertTrue(selector.startsWith("nextPageToken,container(")); + assertTrue(selector.contains("field1")); + assertTrue(selector.contains("field2")); + assertTrue(selector.contains("field3")); + assertTrue(selector.endsWith(")")); + assertEquals(45, selector.length()); + } +} diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java index ee0611279d27..c4b08e31d533 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java @@ -18,6 +18,7 @@ import com.google.common.collect.ImmutableList; import com.google.gcloud.FieldSelector; +import com.google.gcloud.FieldSelector.SelectorHelper; import com.google.gcloud.Page; import com.google.gcloud.Service; import com.google.gcloud.dns.spi.DnsRpc; @@ -157,7 +158,7 @@ public String selector() { /** * Class for specifying record set listing options. */ - class RecordSetListOption extends AbstractOption implements Serializable { + class RecordSetListOption extends Option implements Serializable { private static final long serialVersionUID = 1009627025381096098L; @@ -174,9 +175,8 @@ class RecordSetListOption extends AbstractOption implements Serializable { * of fields that can be used. */ public static RecordSetListOption fields(RecordSetField... fields) { - StringBuilder builder = selector(new StringBuilder().append("nextPageToken,rrsets("), - RecordSetField.REQUIRED_FIELDS, fields).append(')'); - return new RecordSetListOption(DnsRpc.Option.FIELDS, builder.toString()); + return new RecordSetListOption(DnsRpc.Option.FIELDS, + SelectorHelper.selector("rrsets", RecordSetField.REQUIRED_FIELDS, fields)); } /** @@ -218,7 +218,7 @@ public static RecordSetListOption type(RecordSet.Type type) { /** * Class for specifying zone field options. */ - class ZoneOption extends AbstractOption implements Serializable { + class ZoneOption extends Option implements Serializable { private static final long serialVersionUID = -8065564464895945037L; @@ -234,14 +234,15 @@ class ZoneOption extends AbstractOption implements Serializable { * specified. {@link ZoneField} provides a list of fields that can be used. */ public static ZoneOption fields(ZoneField... fields) { - return new ZoneOption(DnsRpc.Option.FIELDS, selector(ZoneField.REQUIRED_FIELDS, fields)); + return new ZoneOption(DnsRpc.Option.FIELDS, + SelectorHelper.selector(ZoneField.REQUIRED_FIELDS, fields)); } } /** * Class for specifying zone listing options. */ - class ZoneListOption extends AbstractOption implements Serializable { + class ZoneListOption extends Option implements Serializable { private static final long serialVersionUID = -2830645032124504717L; @@ -257,9 +258,8 @@ class ZoneListOption extends AbstractOption implements Serializable { * specified. {@link ZoneField} provides a list of fields that can be used. */ public static ZoneListOption fields(ZoneField... fields) { - StringBuilder builder = selector(new StringBuilder().append("nextPageToken,managedZones("), - ZoneField.REQUIRED_FIELDS, fields).append(')'); - return new ZoneListOption(DnsRpc.Option.FIELDS, builder.toString()); + return new ZoneListOption(DnsRpc.Option.FIELDS, + SelectorHelper.selector("managedZones", ZoneField.REQUIRED_FIELDS, fields)); } /** @@ -293,7 +293,7 @@ public static ZoneListOption pageSize(int pageSize) { /** * Class for specifying project options. */ - class ProjectOption extends AbstractOption implements Serializable { + class ProjectOption extends Option implements Serializable { private static final long serialVersionUID = 6817937338218847748L; @@ -311,14 +311,14 @@ class ProjectOption extends AbstractOption implements Serializable { */ public static ProjectOption fields(ProjectField... fields) { return new ProjectOption(DnsRpc.Option.FIELDS, - selector(ProjectField.REQUIRED_FIELDS, fields)); + SelectorHelper.selector(ProjectField.REQUIRED_FIELDS, fields)); } } /** * Class for specifying change request field options. */ - class ChangeRequestOption extends AbstractOption implements Serializable { + class ChangeRequestOption extends Option implements Serializable { private static final long serialVersionUID = 1067273695061077782L; @@ -337,14 +337,14 @@ class ChangeRequestOption extends AbstractOption implements Serializable { */ public static ChangeRequestOption fields(ChangeRequestField... fields) { return new ChangeRequestOption(DnsRpc.Option.FIELDS, - selector(ChangeRequestField.REQUIRED_FIELDS, fields)); + SelectorHelper.selector(ChangeRequestField.REQUIRED_FIELDS, fields)); } } /** * Class for specifying change request listing options. */ - class ChangeRequestListOption extends AbstractOption implements Serializable { + class ChangeRequestListOption extends Option implements Serializable { private static final long serialVersionUID = -900209143895376089L; @@ -362,9 +362,8 @@ class ChangeRequestListOption extends AbstractOption implements Serializable { * a list of fields that can be used. */ public static ChangeRequestListOption fields(ChangeRequestField... fields) { - StringBuilder builder = selector(new StringBuilder().append("nextPageToken,changes("), - ChangeRequestField.REQUIRED_FIELDS, fields).append(')'); - return new ChangeRequestListOption(DnsRpc.Option.FIELDS, builder.toString()); + return new ChangeRequestListOption(DnsRpc.Option.FIELDS, + SelectorHelper.selector("changes", ChangeRequestField.REQUIRED_FIELDS, fields)); } /** diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsImpl.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsImpl.java index 51ab0bd92720..9f4fa2a9d9d1 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsImpl.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsImpl.java @@ -309,9 +309,9 @@ public com.google.api.services.dns.model.Change call() { } } - private Map optionMap(AbstractOption... options) { + private Map optionMap(Option... options) { Map temp = Maps.newEnumMap(DnsRpc.Option.class); - for (AbstractOption option : options) { + for (Option option : options) { Object prev = temp.put(option.rpcOption(), option.value()); checkArgument(prev == null, "Duplicate option %s", option); } diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/AbstractOption.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Option.java similarity index 62% rename from gcloud-java-dns/src/main/java/com/google/gcloud/dns/AbstractOption.java rename to gcloud-java-dns/src/main/java/com/google/gcloud/dns/Option.java index 43dfe69df213..fee99898fb24 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/AbstractOption.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Option.java @@ -18,27 +18,22 @@ import static com.google.common.base.Preconditions.checkNotNull; -import com.google.common.base.Joiner; import com.google.common.base.MoreObjects; -import com.google.common.collect.Sets; -import com.google.gcloud.FieldSelector; import com.google.gcloud.dns.spi.DnsRpc; import java.io.Serializable; -import java.util.List; import java.util.Objects; -import java.util.Set; /** * A base class for options. */ -abstract class AbstractOption implements Serializable { +abstract class Option implements Serializable { private static final long serialVersionUID = -5912727967831484228L; private final Object value; private final DnsRpc.Option rpcOption; - AbstractOption(DnsRpc.Option rpcOption, Object value) { + Option(DnsRpc.Option rpcOption, Object value) { this.rpcOption = checkNotNull(rpcOption); this.value = value; } @@ -53,10 +48,10 @@ DnsRpc.Option rpcOption() { @Override public boolean equals(Object obj) { - if (!(obj instanceof AbstractOption)) { + if (!(obj instanceof Option)) { return false; } - AbstractOption other = (AbstractOption) obj; + Option other = (Option) obj; return Objects.equals(value, other.value) && Objects.equals(rpcOption, other.rpcOption); } @@ -72,20 +67,4 @@ public String toString() { .add("rpcOption", rpcOption) .toString(); } - - static String selector(List required, FieldSelector... others) { - Set fieldStrings = Sets.newHashSetWithExpectedSize(required.size() + others.length); - for (FieldSelector field : required) { - fieldStrings.add(field.selector()); - } - for (FieldSelector field : others) { - fieldStrings.add(field.selector()); - } - return Joiner.on(',').join(fieldStrings); - } - - static StringBuilder selector(StringBuilder partialSelector, List required, - FieldSelector... others) { - return partialSelector.append(selector(required, others)); - } } diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/AbstractOptionTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/OptionTest.java similarity index 66% rename from gcloud-java-dns/src/test/java/com/google/gcloud/dns/AbstractOptionTest.java rename to gcloud-java-dns/src/test/java/com/google/gcloud/dns/OptionTest.java index d88ea85c5846..e9906354f963 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/AbstractOptionTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/OptionTest.java @@ -18,24 +18,27 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.fail; +import static org.junit.Assert.assertNull; import com.google.gcloud.dns.spi.DnsRpc; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; -public class AbstractOptionTest { +public class OptionTest { private static final DnsRpc.Option RPC_OPTION = DnsRpc.Option.DNS_TYPE; private static final DnsRpc.Option ANOTHER_RPC_OPTION = DnsRpc.Option.DNS_NAME; private static final String VALUE = "some value"; private static final String OTHER_VALUE = "another value"; - private static final AbstractOption OPTION = new AbstractOption(RPC_OPTION, VALUE) {}; - private static final AbstractOption OPTION_EQUALS = new AbstractOption(RPC_OPTION, VALUE) {}; - private static final AbstractOption OPTION_NOT_EQUALS1 = - new AbstractOption(RPC_OPTION, OTHER_VALUE) {}; - private static final AbstractOption OPTION_NOT_EQUALS2 = - new AbstractOption(ANOTHER_RPC_OPTION, VALUE) {}; + private static final Option OPTION = new Option(RPC_OPTION, VALUE) {}; + private static final Option OPTION_EQUALS = new Option(RPC_OPTION, VALUE) {}; + private static final Option OPTION_NOT_EQUALS1 = new Option(RPC_OPTION, OTHER_VALUE) {}; + private static final Option OPTION_NOT_EQUALS2 = new Option(ANOTHER_RPC_OPTION, VALUE) {}; + + @Rule + public ExpectedException thrown = ExpectedException.none(); @Test public void testEquals() { @@ -53,12 +56,10 @@ public void testHashCode() { public void testConstructor() { assertEquals(RPC_OPTION, OPTION.rpcOption()); assertEquals(VALUE, OPTION.value()); - try { - new AbstractOption(null, VALUE) {}; - fail("Cannot build with empty option."); - } catch (NullPointerException e) { - // expected - } - new AbstractOption(RPC_OPTION, null) {}; // null value is ok + Option option = new Option(RPC_OPTION, null) {}; + assertEquals(RPC_OPTION, option.rpcOption()); + assertNull(option.value()); + thrown.expect(NullPointerException.class); + new Option(null, VALUE) {}; } } diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Option.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Option.java index 3af167db71a5..3df68468f69f 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Option.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Option.java @@ -18,21 +18,16 @@ import static com.google.common.base.Preconditions.checkNotNull; -import com.google.common.base.Joiner; import com.google.common.base.MoreObjects; -import com.google.common.collect.Sets; -import com.google.gcloud.FieldSelector; import com.google.gcloud.resourcemanager.spi.ResourceManagerRpc; import java.io.Serializable; -import java.util.List; import java.util.Objects; -import java.util.Set; /** * Base class for Resource Manager operation options. */ -class Option implements Serializable { +abstract class Option implements Serializable { private static final long serialVersionUID = 2655177550880762967L; @@ -74,20 +69,4 @@ public String toString() { .add("value", value) .toString(); } - - static String selector(List required, FieldSelector... others) { - Set fieldStrings = Sets.newHashSetWithExpectedSize(required.size() + others.length); - for (FieldSelector field : required) { - fieldStrings.add(field.selector()); - } - for (FieldSelector field : others) { - fieldStrings.add(field.selector()); - } - return Joiner.on(',').join(fieldStrings); - } - - static StringBuilder selector(StringBuilder partialSelector, List required, - FieldSelector... others) { - return partialSelector.append(selector(required, others)); - } } diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManager.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManager.java index 595bfab556d6..e000ca69c359 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManager.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManager.java @@ -18,6 +18,7 @@ import com.google.common.collect.ImmutableList; import com.google.gcloud.FieldSelector; +import com.google.gcloud.FieldSelector.SelectorHelper; import com.google.gcloud.IamPolicy; import com.google.gcloud.Page; import com.google.gcloud.Service; @@ -84,7 +85,7 @@ private ProjectGetOption(ResourceManagerRpc.Option option, Object value) { */ public static ProjectGetOption fields(ProjectField... fields) { return new ProjectGetOption(ResourceManagerRpc.Option.FIELDS, - selector(ProjectField.REQUIRED_FIELDS, fields)); + SelectorHelper.selector(ProjectField.REQUIRED_FIELDS, fields)); } } @@ -157,10 +158,8 @@ public static ProjectListOption pageSize(int pageSize) { * that can be used. */ public static ProjectListOption fields(ProjectField... fields) { - StringBuilder builder = - selector(new StringBuilder().append("projects("), ProjectField.REQUIRED_FIELDS, fields) - .append("),nextPageToken"); - return new ProjectListOption(ResourceManagerRpc.Option.FIELDS, builder.toString()); + return new ProjectListOption(ResourceManagerRpc.Option.FIELDS, + SelectorHelper.selector("projects", ProjectField.REQUIRED_FIELDS, fields)); } } diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/OptionTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/OptionTest.java new file mode 100644 index 000000000000..729c7a4b8911 --- /dev/null +++ b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/OptionTest.java @@ -0,0 +1,66 @@ +/* + * Copyright 2016 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.resourcemanager; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNull; + +import com.google.gcloud.resourcemanager.spi.ResourceManagerRpc; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +public class OptionTest { + + private static final ResourceManagerRpc.Option RPC_OPTION = ResourceManagerRpc.Option.FILTER; + private static final ResourceManagerRpc.Option ANOTHER_RPC_OPTION = + ResourceManagerRpc.Option.FIELDS; + private static final String VALUE = "some value"; + private static final String OTHER_VALUE = "another value"; + private static final Option OPTION = new Option(RPC_OPTION, VALUE) {}; + private static final Option OPTION_EQUALS = new Option(RPC_OPTION, VALUE) {}; + private static final Option OPTION_NOT_EQUALS1 = new Option(RPC_OPTION, OTHER_VALUE) {}; + private static final Option OPTION_NOT_EQUALS2 = new Option(ANOTHER_RPC_OPTION, VALUE) {}; + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Test + public void testEquals() { + assertEquals(OPTION, OPTION_EQUALS); + assertNotEquals(OPTION, OPTION_NOT_EQUALS1); + assertNotEquals(OPTION, OPTION_NOT_EQUALS2); + } + + @Test + public void testHashCode() { + assertEquals(OPTION.hashCode(), OPTION_EQUALS.hashCode()); + } + + @Test + public void testConstructor() { + assertEquals(RPC_OPTION, OPTION.rpcOption()); + assertEquals(VALUE, OPTION.value()); + Option option = new Option(RPC_OPTION, null) {}; + assertEquals(RPC_OPTION, option.rpcOption()); + assertNull(option.value()); + thrown.expect(NullPointerException.class); + new Option(null, VALUE) {}; + } +} diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Option.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Option.java index 1ea0c0561eaa..774023eff78b 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Option.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Option.java @@ -18,21 +18,16 @@ import static com.google.common.base.Preconditions.checkNotNull; -import com.google.common.base.Joiner; import com.google.common.base.MoreObjects; -import com.google.common.collect.Sets; -import com.google.gcloud.FieldSelector; import com.google.gcloud.storage.spi.StorageRpc; import java.io.Serializable; -import java.util.List; import java.util.Objects; -import java.util.Set; /** * Base class for Storage operation option. */ -class Option implements Serializable { +abstract class Option implements Serializable { private static final long serialVersionUID = -73199088766477208L; @@ -74,20 +69,4 @@ public String toString() { .add("value", value) .toString(); } - - static String selector(List required, FieldSelector... others) { - Set fieldStrings = Sets.newHashSetWithExpectedSize(required.size() + others.length); - for (FieldSelector field : required) { - fieldStrings.add(field.selector()); - } - for (FieldSelector field : others) { - fieldStrings.add(field.selector()); - } - return Joiner.on(',').join(fieldStrings); - } - - static StringBuilder selector(StringBuilder partialSelector, List required, - FieldSelector... others) { - return partialSelector.append(selector(required, others)); - } } 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 eb51e9d0f6c1..87d82aad686b 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 @@ -25,6 +25,7 @@ import com.google.gcloud.AuthCredentials; import com.google.gcloud.AuthCredentials.ServiceAccountAuthCredentials; import com.google.gcloud.FieldSelector; +import com.google.gcloud.FieldSelector.SelectorHelper; import com.google.gcloud.Page; import com.google.gcloud.ReadChannel; import com.google.gcloud.Service; @@ -256,7 +257,7 @@ public static BucketGetOption metagenerationNotMatch(long metageneration) { */ public static BucketGetOption fields(BucketField... fields) { return new BucketGetOption(StorageRpc.Option.FIELDS, - selector(BucketField.REQUIRED_FIELDS, fields)); + SelectorHelper.selector(BucketField.REQUIRED_FIELDS, fields)); } } @@ -597,7 +598,7 @@ public static BlobGetOption metagenerationNotMatch(long metageneration) { */ public static BlobGetOption fields(BlobField... fields) { return new BlobGetOption(StorageRpc.Option.FIELDS, - selector(BlobField.REQUIRED_FIELDS, fields)); + SelectorHelper.selector(BlobField.REQUIRED_FIELDS, fields)); } } @@ -641,10 +642,8 @@ public static BucketListOption prefix(String prefix) { * specified. */ public static BucketListOption fields(BucketField... fields) { - StringBuilder builder = - selector(new StringBuilder().append("items("), BucketField.REQUIRED_FIELDS, fields) - .append("),nextPageToken"); - return new BucketListOption(StorageRpc.Option.FIELDS, builder.toString()); + return new BucketListOption(StorageRpc.Option.FIELDS, + SelectorHelper.selector("items", BucketField.REQUIRED_FIELDS, fields)); } } @@ -711,10 +710,8 @@ public static BlobListOption versions(boolean versions) { * specified. */ public static BlobListOption fields(BlobField... fields) { - StringBuilder builder = - selector(new StringBuilder().append("items("), BlobField.REQUIRED_FIELDS, fields) - .append("),nextPageToken"); - return new BlobListOption(StorageRpc.Option.FIELDS, builder.toString()); + return new BlobListOption(StorageRpc.Option.FIELDS, + SelectorHelper.selector("items", BlobField.REQUIRED_FIELDS, fields)); } } diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/OptionTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/OptionTest.java index 5924174ab138..08a8e79b2c3b 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/OptionTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/OptionTest.java @@ -17,22 +17,49 @@ package com.google.gcloud.storage; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNull; import com.google.gcloud.storage.spi.StorageRpc; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; public class OptionTest { + private static final StorageRpc.Option RPC_OPTION = StorageRpc.Option.DELIMITER; + private static final StorageRpc.Option ANOTHER_RPC_OPTION = StorageRpc.Option.FIELDS; + private static final String VALUE = "some value"; + private static final String OTHER_VALUE = "another value"; + private static final Option OPTION = new Option(RPC_OPTION, VALUE) {}; + private static final Option OPTION_EQUALS = new Option(RPC_OPTION, VALUE) {}; + private static final Option OPTION_NOT_EQUALS1 = new Option(RPC_OPTION, OTHER_VALUE) {}; + private static final Option OPTION_NOT_EQUALS2 = new Option(ANOTHER_RPC_OPTION, VALUE) {}; + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Test + public void testEquals() { + assertEquals(OPTION, OPTION_EQUALS); + assertNotEquals(OPTION, OPTION_NOT_EQUALS1); + assertNotEquals(OPTION, OPTION_NOT_EQUALS2); + } + @Test - public void testOption() { - Option option = new Option(StorageRpc.Option.DELIMITER, "/"); - assertEquals(StorageRpc.Option.DELIMITER, option.rpcOption()); - assertEquals("/", option.value()); + public void testHashCode() { + assertEquals(OPTION.hashCode(), OPTION_EQUALS.hashCode()); } - @Test(expected = NullPointerException.class) - public void testIndexOutOfBoundsException() { - new Option(null, "/"); + @Test + public void testConstructor() { + assertEquals(RPC_OPTION, OPTION.rpcOption()); + assertEquals(VALUE, OPTION.value()); + Option option = new Option(RPC_OPTION, null) {}; + assertEquals(RPC_OPTION, option.rpcOption()); + assertNull(option.value()); + thrown.expect(NullPointerException.class); + new Option(null, VALUE) {}; } }