Use composite collections in attribute merging
This commit introduces composite collections (i.e. Collection, Set, Map) and uses these composites in request predicates, where before new collections were instantiated. Closes gh-32245
This commit is contained in:
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
class CompositeCollectionTests {
|
||||
|
||||
@Test
|
||||
void size() {
|
||||
List<String> first = List.of("foo", "bar", "baz");
|
||||
List<String> second = List.of("qux", "quux");
|
||||
CompositeCollection<String> composite = new CompositeCollection<>(first, second);
|
||||
|
||||
assertThat(composite).hasSize(5);
|
||||
}
|
||||
|
||||
@Test
|
||||
void isEmpty() {
|
||||
List<String> first = List.of("foo", "bar", "baz");
|
||||
List<String> second = List.of("qux", "quux");
|
||||
CompositeCollection<String> composite = new CompositeCollection<>(first, second);
|
||||
|
||||
assertThat(composite).isNotEmpty();
|
||||
|
||||
composite = new CompositeCollection<>(Collections.emptyList(), Collections.emptyList());
|
||||
assertThat(composite).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void contains() {
|
||||
List<String> first = List.of("foo", "bar");
|
||||
List<String> second = List.of("baz", "qux");
|
||||
CompositeCollection<String> composite = new CompositeCollection<>(first, second);
|
||||
|
||||
assertThat(composite.contains("foo")).isTrue();
|
||||
assertThat(composite.contains("bar")).isTrue();
|
||||
assertThat(composite.contains("baz")).isTrue();
|
||||
assertThat(composite.contains("qux")).isTrue();
|
||||
assertThat(composite.contains("quux")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void iterator() {
|
||||
List<String> first = List.of("foo", "bar");
|
||||
List<String> second = List.of("baz", "qux");
|
||||
CompositeCollection<String> composite = new CompositeCollection<>(first, second);
|
||||
|
||||
Iterator<String> iterator = composite.iterator();
|
||||
assertThat(iterator).hasNext();
|
||||
assertThat(iterator.next()).isEqualTo("foo");
|
||||
assertThat(iterator).hasNext();
|
||||
assertThat(iterator.next()).isEqualTo("bar");
|
||||
assertThat(iterator).hasNext();
|
||||
assertThat(iterator.next()).isEqualTo("baz");
|
||||
assertThat(iterator).hasNext();
|
||||
assertThat(iterator.next()).isEqualTo("qux");
|
||||
assertThat(iterator).isExhausted();
|
||||
}
|
||||
|
||||
@Test
|
||||
void toArray() {
|
||||
List<String> first = List.of("foo", "bar");
|
||||
List<String> second = List.of("baz", "qux");
|
||||
CompositeCollection<String> composite = new CompositeCollection<>(first, second);
|
||||
|
||||
Object[] array = composite.toArray();
|
||||
assertThat(array).containsExactly("foo", "bar", "baz", "qux");
|
||||
}
|
||||
|
||||
@Test
|
||||
void toArrayArgs() {
|
||||
List<String> first = List.of("foo", "bar");
|
||||
List<String> second = List.of("baz", "qux");
|
||||
CompositeCollection<String> composite = new CompositeCollection<>(first, second);
|
||||
|
||||
String[] array = new String[composite.size()];
|
||||
array = composite.toArray(array);
|
||||
assertThat(array).containsExactly("foo", "bar", "baz", "qux");
|
||||
}
|
||||
|
||||
@Test
|
||||
void add() {
|
||||
List<String> first = List.of("foo", "bar");
|
||||
List<String> second = List.of("baz", "qux");
|
||||
CompositeCollection<String> composite = new CompositeCollection<>(first, second);
|
||||
|
||||
assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(() -> composite.add("quux"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void remove() {
|
||||
List<String> first = new ArrayList<>(List.of("foo", "bar"));
|
||||
List<String> second = new ArrayList<>(List.of("baz", "qux"));
|
||||
CompositeCollection<String> composite = new CompositeCollection<>(first, second);
|
||||
|
||||
assertThat(composite.remove("foo")).isTrue();
|
||||
assertThat(composite.contains("foo")).isFalse();
|
||||
assertThat(first).containsExactly("bar");
|
||||
|
||||
assertThat(composite.remove("quux")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void containsAll() {
|
||||
List<String> first = List.of("foo", "bar");
|
||||
List<String> second = List.of("baz", "qux");
|
||||
CompositeCollection<String> composite = new CompositeCollection<>(first, second);
|
||||
|
||||
List<String> all = new ArrayList<>(first);
|
||||
all.addAll(second);
|
||||
|
||||
assertThat(composite.containsAll(all)).isTrue();
|
||||
|
||||
all.add("quux");
|
||||
|
||||
assertThat(composite.containsAll(all)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void addAll() {
|
||||
List<String> first = List.of("foo", "bar");
|
||||
List<String> second = List.of("baz", "qux");
|
||||
CompositeCollection<String> composite = new CompositeCollection<>(first, second);
|
||||
|
||||
assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(() -> composite.addAll(List.of("quux", "corge")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void removeAll() {
|
||||
List<String> first = new ArrayList<>(List.of("foo", "bar"));
|
||||
List<String> second = new ArrayList<>(List.of("baz", "qux"));
|
||||
CompositeCollection<String> composite = new CompositeCollection<>(first, second);
|
||||
|
||||
List<String> all = new ArrayList<>(first);
|
||||
all.addAll(second);
|
||||
|
||||
assertThat(composite.removeAll(all)).isTrue();
|
||||
|
||||
assertThat(composite).isEmpty();
|
||||
assertThat(first).isEmpty();
|
||||
assertThat(second).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void retainAll() {
|
||||
List<String> first = new ArrayList<>(List.of("foo", "bar"));
|
||||
List<String> second = new ArrayList<>(List.of("baz", "qux"));
|
||||
CompositeCollection<String> composite = new CompositeCollection<>(first, second);
|
||||
|
||||
assertThat(composite.retainAll(List.of("bar", "baz"))).isTrue();
|
||||
|
||||
assertThat(composite).containsExactly("bar", "baz");
|
||||
assertThat(first).containsExactly("bar");
|
||||
assertThat(second).containsExactly("baz");
|
||||
}
|
||||
|
||||
@Test
|
||||
void clear() {
|
||||
List<String> first = new ArrayList<>(List.of("foo", "bar"));
|
||||
List<String> second = new ArrayList<>(List.of("baz", "qux"));
|
||||
CompositeCollection<String> composite = new CompositeCollection<>(first, second);
|
||||
|
||||
composite.clear();
|
||||
|
||||
assertThat(composite).isEmpty();
|
||||
assertThat(first).isEmpty();
|
||||
assertThat(second).isEmpty();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,221 @@
|
||||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.util;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.assertj.core.api.Assertions.entry;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
class CompositeMapTests {
|
||||
|
||||
@Test
|
||||
void size() {
|
||||
Map<String, String> first = Map.of("foo", "bar", "baz", "qux");
|
||||
Map<String, String> second = Map.of("quux", "corge");
|
||||
CompositeMap<String, String> composite = new CompositeMap<>(first, second);
|
||||
|
||||
assertThat(composite).hasSize(3);
|
||||
}
|
||||
|
||||
@Test
|
||||
void isEmpty() {
|
||||
Map<String, String> first = Map.of("foo", "bar", "baz", "qux");
|
||||
Map<String, String> second = Map.of("quux", "corge");
|
||||
CompositeMap<String, String> composite = new CompositeMap<>(first, second);
|
||||
|
||||
assertThat(composite).isNotEmpty();
|
||||
|
||||
composite = new CompositeMap<>(Collections.emptyMap(), Collections.emptyMap());
|
||||
assertThat(composite).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void containsKey() {
|
||||
Map<String, String> first = Map.of("foo", "bar", "baz", "qux");
|
||||
Map<String, String> second = Map.of("quux", "corge");
|
||||
CompositeMap<String, String> composite = new CompositeMap<>(first, second);
|
||||
|
||||
assertThat(composite.containsKey("foo")).isTrue();
|
||||
assertThat(composite.containsKey("bar")).isFalse();
|
||||
assertThat(composite.containsKey("baz")).isTrue();
|
||||
assertThat(composite.containsKey("qux")).isFalse();
|
||||
assertThat(composite.containsKey("quux")).isTrue();
|
||||
assertThat(composite.containsKey("corge")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void containsValue() {
|
||||
Map<String, String> first = Map.of("foo", "bar", "baz", "qux");
|
||||
Map<String, String> second = Map.of("quux", "corge");
|
||||
CompositeMap<String, String> composite = new CompositeMap<>(first, second);
|
||||
|
||||
assertThat(composite.containsValue("foo")).isFalse();
|
||||
assertThat(composite.containsValue("bar")).isTrue();
|
||||
assertThat(composite.containsValue("baz")).isFalse();
|
||||
assertThat(composite.containsValue("qux")).isTrue();
|
||||
assertThat(composite.containsValue("quux")).isFalse();
|
||||
assertThat(composite.containsValue("corge")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void get() {
|
||||
Map<String, String> first = Map.of("foo", "bar", "baz", "qux");
|
||||
Map<String, String> second = Map.of("quux", "corge");
|
||||
CompositeMap<String, String> composite = new CompositeMap<>(first, second);
|
||||
|
||||
assertThat(composite.get("foo")).isEqualTo("bar");
|
||||
assertThat(composite.get("baz")).isEqualTo("qux");
|
||||
assertThat(composite.get("quux")).isEqualTo("corge");
|
||||
|
||||
assertThat(composite.get("grault")).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void putUnsupported() {
|
||||
Map<String, String> first = Map.of("foo", "bar");
|
||||
Map<String, String> second = Map.of("baz", "qux");
|
||||
CompositeMap<String, String> composite = new CompositeMap<>(first, second);
|
||||
|
||||
assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(() -> composite.put("grault", "garply"));
|
||||
}
|
||||
@Test
|
||||
void putSupported() {
|
||||
Map<String, String> first = Map.of("foo", "bar");
|
||||
Map<String, String> second = Map.of("baz", "qux");
|
||||
CompositeMap<String, String> composite = new CompositeMap<>(first, second, (k,v) -> {
|
||||
assertThat(k).isEqualTo("quux");
|
||||
assertThat(v).isEqualTo("corge");
|
||||
return "grault";
|
||||
}, null);
|
||||
|
||||
assertThat(composite.put("quux", "corge")).isEqualTo("grault");
|
||||
}
|
||||
|
||||
@Test
|
||||
void remove() {
|
||||
Map<String, String> first = new HashMap<>(Map.of("foo", "bar", "baz", "qux"));
|
||||
Map<String, String> second = new HashMap<>(Map.of("quux", "corge"));
|
||||
CompositeMap<String, String> composite = new CompositeMap<>(first, second);
|
||||
|
||||
assertThat(composite.remove("foo")).isEqualTo("bar");
|
||||
assertThat(composite.containsKey("foo")).isFalse();
|
||||
assertThat(first).containsExactly(entry("baz", "qux"));
|
||||
|
||||
assertThat(composite.remove("grault")).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void putAllUnsupported() {
|
||||
Map<String, String> first = Map.of("foo", "bar");
|
||||
Map<String, String> second = Map.of("baz", "qux");
|
||||
|
||||
CompositeMap<String, String> composite = new CompositeMap<>(first, second);
|
||||
|
||||
assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(() -> composite.putAll(Map.of("quux", "corge", "grault", "garply")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void putAllPutFunction() {
|
||||
Map<String, String> first = Map.of("foo", "bar");
|
||||
Map<String, String> second = Map.of("baz", "qux");
|
||||
|
||||
AtomicBoolean functionInvoked = new AtomicBoolean();
|
||||
CompositeMap<String, String> composite = new CompositeMap<>(first, second, (k,v) -> {
|
||||
assertThat(k).isEqualTo("quux");
|
||||
assertThat(v).isEqualTo("corge");
|
||||
functionInvoked.set(true);
|
||||
return "grault";
|
||||
}, null);
|
||||
|
||||
composite.putAll(Map.of("quux", "corge"));
|
||||
|
||||
assertThat(functionInvoked).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void putAllPutAllFunction() {
|
||||
Map<String, String> first = Map.of("foo", "bar");
|
||||
Map<String, String> second = Map.of("baz", "qux");
|
||||
|
||||
AtomicBoolean functionInvoked = new AtomicBoolean();
|
||||
Map<String, String> argument = Map.of("quux", "corge");
|
||||
CompositeMap<String, String> composite = new CompositeMap<>(first, second, null,
|
||||
m -> {
|
||||
assertThat(m).isSameAs(argument);
|
||||
functionInvoked.set(true);
|
||||
});
|
||||
|
||||
composite.putAll(argument);
|
||||
|
||||
assertThat(functionInvoked).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void clear() {
|
||||
Map<String, String> first = new HashMap<>(Map.of("foo", "bar", "baz", "qux"));
|
||||
Map<String, String> second = new HashMap<>(Map.of("quux", "corge"));
|
||||
CompositeMap<String, String> composite = new CompositeMap<>(first, second);
|
||||
|
||||
composite.clear();
|
||||
|
||||
assertThat(composite).isEmpty();
|
||||
assertThat(first).isEmpty();
|
||||
assertThat(second).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void keySet() {
|
||||
Map<String, String> first = Map.of("foo", "bar");
|
||||
Map<String, String> second = Map.of("baz", "qux");
|
||||
CompositeMap<String, String> composite = new CompositeMap<>(first, second);
|
||||
|
||||
Set<String> keySet = composite.keySet();
|
||||
assertThat(keySet).containsExactly("foo", "baz");
|
||||
}
|
||||
|
||||
@Test
|
||||
void values() {
|
||||
Map<String, String> first = Map.of("foo", "bar");
|
||||
Map<String, String> second = Map.of("baz", "qux");
|
||||
CompositeMap<String, String> composite = new CompositeMap<>(first, second);
|
||||
|
||||
Collection<String> values = composite.values();
|
||||
assertThat(values).containsExactly("bar", "qux");
|
||||
}
|
||||
|
||||
@Test
|
||||
void entrySet() {
|
||||
Map<String, String> first = Map.of("foo", "bar");
|
||||
Map<String, String> second = Map.of("baz", "qux");
|
||||
CompositeMap<String, String> composite = new CompositeMap<>(first, second);
|
||||
|
||||
Set<Map.Entry<String, String>> entries = composite.entrySet();
|
||||
assertThat(entries).containsExactly(entry("foo", "bar"), entry("baz", "qux"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.util;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
class CompositeSetTests {
|
||||
|
||||
@Test
|
||||
void testEquals() {
|
||||
Set<String> first = Set.of("foo", "bar");
|
||||
Set<String> second = Set.of("baz", "qux");
|
||||
CompositeSet<String> composite = new CompositeSet<>(first, second);
|
||||
|
||||
Set<String> all = new HashSet<>(first);
|
||||
all.addAll(second);
|
||||
|
||||
assertThat(composite.equals(all)).isTrue();
|
||||
assertThat(composite.equals(first)).isFalse();
|
||||
assertThat(composite.equals(second)).isFalse();
|
||||
assertThat(composite.equals(Collections.emptySet())).isFalse();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user