Skip to content

Commit 0074a7c

Browse files
joerg1985pujagani
andauthored
[java] removed use of guava from devtools (#12943)
Co-authored-by: Puja Jagani <[email protected]>
1 parent a98e61f commit 0074a7c

25 files changed

+141
-93
lines changed

java/src/org/openqa/selenium/devtools/BUILD.bazel

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ java_library(
2222
deps = [
2323
"//java/src/org/openqa/selenium:core",
2424
"//java/src/org/openqa/selenium/json",
25-
artifact("com.google.guava:guava"),
2625
],
2726
)
2827

@@ -76,7 +75,6 @@ java_library(
7675
"//java/src/org/openqa/selenium:core",
7776
"//java/src/org/openqa/selenium/json",
7877
"//java/src/org/openqa/selenium/remote/http",
79-
artifact("com.google.guava:guava"),
8078
],
8179
)
8280

java/src/org/openqa/selenium/devtools/CdpClientGenerator.java

Lines changed: 48 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import java.nio.file.SimpleFileVisitor;
4141
import java.nio.file.attribute.BasicFileAttributes;
4242
import java.util.ArrayList;
43+
import java.util.LinkedHashMap;
4344
import java.util.List;
4445
import java.util.Map;
4546
import java.util.Objects;
@@ -287,7 +288,8 @@ private void dumpMainClass(Path target) {
287288
unit.addImport(Command.class);
288289
unit.addImport(Event.class);
289290
unit.addImport(ConverterFunctions.class);
290-
unit.addImport(ImmutableMap.class);
291+
unit.addImport(Map.class);
292+
unit.addImport(LinkedHashMap.class);
291293
unit.addImport(JsonInput.class);
292294

293295
ClassOrInterfaceDeclaration classDecl = unit.addClass(name);
@@ -640,7 +642,7 @@ public MethodDeclaration toMethodDeclaration() {
640642
String.format(
641643
"java.util.Objects.requireNonNull(%s, \"%s is required\");",
642644
name, name)));
643-
body.addStatement("ImmutableMap.Builder<String, Object> params = ImmutableMap.builder();");
645+
body.addStatement("LinkedHashMap<String, Object> params = new LinkedHashMap<>();");
644646
parameters.forEach(
645647
parameter -> {
646648
if (parameter.optional) {
@@ -655,16 +657,17 @@ public MethodDeclaration toMethodDeclaration() {
655657

656658
if (type instanceof VoidType) {
657659
body.addStatement(
658-
String.format("return new Command<>(\"%s.%s\", params.build());", domain.name, name));
660+
String.format(
661+
"return new Command<>(\"%s.%s\", Map.copyOf(params));", domain.name, name));
659662
} else if (type instanceof ObjectType) {
660663
body.addStatement(
661664
String.format(
662-
"return new Command<>(\"%s.%s\", params.build(), input -> %s);",
665+
"return new Command<>(\"%s.%s\", Map.copyOf(params), input -> %s);",
663666
domain.name, name, type.getMapper()));
664667
} else {
665668
body.addStatement(
666669
String.format(
667-
"return new Command<>(\"%s.%s\", params.build(), ConverterFunctions.map(\"%s\","
670+
"return new Command<>(\"%s.%s\", Map.copyOf(params), ConverterFunctions.map(\"%s\","
668671
+ " %s));",
669672
domain.name, name, type.getName(), type.getTypeToken()));
670673
}
@@ -792,8 +795,7 @@ public String getName() {
792795
@Override
793796
public String getTypeToken() {
794797
if (type.equals("object")) {
795-
return "new com.google.common.reflect.TypeToken<java.util.Map<String, Object>>()"
796-
+ " {}.getType()";
798+
return "java.util.Map.class";
797799
} else {
798800
return getJavaType() + ".class";
799801
}
@@ -844,7 +846,7 @@ public TypeDeclaration<?> toTypeDeclaration() {
844846
ClassOrInterfaceDeclaration classDecl = new ClassOrInterfaceDeclaration().setName(name);
845847

846848
if (type.equals("object")) {
847-
classDecl.addExtendedType("com.google.common.collect.ForwardingMap<String, Object>");
849+
classDecl.addExtendedType("java.util.AbstractMap<String, Object>");
848850
}
849851

850852
String propertyName = decapitalize(name);
@@ -860,6 +862,31 @@ public TypeDeclaration<?> toTypeDeclaration() {
860862
propertyName, propertyName, name));
861863

862864
if (type.equals("object")) {
865+
// we only need to implement entrySet and put to have a working map
866+
MethodDeclaration entrySet = classDecl.addMethod("entrySet").setPublic(true);
867+
entrySet.setType("java.util.Set<java.util.Map.Entry<String, Object>>");
868+
entrySet.getBody().get().addStatement(String.format("return %s.entrySet();", propertyName));
869+
870+
MethodDeclaration put = classDecl.addMethod("put").setPublic(true);
871+
put.setType("Object");
872+
put.addParameter("String", "key");
873+
put.addParameter("Object", "value");
874+
put.getBody().get().addStatement(String.format("return %s.put(key, value);", propertyName));
875+
876+
// containsKey and get are implemented to have better performance
877+
MethodDeclaration containsKey = classDecl.addMethod("containsKey").setPublic(true);
878+
containsKey.setType("boolean");
879+
containsKey.addParameter("String", "key");
880+
containsKey
881+
.getBody()
882+
.get()
883+
.addStatement(String.format("return %s.containsKey(key);", propertyName));
884+
885+
MethodDeclaration get = classDecl.addMethod("get").setPublic(true);
886+
get.setType("Object");
887+
get.addParameter("String", "key");
888+
get.getBody().get().addStatement(String.format("return %s.get(key);", propertyName));
889+
863890
MethodDeclaration delegate = classDecl.addMethod("delegate").setProtected(true);
864891
delegate.setType("java.util.Map<String, Object>");
865892
delegate.getBody().get().addStatement(String.format("return %s;", propertyName));
@@ -906,8 +933,7 @@ public String getMapper() {
906933
case "any":
907934
return "input.read(Object.class)";
908935
case "object":
909-
return "input.read(new com.google.common.reflect.TypeToken<java.util.Map<String,"
910-
+ " Object>>() {}.getType())";
936+
return "(java.util.Map<String, Object>) input.read(java.util.Map.class)";
911937
case "array":
912938
return "input.nextString()";
913939
default:
@@ -1192,8 +1218,7 @@ public ArrayType(String name) {
11921218

11931219
@Override
11941220
public String getTypeToken() {
1195-
return String.format(
1196-
"new com.google.common.reflect.TypeToken<%s>() {}.getType()", getJavaType());
1221+
return "java.util.List.class";
11971222
}
11981223

11991224
@Override
@@ -1229,7 +1254,7 @@ public TypeDeclaration<?> toTypeDeclaration() {
12291254
MethodDeclaration fromJson = classDecl.addMethod("fromJson").setPrivate(true).setStatic(true);
12301255
fromJson.setType(name);
12311256
fromJson.addParameter(JsonInput.class, "input");
1232-
fromJson.getBody().get().addStatement(String.format("return %s;", getMapper()));
1257+
fromJson.getBody().get().addStatement(String.format("return new %s(%s);", name, getMapper()));
12331258

12341259
MethodDeclaration toString = classDecl.addMethod("toString").setPublic(true);
12351260
toString.setType(String.class);
@@ -1240,9 +1265,16 @@ public TypeDeclaration<?> toTypeDeclaration() {
12401265

12411266
@Override
12421267
public String getMapper() {
1243-
return String.format(
1244-
"input.read(new com.google.common.reflect.TypeToken<java.util.List<%s>>() {}.getType())",
1245-
itemType.getJavaType());
1268+
String itemTypeToken = itemType.getTypeToken();
1269+
1270+
if (getTypeToken().equals(itemTypeToken)) {
1271+
// This would end up with a List<List<Map<String, Object>>> instead of the target type of
1272+
// List<List<T>>. It is unlikely this must ever be supported, fail with an error while
1273+
// generating the CDP client code for now.
1274+
throw new UnsupportedOperationException("nested arrays are not supported");
1275+
}
1276+
1277+
return "input.readArray(" + itemTypeToken + ")";
12461278
}
12471279

12481280
public void parse(Domain domain, Map<String, Object> json) {

java/src/org/openqa/selenium/devtools/CdpVersionFinder.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717

1818
package org.openqa.selenium.devtools;
1919

20-
import com.google.common.collect.ImmutableSet;
2120
import java.util.Collection;
2221
import java.util.Map;
2322
import java.util.Optional;
@@ -53,7 +52,7 @@ public CdpVersionFinder(int versionFudgeFactor, Collection<CdpInfo> infos) {
5352

5453
Require.nonNull("CDP versions", infos);
5554

56-
this.infos = ImmutableSet.copyOf(infos);
55+
this.infos = Set.copyOf(infos);
5756
}
5857

5958
/**

java/src/org/openqa/selenium/devtools/Command.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717

1818
package org.openqa.selenium.devtools;
1919

20-
import com.google.common.collect.ImmutableMap;
2120
import java.lang.reflect.Type;
2221
import java.util.Map;
2322
import java.util.function.Function;
@@ -49,7 +48,7 @@ private Command(
4948
Function<JsonInput, X> mapper,
5049
boolean sendsResponse) {
5150
this.method = Require.nonNull("Method name", method);
52-
this.params = ImmutableMap.copyOf(Require.nonNull("Command parameters", params));
51+
this.params = Map.copyOf(Require.nonNull("Command parameters", params));
5352
this.mapper = Require.nonNull("Mapper for result", mapper);
5453

5554
this.sendsResponse = sendsResponse;

java/src/org/openqa/selenium/devtools/Connection.java

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,13 @@
2222
import static org.openqa.selenium.json.Json.MAP_TYPE;
2323
import static org.openqa.selenium.remote.http.HttpMethod.GET;
2424

25-
import com.google.common.collect.HashMultimap;
26-
import com.google.common.collect.ImmutableMap;
27-
import com.google.common.collect.Multimap;
2825
import java.io.Closeable;
2926
import java.io.StringReader;
3027
import java.time.Duration;
28+
import java.util.ArrayList;
29+
import java.util.HashMap;
30+
import java.util.LinkedHashMap;
31+
import java.util.List;
3132
import java.util.Map;
3233
import java.util.concurrent.CompletableFuture;
3334
import java.util.concurrent.ConcurrentHashMap;
@@ -70,7 +71,7 @@ public class Connection implements Closeable {
7071
private final Map<Long, Consumer<Either<Throwable, JsonInput>>> methodCallbacks =
7172
new ConcurrentHashMap<>();
7273
private final ReadWriteLock callbacksLock = new ReentrantReadWriteLock(true);
73-
private final Multimap<Event<?>, Consumer<?>> eventCallbacks = HashMultimap.create();
74+
private final Map<Event<?>, List<Consumer<?>>> eventCallbacks = new HashMap<>();
7475
private final HttpClient client;
7576
private final String url;
7677
private final AtomicBoolean isClosed;
@@ -144,7 +145,7 @@ public <X> CompletableFuture<X> send(SessionID sessionId, Command<X> command) {
144145
}));
145146
}
146147

147-
ImmutableMap.Builder<String, Object> serialized = ImmutableMap.builder();
148+
Map<String, Object> serialized = new LinkedHashMap<>();
148149
serialized.put("id", id);
149150
serialized.put("method", command.getMethod());
150151
serialized.put("params", command.getParams());
@@ -154,7 +155,7 @@ public <X> CompletableFuture<X> send(SessionID sessionId, Command<X> command) {
154155

155156
StringBuilder json = new StringBuilder();
156157
try (JsonOutput out = JSON.newOutput(json).writeClassName(false)) {
157-
out.write(serialized.build());
158+
out.write(Map.copyOf(serialized));
158159
}
159160
LOG.log(getDebugLogLevel(), "-> {0}", json);
160161
socket.sendText(json);
@@ -191,7 +192,7 @@ public <X> void addListener(Event<X> event, Consumer<X> handler) {
191192
Lock lock = callbacksLock.writeLock();
192193
lock.lock();
193194
try {
194-
eventCallbacks.put(event, handler);
195+
eventCallbacks.computeIfAbsent(event, (key) -> new ArrayList<>()).add(handler);
195196
} finally {
196197
lock.unlock();
197198
}
@@ -285,14 +286,14 @@ private void handle(CharSequence data) {
285286
}
286287
try {
287288
// TODO: Also only decode once.
288-
eventCallbacks.keySet().stream()
289+
eventCallbacks.entrySet().stream()
289290
.peek(
290291
event ->
291292
LOG.log(
292293
getDebugLogLevel(),
293294
"Matching {0} with {1}",
294-
new Object[] {raw.get("method"), event.getMethod()}))
295-
.filter(event -> raw.get("method").equals(event.getMethod()))
295+
new Object[] {raw.get("method"), event.getKey().getMethod()}))
296+
.filter(event -> raw.get("method").equals(event.getKey().getMethod()))
296297
.forEach(
297298
event -> {
298299
// TODO: This is grossly inefficient. I apologise, and we should fix this.
@@ -303,7 +304,7 @@ private void handle(CharSequence data) {
303304
while (input.hasNext()) {
304305
switch (input.nextName()) {
305306
case "params":
306-
value = event.getMapper().apply(input);
307+
value = event.getKey().getMapper().apply(input);
307308
break;
308309

309310
default:
@@ -320,13 +321,13 @@ private void handle(CharSequence data) {
320321

321322
final Object finalValue = value;
322323

323-
for (Consumer<?> action : eventCallbacks.get(event)) {
324+
for (Consumer<?> action : event.getValue()) {
324325
@SuppressWarnings("unchecked")
325326
Consumer<Object> obj = (Consumer<Object>) action;
326327
LOG.log(
327328
getDebugLogLevel(),
328329
"Calling callback for {0} using {1} being passed {2}",
329-
new Object[] {event, obj, finalValue});
330+
new Object[] {event.getKey(), obj, finalValue});
330331
obj.accept(finalValue);
331332
}
332333
}

java/src/org/openqa/selenium/devtools/events/CdpEventTypes.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,8 @@
2020
import static java.nio.charset.StandardCharsets.UTF_8;
2121
import static org.openqa.selenium.json.Json.MAP_TYPE;
2222

23-
import com.google.common.io.Resources;
2423
import java.io.IOException;
25-
import java.net.URL;
24+
import java.io.InputStream;
2625
import java.util.List;
2726
import java.util.Map;
2827
import java.util.function.Consumer;
@@ -68,13 +67,14 @@ public void initializeListener(WebDriver webDriver) {
6867
public static EventType<Void> domMutation(Consumer<DomMutationEvent> handler) {
6968
Require.nonNull("Handler", handler);
7069

71-
URL url = CdpEventTypes.class.getResource("/org/openqa/selenium/devtools/mutation-listener.js");
72-
if (url == null) {
73-
throw new IllegalStateException("Unable to find helper script");
74-
}
7570
String script;
76-
try {
77-
script = Resources.toString(url, UTF_8);
71+
try (InputStream stream =
72+
CdpEventTypes.class.getResourceAsStream(
73+
"/org/openqa/selenium/devtools/mutation-listener.js")) {
74+
if (stream == null) {
75+
throw new IllegalStateException("Unable to find helper script");
76+
}
77+
script = new String(stream.readAllBytes(), UTF_8);
7878
} catch (IOException e) {
7979
throw new IllegalStateException("Unable to read helper script");
8080
}

java/src/org/openqa/selenium/devtools/events/ConsoleEvent.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717

1818
package org.openqa.selenium.devtools.events;
1919

20-
import com.google.common.collect.ImmutableList;
2120
import java.time.Instant;
2221
import java.util.List;
2322
import java.util.Objects;
@@ -36,7 +35,7 @@ public ConsoleEvent(String type, Instant timestamp, List<Object> modifiedArgs, O
3635
this.type = type;
3736
this.timestamp = timestamp;
3837
this.modifiedArgs = modifiedArgs;
39-
this.args = ImmutableList.copyOf(args);
38+
this.args = List.of(args);
4039
}
4140

4241
public String getType() {

java/src/org/openqa/selenium/devtools/v116/BUILD.bazel

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
load("@rules_jvm_external//:defs.bzl", "artifact")
21
load("//common:defs.bzl", "copy_file")
32
load("//java:defs.bzl", "java_export", "java_library")
43
load("//java:version.bzl", "SE_VERSION")
@@ -25,7 +24,6 @@ java_export(
2524
"//java/src/org/openqa/selenium:core",
2625
"//java/src/org/openqa/selenium/json",
2726
"//java/src/org/openqa/selenium/remote",
28-
artifact("com.google.guava:guava"),
2927
],
3028
)
3129

@@ -41,7 +39,6 @@ java_library(
4139
"//java/src/org/openqa/selenium:core",
4240
"//java/src/org/openqa/selenium/json",
4341
"//java/src/org/openqa/selenium/remote",
44-
artifact("com.google.guava:guava"),
4542
],
4643
)
4744

java/src/org/openqa/selenium/devtools/v116/v116Events.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@
1717

1818
package org.openqa.selenium.devtools.v116;
1919

20-
import com.google.common.collect.ImmutableList;
2120
import java.time.Instant;
2221
import java.util.List;
2322
import java.util.Optional;
23+
import java.util.stream.Collectors;
2424
import org.openqa.selenium.JavascriptException;
2525
import org.openqa.selenium.devtools.Command;
2626
import org.openqa.selenium.devtools.DevTools;
@@ -67,7 +67,7 @@ protected ConsoleEvent toConsoleEvent(ConsoleAPICalled event) {
6767
List<Object> modifiedArgs =
6868
event.getArgs().stream()
6969
.map(obj -> new RemoteObject(obj.getType().toString(), obj.getValue().orElse(null)))
70-
.collect(ImmutableList.toImmutableList());
70+
.collect(Collectors.toUnmodifiableList());
7171

7272
return new ConsoleEvent(
7373
event.getType().toString(), Instant.ofEpochMilli(ts), modifiedArgs, event.getArgs());

0 commit comments

Comments
 (0)