Skip to content

Commit 1710a4c

Browse files
committed
Refactor field selection and helpers
- Add FieldSelector.SelectorHelper with static methods to create selectors - Add SelectorHelperTest - Rename dns.AbstractOption to Option, make other Option classes abstract - Add OptionTest class to resource manager and refactor other OptionTest classes
1 parent 712b255 commit 1710a4c

File tree

16 files changed

+337
-166
lines changed

16 files changed

+337
-166
lines changed

gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQuery.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import com.google.common.collect.ImmutableList;
2323
import com.google.common.collect.Lists;
2424
import com.google.gcloud.FieldSelector;
25+
import com.google.gcloud.FieldSelector.SelectorHelper;
2526
import com.google.gcloud.Page;
2627
import com.google.gcloud.Service;
2728
import com.google.gcloud.bigquery.spi.BigQueryRpc;
@@ -192,7 +193,7 @@ private DatasetOption(BigQueryRpc.Option option, Object value) {
192193
*/
193194
public static DatasetOption fields(DatasetField... fields) {
194195
return new DatasetOption(BigQueryRpc.Option.FIELDS,
195-
selector(DatasetField.REQUIRED_FIELDS, fields));
196+
SelectorHelper.selector(DatasetField.REQUIRED_FIELDS, fields));
196197
}
197198
}
198199

@@ -262,7 +263,7 @@ private TableOption(BigQueryRpc.Option option, Object value) {
262263
*/
263264
public static TableOption fields(TableField... fields) {
264265
return new TableOption(BigQueryRpc.Option.FIELDS,
265-
selector(TableField.REQUIRED_FIELDS, fields));
266+
SelectorHelper.selector(TableField.REQUIRED_FIELDS, fields));
266267
}
267268
}
268269

@@ -359,10 +360,9 @@ public static JobListOption pageToken(String pageToken) {
359360
* listing jobs.
360361
*/
361362
public static JobListOption fields(JobField... fields) {
362-
StringBuilder builder =
363-
selector(new StringBuilder().append("etag,jobs("), JobField.REQUIRED_FIELDS, fields)
364-
.append(",state,errorResult),nextPageToken");
365-
return new JobListOption(BigQueryRpc.Option.FIELDS, builder.toString());
363+
return new JobListOption(BigQueryRpc.Option.FIELDS,
364+
SelectorHelper.selector("jobs", JobField.REQUIRED_FIELDS, fields, "state",
365+
"errorResult"));
366366
}
367367
}
368368

@@ -386,7 +386,7 @@ private JobOption(BigQueryRpc.Option option, Object value) {
386386
*/
387387
public static JobOption fields(JobField... fields) {
388388
return new JobOption(BigQueryRpc.Option.FIELDS,
389-
Option.selector(JobField.REQUIRED_FIELDS, fields));
389+
SelectorHelper.selector(JobField.REQUIRED_FIELDS, fields));
390390
}
391391
}
392392

gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Option.java

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,16 @@
1818

1919
import static com.google.common.base.Preconditions.checkNotNull;
2020

21-
import com.google.common.base.Joiner;
2221
import com.google.common.base.MoreObjects;
23-
import com.google.common.collect.Sets;
24-
import com.google.gcloud.FieldSelector;
2522
import com.google.gcloud.bigquery.spi.BigQueryRpc;
2623

2724
import java.io.Serializable;
28-
import java.util.List;
2925
import java.util.Objects;
30-
import java.util.Set;
3126

