Skip to content

Commit dfee472

Browse files
committed
Make immutable capabilities be based on an immutable data store
1 parent 0f2795d commit dfee472

File tree

4 files changed

+231
-111
lines changed

4 files changed

+231
-111
lines changed

java/client/src/org/openqa/selenium/ImmutableCapabilities.java

Lines changed: 117 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -19,39 +19,85 @@
1919

2020
import org.openqa.selenium.internal.Require;
2121

22+
import java.util.Collections;
2223
import java.util.Map;
24+
import java.util.Objects;
25+
import java.util.Set;
26+
import java.util.TreeMap;
27+
28+
import static org.openqa.selenium.SharedCapabilitiesMethods.setCapability;
2329

2430
public class ImmutableCapabilities implements Capabilities {
2531

26-
private MutableCapabilities delegate = new MutableCapabilities();
32+
private final Map<String, Object> delegate;
2733

2834
public ImmutableCapabilities() {
35+
this.delegate = Collections.emptyMap();
2936
}
3037

3138
public ImmutableCapabilities(String k, Object v) {
32-
delegate.setCapability(k, v);
39+
Require.nonNull("Capability", k);
40+
Require.nonNull("Value", v);
41+
42+
Map<String, Object> delegate = new TreeMap<>();
43+
setCapability(delegate, k, v);
44+
45+
this.delegate = Collections.unmodifiableMap(delegate);
3346
}
3447

3548
public ImmutableCapabilities(String k1, Object v1, String k2, Object v2) {
36-
delegate.setCapability(k1, v1);
37-
delegate.setCapability(k2, v2);
49+
Require.nonNull("First capability", k1);
50+
Require.nonNull("First value", v1);
51+
Require.nonNull("Second capability", k2);
52+
Require.nonNull("Second value", v2);
53+
54+
Map<String, Object> delegate = new TreeMap<>();
55+
56+
setCapability(delegate, k1, v1);
57+
setCapability(delegate, k2, v2);
58+
59+
this.delegate = Collections.unmodifiableMap(delegate);
3860
}
3961

4062
public ImmutableCapabilities(String k1, Object v1, String k2, Object v2, String k3, Object v3) {
41-
delegate.setCapability(k1, v1);
42-
delegate.setCapability(k2, v2);
43-
delegate.setCapability(k3, v3);
63+
Require.nonNull("First capability", k1);
64+
Require.nonNull("First value", v1);
65+
Require.nonNull("Second capability", k2);
66+
Require.nonNull("Second value", v2);
67+
Require.nonNull("Third capability", k3);
68+
Require.nonNull("Third value", v3);
69+
70+
Map<String, Object> delegate = new TreeMap<>();
71+
72+
setCapability(delegate, k1, v1);
73+
setCapability(delegate, k2, v2);
74+
setCapability(delegate, k3, v3);
75+
76+
this.delegate = Collections.unmodifiableMap(delegate);
4477
}
4578

4679
public ImmutableCapabilities(
4780
String k1, Object v1,
4881
String k2, Object v2,
4982
String k3, Object v3,
5083
String k4, Object v4) {
51-
delegate.setCapability(k1, v1);
52-
delegate.setCapability(k2, v2);
53-
delegate.setCapability(k3, v3);
54-
delegate.setCapability(k4, v4);
84+
Require.nonNull("First capability", k1);
85+
Require.nonNull("First value", v1);
86+
Require.nonNull("Second capability", k2);
87+
Require.nonNull("Second value", v2);
88+
Require.nonNull("Third capability", k3);
89+
Require.nonNull("Third value", v3);
90+
Require.nonNull("Fourth capability", k4);
91+
Require.nonNull("Fourth value", v4);
92+
93+
Map<String, Object> delegate = new TreeMap<>();
94+
95+
setCapability(delegate, k1, v1);
96+
setCapability(delegate, k2, v2);
97+
setCapability(delegate, k3, v3);
98+
setCapability(delegate, k4, v4);
99+
100+
this.delegate = Collections.unmodifiableMap(delegate);
55101
}
56102

57103
public ImmutableCapabilities(
@@ -60,34 +106,67 @@ public ImmutableCapabilities(
60106
String k3, Object v3,
61107
String k4, Object v4,
62108
String k5, Object v5) {
63-
delegate.setCapability(k1, v1);
64-
delegate.setCapability(k2, v2);
65-
delegate.setCapability(k3, v3);
66-
delegate.setCapability(k4, v4);
67-
delegate.setCapability(k5, v5);
109+
Require.nonNull("First capability", k1);
110+
Require.nonNull("First value", v1);
111+
Require.nonNull("Second capability", k2);
112+
Require.nonNull("Second value", v2);
113+
Require.nonNull("Third capability", k3);
114+
Require.nonNull("Third value", v3);
115+
Require.nonNull("Fourth capability", k4);
116+
Require.nonNull("Fourth value", v4);
117+
Require.nonNull("Fifth capability", k5);
118+
Require.nonNull("Fifth value", v5);
119+
120+
Map<String, Object> delegate = new TreeMap<>();
121+
122+
setCapability(delegate, k1, v1);
123+
setCapability(delegate, k2, v2);
124+
setCapability(delegate, k3, v3);
125+
setCapability(delegate, k4, v4);
126+
setCapability(delegate, k5, v5);
127+
128+
this.delegate = Collections.unmodifiableMap(delegate);
68129
}
69130

70131
public ImmutableCapabilities(Capabilities other) {
71132
Require.nonNull("Capabilities", other);
72-
other.getCapabilityNames().forEach(name -> delegate.setCapability(name, other.getCapability(name)));
133+
134+
Map<String, Object> delegate = new TreeMap<>();
135+
other.getCapabilityNames().forEach(name -> {
136+
Require.nonNull("Capability name", name);
137+
Object value = other.getCapability(name);
138+
Require.nonNull("Capability value", value);
139+
140+
setCapability(delegate, name, value);
141+
});
142+
143+
this.delegate = Collections.unmodifiableMap(delegate);
73144
}
74145

75146
public ImmutableCapabilities(Map<?, ?> capabilities) {
76147
Require.nonNull("Capabilities", capabilities);
148+
149+
Map<String, Object> delegate = new TreeMap<>();
77150
capabilities.forEach((key, value) -> {
78-
Require.argument("Key", key).instanceOf(String.class);
79-
delegate.setCapability(String.valueOf(key), value);
151+
Require.argument("Capability key", key).instanceOf(String.class);
152+
Object v = capabilities.get(key);
153+
Require.nonNull("Capability value", value);
154+
155+
setCapability(delegate, (String) key, v);
80156
});
157+
158+
this.delegate = Collections.unmodifiableMap(delegate);
81159
}
82160

83161
@Override
84162
public Object getCapability(String capabilityName) {
85-
return delegate.getCapability(capabilityName);
163+
Require.nonNull("Capability name", capabilityName);
164+
return delegate.get(capabilityName);
86165
}
87166

88167
@Override
89168
public Map<String, Object> asMap() {
90-
return delegate.asMap();
169+
return delegate;
91170
}
92171

93172
@Override
@@ -100,15 +179,29 @@ public boolean equals(Object o) {
100179
if (this == o) {
101180
return true;
102181
}
182+
103183
if (!(o instanceof Capabilities)) {
104184
return false;
105185
}
106-
return delegate.equals(o);
186+
187+
Capabilities other = (Capabilities) o;
188+
Set<String> names = other.getCapabilityNames();
189+
if (names.size() != delegate.size()) {
190+
return false;
191+
}
192+
193+
for (String name : names) {
194+
if (!Objects.equals(delegate.get(name), other.getCapability(name))) {
195+
return false;
196+
}
197+
}
198+
199+
return true;
107200
}
108201

109202
@Override
110203
public String toString() {
111-
return delegate.toString();
204+
return SharedCapabilitiesMethods.toString(delegate);
112205
}
113206

114207
public static ImmutableCapabilities copyOf(Capabilities capabilities) {
@@ -120,4 +213,5 @@ public static ImmutableCapabilities copyOf(Capabilities capabilities) {
120213

121214
return new ImmutableCapabilities(capabilities);
122215
}
216+
123217
}

java/client/src/org/openqa/selenium/MutableCapabilities.java

Lines changed: 2 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,13 @@
1818
package org.openqa.selenium;
1919

2020
import org.openqa.selenium.internal.Require;
21-
import org.openqa.selenium.logging.LogLevelMapping;
22-
import org.openqa.selenium.logging.LoggingPreferences;
2321

24-
import java.util.Collection;
2522
import java.util.Collections;
26-
import java.util.Comparator;
2723
import java.util.HashSet;
28-
import java.util.IdentityHashMap;
2924
import java.util.Map;
3025
import java.util.Objects;
3126
import java.util.Set;
3227
import java.util.TreeMap;
33-
import java.util.stream.Collectors;
34-
import java.util.stream.Stream;
3528

3629
public class MutableCapabilities implements Capabilities {
3730

@@ -109,31 +102,7 @@ public void setCapability(String key, Object value) {
109102
return;
110103
}
111104

112-
if ("loggingPrefs".equals(key) && value instanceof Map) {
113-
LoggingPreferences prefs = new LoggingPreferences();
114-
@SuppressWarnings("unchecked") Map<String, String> prefsMap = (Map<String, String>) value;
115-
116-
prefsMap.forEach((pKey, pValue) -> prefs.enable(pKey, LogLevelMapping.toLevel(pValue)));
117-
caps.put(key, prefs);
118-
return;
119-
}
120-
121-
if ("platform".equals(key) && value instanceof String) {
122-
try {
123-
caps.put(key, Platform.fromString((String) value));
124-
} catch (WebDriverException e) {
125-
caps.put(key, value);
126-
}
127-
return;
128-
}
129-
130-
if ("unexpectedAlertBehaviour".equals(key)) {
131-
caps.put("unexpectedAlertBehaviour", value);
132-
caps.put("unhandledPromptBehavior", value);
133-
return;
134-
}
135-
136-
caps.put(key, value);
105+
SharedCapabilitiesMethods.setCapability(caps, key, value);
137106
}
138107

139108
@Override
@@ -183,49 +152,6 @@ public boolean equals(Object o) {
183152

184153
@Override
185154
public String toString() {
186-
Map<Object, String> seen = new IdentityHashMap<>();
187-
return "Capabilities " + abbreviate(seen, caps);
188-
}
189-
190-
private String abbreviate(Map<Object, String> seen, Object stringify) {
191-
if (stringify == null) {
192-
return "null";
193-
}
194-
195-
StringBuilder value = new StringBuilder();
196-
197-
if (stringify.getClass().isArray()) {
198-
value.append("[");
199-
value.append(
200-
Stream.of((Object[]) stringify)
201-
.map(item -> abbreviate(seen, item))
202-
.collect(Collectors.joining(", ")));
203-
value.append("]");
204-
} else if (stringify instanceof Collection) {
205-
value.append("[");
206-
value.append(
207-
((Collection<?>) stringify).stream()
208-
.map(item -> abbreviate(seen, item))
209-
.collect(Collectors.joining(", ")));
210-
value.append("]");
211-
} else if (stringify instanceof Map) {
212-
value.append("{");
213-
value.append(
214-
((Map<?, ?>) stringify).entrySet().stream()
215-
.sorted(Comparator.comparing(entry -> String.valueOf(entry.getKey())))
216-
.map(entry -> String.format("%s: %s", entry.getKey(), abbreviate(seen, entry.getValue())))
217-
.collect(Collectors.joining(", ")));
218-
value.append("}");
219-
} else {
220-
String s = String.valueOf(stringify);
221-
if (s.length() > 30) {
222-
value.append(s, 0, 27).append("...");
223-
} else {
224-
value.append(s);
225-
}
226-
}
227-
228-
seen.put(stringify, value.toString());
229-
return value.toString();
155+
return SharedCapabilitiesMethods.toString(caps);
230156
}
231157
}

0 commit comments

Comments
 (0)