Skip to content

Commit 4e1189e

Browse files
committed
Improve collection setters, change back builder setters to functions
1 parent 0af73c2 commit 4e1189e

File tree

10 files changed

+298
-70
lines changed

10 files changed

+298
-70
lines changed

java-client/src/main/java/co/elastic/clients/util/ModelTypeHelper.java

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,8 @@ public static <T> T requireNonNull(T value, Object obj, String name) {
8080

8181
//----- Lists
8282

83-
private static final List<Object> UNDEFINED_LIST = new AbstractList<Object>() {
83+
/** Immutable empty list implementation so that we can create marker list objects */
84+
static class EmptyList extends AbstractList<Object> {
8485
@Override
8586
public Object get(int index) {
8687
throw new IndexOutOfBoundsException();
@@ -97,6 +98,9 @@ public Iterator<Object> iterator() {
9798
}
9899
};
99100

101+
static final List<Object> UNDEFINED_LIST = new EmptyList();
102+
static final List<Object> RESET_LIST = new EmptyList();
103+
100104
/**
101105
* Returns an empty list that is undefined from a JSON perspective. It will not be serialized
102106
* when used as the value of an array property in API objects.
@@ -106,6 +110,11 @@ public static <T> List<T> undefinedList() {
106110
return (List<T>)UNDEFINED_LIST;
107111
}
108112

113+
@SuppressWarnings("unchecked")
114+
public static <T> List<T> resetList() {
115+
return (List<T>)RESET_LIST;
116+
}
117+
109118
/**
110119
* Is {@code list} defined according to JSON/JavaScript semantics?
111120
*
@@ -141,12 +150,15 @@ public static <T> List<T> unmodifiableRequired(List<T> list, Object obj, String
141150

142151
//----- Maps
143152

144-
private static final Map<Object, Object> UNDEFINED_MAP = new AbstractMap<Object, Object>() {
153+
static class EmptyMap extends AbstractMap<Object, Object> {
145154
@Override
146155
public Set<Entry<Object, Object>> entrySet() {
147156
return Collections.emptySet();
148157
}
149-
};
158+
}
159+
160+
static final Map<Object, Object> UNDEFINED_MAP = new EmptyMap();
161+
static final Map<Object, Object> RESET_MAP = new ModelTypeHelper.EmptyMap();
150162

151163
/**
152164
* Returns an empty list that is undefined from a JSON perspective. It will not be serialized
@@ -157,6 +169,11 @@ public static <K, V> Map<K, V> undefinedMap() {
157169
return (Map<K, V>)UNDEFINED_MAP;
158170
}
159171

172+
@SuppressWarnings("unchecked")
173+
public static <K, V> Map<K, V> resetMap() {
174+
return (Map<K, V>)RESET_MAP;
175+
}
176+
160177
/**
161178
* Is {@code map} defined according to JSON/JavaScript semantics?
162179
*

java-client/src/main/java/co/elastic/clients/util/ObjectBuilderBase.java

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@
1919

2020
package co.elastic.clients.util;
2121

22+
import java.util.ArrayList;
23+
import java.util.Arrays;
24+
import java.util.Collection;
25+
import java.util.HashMap;
26+
import java.util.List;
27+
import java.util.Map;
28+
2229
public class ObjectBuilderBase {
2330
private boolean _used = false;
2431

@@ -28,4 +35,95 @@ protected void _checkSingleUse() {
2835
}
2936
this._used = true;
3037
}
38+
39+
//----- List utilities
40+
41+
/** A private extension of ArrayList so that we can recognize our own creations */
42+
static final class InternalList<T> extends ArrayList<T> {
43+
InternalList() {
44+
}
45+
46+
InternalList(Collection<? extends T> c) {
47+
super(c);
48+
}
49+
};
50+
51+
/** Get a mutable list from the current list value of an object builder property */
52+
private static <T> List<T> _mutableList(List<T> list) {
53+
if (list == null) {
54+
return new InternalList<>();
55+
} else if (list instanceof InternalList) {
56+
return list;
57+
} else {
58+
// Adding to a list we don't own: make a defensive copy, also ensuring it is mutable.
59+
return new InternalList<>(list);
60+
}
61+
}
62+
63+
/** Add a value to a (possibly {@code null}) list */
64+
@SafeVarargs
65+
protected static <T> List<T> _listAdd(List<T> list, T value, T... values) {
66+
list = _mutableList(list);
67+
list.add(value);
68+
if (values.length > 0) {
69+
list.addAll(Arrays.asList(values));
70+
}
71+
return list;
72+
}
73+
74+
/** Add all elements of a list to a (possibly {@code null}) list */
75+
protected static <T> List<T> _listAddAll(List<T> list, List<T> values) {
76+
if (list == null) {
77+
// Keep the original list to avoid an unnecessary copy.
78+
// It will be copied if we add more values.
79+
return values;
80+
} else if (values == ModelTypeHelper.RESET_LIST) {
81+
return null;
82+
} else {
83+
list = _mutableList(list);
84+
list.addAll(values);
85+
return list;
86+
}
87+
}
88+
89+
//----- Map utilities
90+
91+
/** A private extension of HashMap so that we can recognize our own creations */
92+
private static final class InternalMap<K, V> extends HashMap<K, V> {
93+
InternalMap() {
94+
}
95+
96+
InternalMap(Map<? extends K, ? extends V> m) {
97+
super(m);
98+
}
99+
}
100+
101+
/** Get a mutable map from the current map value of an object builder property */
102+
private static <K, V> Map<K, V> _mutableMap(Map<K, V> map) {
103+
if (map == null) {
104+
return new InternalMap<>();
105+
} else if (map instanceof InternalMap) {
106+
return map;
107+
} else {
108+
// Adding to a map we don't own: make a defensive copy, also ensuring it is mutable.
109+
return new InternalMap<>(map);
110+
}
111+
}
112+
113+
/** Add a value to a (possibly {@code null}) map */
114+
protected static <K, V> Map<K, V> _mapPut(Map<K, V> map, K key, V value) {
115+
map = _mutableMap(map);
116+
map.put(key, value);
117+
return map;
118+
}
119+
120+
/** Add all elements of a list to a (possibly {@code null}) map */
121+
protected static <K, V> Map<K, V> _mapPutAll(Map<K, V> map, Map<K, V> entries) {
122+
if (entries == ModelTypeHelper.RESET_MAP) {
123+
return null;
124+
}
125+
map = _mutableMap(map);
126+
map.putAll(entries);
127+
return map;
128+
}
31129
}

java-client/src/test/java/co/elastic/clients/elasticsearch/end_to_end/RequestTest.java

Lines changed: 34 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -189,16 +189,13 @@ public void testDataIngestion() throws Exception {
189189
// MSearch: 1st search on an existing index, 2nd one on a non-existing index
190190
final MsearchResponse<AppData> msearch = client.msearch(_0 -> _0
191191
.searches(_1 -> _1
192-
.add(_2 -> _2
193-
.header(_3 -> _3.index(index))
194-
.body(_3 -> _3.query(_4 -> _4.matchAll(_5 -> {})))
195-
)
196-
.add(_2 -> _2
197-
.header(_3 -> _3.index("non-existing"))
198-
.body(_3 -> _3.query(_4 -> _4.matchAll(_5 -> {})))
199-
)
192+
.header(_3 -> _3.index(index))
193+
.body(_3 -> _3.query(_4 -> _4.matchAll(_5 -> _5)))
194+
).searches(_1 -> _1
195+
.header(_3 -> _3.index("non-existing"))
196+
.body(_3 -> _3.query(_4 -> _4.matchAll(_5 -> _5)))
200197
)
201-
, AppData.class);
198+
, AppData.class);
202199

203200
assertEquals(2, msearch.responses().size());
204201
assertTrue(msearch.responses().get(0).isResult());
@@ -210,7 +207,7 @@ public void testDataIngestion() throws Exception {
210207
@Test
211208
public void testCatRequest() throws IOException {
212209
// Cat requests should have the "format=json" added by the transport
213-
NodesResponse nodes = client.cat().nodes(_0 -> {});
210+
NodesResponse nodes = client.cat().nodes(_0 -> _0);
214211
System.out.println(ModelTestCase.toJson(nodes, mapper));
215212

216213
assertEquals(1, nodes.valueBody().size());
@@ -225,20 +222,17 @@ public void testBulkRequest() throws IOException {
225222

226223
BulkResponse bulk = client.bulk(_0 -> _0
227224
.operations(_1 -> _1
228-
.add(_2 -> _2
229-
.create(_3 -> _3
230-
.index("foo")
231-
.id("abc")
232-
.document(appData)
233-
)
234-
).add(_2 -> _2
235-
.create(_3 -> _3
236-
.index("foo")
237-
.id("def")
238-
.document(appData)
239-
)
240-
)
241-
)
225+
.create(_2 -> _2
226+
.index("foo")
227+
.id("abc")
228+
.document(appData)
229+
))
230+
.operations(_1 -> _1
231+
.create(_2 -> _2
232+
.index("foo")
233+
.id("def")
234+
.document(appData)
235+
))
242236
);
243237

244238
assertFalse(bulk.errors());
@@ -324,16 +318,14 @@ public void testSearchAggregation() throws IOException {
324318
SearchResponse<Product> searchResponse = client.search(_1 -> _1
325319
.index("products")
326320
.size(0)
327-
.aggregations(_2 -> _2
328-
.put("prices", _3 -> _3
329-
.histogram(_4 -> _4
330-
.field("price")
331-
.interval(10.0)
332-
).aggregations(_4 -> _4
333-
.put("average", _5 -> _5
334-
.avg(_6 -> _6.field("price"))
335-
)
336-
)
321+
.aggregations(
322+
"prices", _3 -> _3
323+
.histogram(_4 -> _4
324+
.field("price")
325+
.interval(10.0)
326+
).aggregations(
327+
"average", _5 -> _5
328+
.avg(_6 -> _6.field("price"))
337329
)
338330
)
339331
, Product.class
@@ -360,15 +352,15 @@ public void testGetMapping() throws Exception {
360352

361353
client.indices().create(c -> c
362354
.index(index)
363-
.mappings(m -> m.properties(ps -> ps
364-
.put("id", text)
365-
.put("name", p -> p
366-
.object(o -> o.properties(fs -> fs
367-
.put("first", text)
368-
.put("last", text)
369-
))
355+
.mappings(m -> m
356+
.properties("id", text)
357+
.properties("name", p -> p
358+
.object(o -> o
359+
.properties("first", text)
360+
.properties("last", text)
361+
)
370362
)
371-
))
363+
)
372364
);
373365

374366
GetMappingResponse mr = client.indices().getMapping(mrb -> mrb.index(index));

0 commit comments

Comments
 (0)