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:
Arjen Poutsma
2024-02-14 09:55:52 +01:00
parent 89d746ddf8
commit aee03c5201
9 changed files with 953 additions and 53 deletions

View File

@@ -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();
}
}

View File

@@ -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"));
}
}

View File

@@ -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();
}
}