Path: blob/trunk/java/src/org/openqa/selenium/MutableCapabilities.java
1865 views
// Licensed to the Software Freedom Conservancy (SFC) under one1// or more contributor license agreements. See the NOTICE file2// distributed with this work for additional information3// regarding copyright ownership. The SFC licenses this file4// to you under the Apache License, Version 2.0 (the5// "License"); you may not use this file except in compliance6// with the License. You may obtain a copy of the License at7//8// http://www.apache.org/licenses/LICENSE-2.09//10// Unless required by applicable law or agreed to in writing,11// software distributed under the License is distributed on an12// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY13// KIND, either express or implied. See the License for the14// specific language governing permissions and limitations15// under the License.1617package org.openqa.selenium;1819import java.util.Collections;20import java.util.HashSet;21import java.util.Map;22import java.util.Set;23import java.util.TreeMap;24import org.jspecify.annotations.NullMarked;25import org.jspecify.annotations.Nullable;26import org.openqa.selenium.internal.Require;2728@NullMarked29public class MutableCapabilities implements Capabilities {3031private static final Set<String> OPTION_KEYS;3233static {34HashSet<String> keys = new HashSet<>();35keys.add("goog:chromeOptions");36keys.add("ms:edgeOptions");37keys.add("moz:firefoxOptions");38keys.add("se:ieOptions");39OPTION_KEYS = Collections.unmodifiableSet(keys);40}4142private final Map<String, Object> caps = new TreeMap<>();4344public MutableCapabilities() {45// no-arg constructor46}4748public MutableCapabilities(Capabilities other) {49this(other.asMap());50}5152public MutableCapabilities(Map<String, ?> capabilities) {53capabilities.forEach(54(key, value) -> {55if (value != null) {56setCapability(key, value);57}58});59}6061/**62* Merge two {@link Capabilities} together and return the union of the two as a new {@link63* Capabilities} instance. Capabilities from {@code other} will override those in {@code this}.64*/65@Override66public MutableCapabilities merge(Capabilities other) {67MutableCapabilities newInstance = new MutableCapabilities(this);68if (other != null) {69other.asMap().forEach(newInstance::setCapability);70}71return newInstance;72}7374public void setCapability(String capabilityName, boolean value) {75setCapability(capabilityName, (Object) value);76}7778public void setCapability(String capabilityName, String value) {79setCapability(capabilityName, (Object) value);80}8182public void setCapability(String capabilityName, Platform value) {83setCapability(capabilityName, (Object) value);84}8586public void setCapability(String key, @Nullable Object value) {87Require.nonNull("Capability name", key);8889// We have to special-case some keys and values because of the popular idiom of calling90// something like "capabilities.setCapability(SafariOptions.CAPABILITY, new SafariOptions());"91// and this is no longer needed as options are capabilities. There will be a large amount of92// legacy code that will always try and follow this pattern, however.93if (OPTION_KEYS.contains(key) && value instanceof Capabilities) {94((Capabilities) value).asMap().forEach(this::setCapability);95return;96}9798if (value == null) {99caps.remove(key);100return;101}102103SharedCapabilitiesMethods.setCapability(caps, key, value);104}105106@Override107public Map<String, Object> asMap() {108return Collections.unmodifiableMap(caps);109}110111@Override112public @Nullable Object getCapability(String capabilityName) {113return caps.get(capabilityName);114}115116@Override117public Set<String> getCapabilityNames() {118return Collections.unmodifiableSet(caps.keySet());119}120121public Map<String, Object> toJson() {122return asMap();123}124125@Override126public int hashCode() {127return SharedCapabilitiesMethods.hashCode(this);128}129130@Override131public boolean equals(@Nullable Object o) {132if (!(o instanceof Capabilities)) {133return false;134}135return SharedCapabilitiesMethods.equals(this, (Capabilities) o);136}137138@Override139public String toString() {140return SharedCapabilitiesMethods.toString(this);141}142}143144145