3227
/**
3328
* Base class for BigQuery operation option.
3429
*/
35-
class Option implements Serializable {
30+
abstract class Option implements Serializable {
3631

3732
private static final long serialVersionUID = -6647817677804099207L;
3833

@@ -73,20 +68,4 @@ public String toString() {
7368
.add("value", value)
7469
.toString();
7570
}
76-
77-
static String selector(List<FieldSelector> required, FieldSelector... others) {
78-
Set<String> fieldStrings = Sets.newHashSetWithExpectedSize(required.size() + others.length);
79-
for (FieldSelector field : required) {
80-
fieldStrings.add(field.selector());
81-
}
82-
for (FieldSelector field : others) {
83-
fieldStrings.add(field.selector());
84-
}
85-
return Joiner.on(',').join(fieldStrings);
86-
}
87-
88-
static StringBuilder selector(StringBuilder partialSelector, List<FieldSelector> required,
89-
FieldSelector... others) {
90-
return partialSelector.append(selector(required, others));
91-
}
9271
}

gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/BigQueryImplTest.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -886,12 +886,14 @@ public com.google.api.services.bigquery.model.Job apply(Job job) {
886886
assertEquals(cursor, page.nextPageCursor());
887887
assertArrayEquals(jobList.toArray(), Iterables.toArray(page.values(), Job.class));
888888
String selector = (String) capturedOptions.getValue().get(JOB_OPTION_FIELDS.rpcOption());
889-
assertTrue(selector.contains("etag,jobs("));
889+
assertTrue(selector.contains("nextPageToken,jobs("));
890890
assertTrue(selector.contains("configuration"));
891891
assertTrue(selector.contains("jobReference"));
892892
assertTrue(selector.contains("statistics"));
893-
assertTrue(selector.contains("state,errorResult),nextPageToken"));
894-
assertEquals(80, selector.length());
893+
assertTrue(selector.contains("state"));
894+
assertTrue(selector.contains("errorResult"));
895+
assertTrue(selector.contains(")"));
896+
assertEquals(75, selector.length());
895897
}
896898

897899
@Test

gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/OptionTest.java

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,22 +17,49 @@
1717
package com.google.gcloud.bigquery;
1818

1919
import static org.junit.Assert.assertEquals;
20+
import static org.junit.Assert.assertNotEquals;
21+
import static org.junit.Assert.assertNull;
2022

2123
import com.google.gcloud.bigquery.spi.BigQueryRpc;
2224

25+
import org.junit.Rule;
2326
import org.junit.Test;
27+
import org.junit.rules.ExpectedException;
2428

2529
public class OptionTest {
2630

31+
private static final BigQueryRpc.Option RPC_OPTION = BigQueryRpc.Option.PAGE_TOKEN;
32+
private static final BigQueryRpc.Option ANOTHER_RPC_OPTION = BigQueryRpc.Option.FIELDS;
33+
private static final String VALUE = "some value";
34+
private static final String OTHER_VALUE = "another value";
35+
private static final Option OPTION = new Option(RPC_OPTION, VALUE) {};
36+
private static final Option OPTION_EQUALS = new Option(RPC_OPTION, VALUE) {};
37+
private static final Option OPTION_NOT_EQUALS1 = new Option(RPC_OPTION, OTHER_VALUE) {};
38+
private static final Option OPTION_NOT_EQUALS2 = new Option(ANOTHER_RPC_OPTION, VALUE) {};
39+
40+
@Rule
41+
public ExpectedException thrown = ExpectedException.none();
42+
43+
@Test
44+
public void testEquals() {
45+
assertEquals(OPTION, OPTION_EQUALS);
46+
assertNotEquals(OPTION, OPTION_NOT_EQUALS1);
47+
assertNotEquals(OPTION, OPTION_NOT_EQUALS2);
48+
}
49+
2750
@Test
28-
public void testOption() {
29-
Option option = new Option(BigQueryRpc.Option.PAGE_TOKEN, "token");
30-
assertEquals(BigQueryRpc.Option.PAGE_TOKEN, option.rpcOption());
31-
assertEquals("token", option.value());
51+
public void testHashCode() {
52+
assertEquals(OPTION.hashCode(), OPTION_EQUALS.hashCode());
3253
}
3354

34-
@Test(expected = NullPointerException.class)
35-
public void testNullRpcOption() {
36-
new Option(null, "token");
55+
@Test
56+
public void testConstructor() {
57+
assertEquals(RPC_OPTION, OPTION.rpcOption());
58+
assertEquals(VALUE, OPTION.value());
59+
Option option = new Option(RPC_OPTION, null) {};
60+
assertEquals(RPC_OPTION, option.rpcOption());
61+
assertNull(option.value());
62+
thrown.expect(NullPointerException.class);
63+
new Option(null, VALUE) {};
3764
}
3865
}

gcloud-java-core/src/main/java/com/google/gcloud/FieldSelector.java

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,18 @@
1616

1717
package com.google.gcloud;
1818

19+
import com.google.common.base.Function;
20+
import com.google.common.base.Joiner;
21+
import com.google.common.collect.Lists;
22+
import com.google.common.collect.Sets;
23+
24+
import java.util.Arrays;
25+
import java.util.List;
26+
import java.util.Set;
27+
1928
/**
2029
* Interface for Google Cloud resource's fields. Implementations of this interface can be used to
21-
* select only desired fields when getting or listing Google Cloud resources.
30+
* select only desired fields from a returned Google Cloud resource.
2231
*/
2332
public interface FieldSelector {
2433

@@ -27,4 +36,61 @@ public interface FieldSelector {
2736
* other field selectors) to specify which resource fields should be returned by an API call.
2837
*/
2938
String selector();
39+
40+
/**
41+
* A helper class used to build composite selectors given a number of fields. This class is not
42+
* supposed to be used directly by users.
43+
*/
44+
class SelectorHelper {
45+
46+
private SelectorHelper() {}
47+
48+
private static final Function<FieldSelector, String> FIELD_TO_STRING_FUNCTION =
49+
new Function<FieldSelector, String>() {
50+
@Override
51+
public String apply(FieldSelector fieldSelector) {
52+
return fieldSelector.selector();
53+
}
54+
};
55+
56+
private static String selector(List<FieldSelector> required, FieldSelector[] others,
57+
String... extraResourceFields) {
58+
Set<String> fieldStrings = Sets.newHashSetWithExpectedSize(required.size() + others.length);
59+
fieldStrings.addAll(Lists.transform(required, FIELD_TO_STRING_FUNCTION));
60+
fieldStrings.addAll(Lists.transform(Arrays.asList(others), FIELD_TO_STRING_FUNCTION));
61+
fieldStrings.addAll(Arrays.asList(extraResourceFields));
62+
return Joiner.on(',').join(fieldStrings);
63+
}
64+
65+
/**
66+
* Returns a composite selector given a number of fields. The string selector returned by this
67+
* method can be used for field selection in API calls that return a single resource. This
68+
* method is not supposed to be used directly by users.
69+
*/
70+
public static String selector(List<FieldSelector> required, FieldSelector... others) {
71+
return selector(required, others, new String[]{});
72+
}
73+
74+
/**
75+
* Returns a composite selector given a number of fields and a container name. The string
76+
* selector returned by this method can be used for field selection in API calls that return a
77+
* list of resources. This method is not supposed to be used directly by users.
78+
*/
79+
public static String selector(String containerName, List<FieldSelector> required,
80+
FieldSelector... others) {
81+
return "nextPageToken," + containerName + '(' + selector(required, others) + ')';
82+
}
83+
84+
/**
85+
* Returns a composite selector given a number of fields and a container name. This methods also
86+
* takes an {@code extraResourceFields} parameter to specify some extra fields as strings. The
87+
* string selector returned by this method can be used for field selection in API calls that
88+
* return a list of resources. This method is not supposed to be used directly by users.
89+
*/
90+
public static String selector(String containerName, List<FieldSelector> required,
91+
FieldSelector[] others, String... extraResourceFields) {
92+
return "nextPageToken," + containerName + '('
93+
+ selector(required, others, extraResourceFields) + ')';
94+
}
95+
}
3096
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* Copyright 2016 Google Inc. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.gcloud;
18+
19+
import static org.junit.Assert.assertEquals;
20+
import static org.junit.Assert.assertTrue;
21+
22+
import com.google.common.collect.ImmutableList;
23+
import com.google.gcloud.FieldSelector.SelectorHelper;
24+
25+
import org.junit.Test;
26+
27+
import java.util.List;
28+
29+
public class SelectorHelperTest {
30+
31+
private static final FieldSelector FIELD1 = new FieldSelector() {
32+
@Override
33+
public String selector() {
34+
return "field1";
35+
}
36+
};
37+
private static final FieldSelector FIELD2 = new FieldSelector() {
38+
@Override
39+
public String selector() {
40+
return "field2";
41+
}
42+
};
43+
private static final FieldSelector FIELD3 = new FieldSelector() {
44+
@Override
45+
public String selector() {
46+
return "field3";
47+
}
48+
};
49+
private static final List<FieldSelector> REQUIRED_FIELDS = ImmutableList.of(FIELD1, FIELD2);
50+
private static final String CONTAINER = "container";
51+
52+
@Test
53+
public void testSelector() {
54+
String selector = SelectorHelper.selector(REQUIRED_FIELDS, FIELD3);
55+
assertTrue(selector.contains("field1"));
56+
assertTrue(selector.contains("field2"));
57+
assertTrue(selector.contains("field3"));
58+
assertEquals(20, selector.length());
59+
}
60+
61+
@Test
62+
public void testListSelector() {
63+
String selector = SelectorHelper.selector(CONTAINER, REQUIRED_FIELDS, FIELD3);
64+
assertTrue(selector.startsWith("nextPageToken,container("));
65+
assertTrue(selector.contains("field1"));
66+
assertTrue(selector.contains("field2"));
67+
assertTrue(selector.contains("field3"));
68+
assertTrue(selector.endsWith(")"));
69+
assertEquals(45, selector.length());
70+
}
71+
}

0 commit comments

Comments
 (0)