Skip to content

Commit

Permalink
Merge pull request #186
Browse files Browse the repository at this point in the history
  • Loading branch information
sapessi committed Oct 19, 2018
2 parents 305372a + 9f13d3a commit 8c25373
Show file tree
Hide file tree
Showing 50 changed files with 259 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
package com.amazonaws.serverless.proxy.model;


import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;

import javax.ws.rs.core.MultivaluedMap;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;


/**
* Simple implementation of a multi valued tree map to use for case-insensitive headers
*
* @param <Key> The type for the map key
* @param <Value> The type for the map values
*/
public class MultiValuedTreeMap<Key, Value> implements MultivaluedMap<Key, Value>, Serializable, Cloneable {

private static final long serialVersionUID = 42L;

private final Map<Key, List<Value>> map;


public MultiValuedTreeMap() {
map = new TreeMap<>();
}

public MultiValuedTreeMap(Comparator<Key> comparator) {
map = new TreeMap<>(comparator);
}

public void add(Key key, Value value) {
List<Value> values = findKey(key);
values.add(value);
}

public Value getFirst(Key key) {
List<Value> values = get(key);
if (values == null || values.size() == 0) {
return null;
}
return values.get(0);
}

public void putSingle(Key key, Value value) {
List<Value> values = findKey(key);
values.clear();
values.add(value);
}

public void clear() {
map.clear();
}

public boolean containsKey(Object key) {
return map.containsKey(key);
}

public boolean containsValue(Object value) {
return map.containsValue(value);
}

public Set<Entry<Key, List<Value>>> entrySet() {
return map.entrySet();
}

public boolean equals(Object o) {
return map.equals(o);
}

public List<Value> get(Object key) {
return map.get(key);
}

public int hashCode() {
return map.hashCode();
}

public boolean isEmpty() {
return map.isEmpty();
}

public Set<Key> keySet() {
return map.keySet();
}

public List<Value> put(Key key, List<Value> value) {
return map.put(key, value);
}

public void putAll(Map<? extends Key, ? extends List<Value>> t) {
map.putAll(t);
}

public List<Value> remove(Object key) {
return map.remove(key);
}

public int size() {
return map.size();
}

public Collection<List<Value>> values() {
return map.values();
}

public void addAll(Key key, Value... newValues) {
for (Value value : newValues) {
add(key, value);
}
}

public void addAll(Key key, List<Value> valueList) {
for (Value value : valueList) {
add(key, value);
}
}

public void addFirst(Key key, Value value) {
List<Value> values = get(key);
if (values == null) {
add(key, value);
return;
} else {
values.add(0, value);
}
}

public boolean equalsIgnoreValueOrder(MultivaluedMap<Key, Value> vmap) {
if (this == vmap) {
return true;
}
if (!keySet().equals(vmap.keySet())) {
return false;
}
for (Map.Entry<Key, List<Value>> e : entrySet()) {
List<Value> olist = vmap.get(e.getKey());
if (e.getValue().size() != olist.size()) {
return false;
}
for (Value v : e.getValue()) {
if (!olist.contains(v)) {
return false;
}
}
}
return true;
}

private List<Value> findKey(Key key) {
List<Value> values = this.get(key);
if (values == null) {
values = new ArrayList<>();
put(key, values);
}
return values;
}

@SuppressFBWarnings("CN_IDIOM_NO_SUPER_CALL")
public MultiValuedTreeMap<Key, Value> clone() {
MultiValuedTreeMap<Key, Value> clone = new MultiValuedTreeMap<>();
for (Key key : keySet()) {
List<Value> value = get(key);
List<Value> newValue = new ArrayList<>();
newValue.addAll(value);
clone.put(key, newValue);
}
return clone;
}

public String toString() {
StringBuilder result = new StringBuilder();
String delim = ",";
for (Object name : keySet()) {
for (Object value : get(name)) {
result.append(delim);
if (name == null) {
result.append("null"); //$NON-NLS-1$
} else {
result.append(name.toString());
}
if (value != null) {
result.append('=');
result.append(value.toString());
}
}
}
return "[" + result.toString() + "]";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package com.amazonaws.serverless.proxy.model;


import org.junit.Test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;


public class MultiValuedTreeMapTest {

@Test
public void add_sameNameCaseSensitive_expectBothValues() {
MultiValuedTreeMap<String, String> map = new MultiValuedTreeMap<>();
map.add("Test", "test");
map.add("Test", "test2");

assertNotNull(map.get("Test"));
assertEquals(2, map.get("Test").size());
assertEquals("test", map.getFirst("Test"));
assertEquals("test2", map.get("Test").get(1));
assertNull(map.get("test"));

map.add("test", "test");
assertNotNull(map.get("test"));
assertEquals(1, map.get("test").size());
}

@Test
public void add_sameNameCaseInsensitive_expectOneValue() {
MultiValuedTreeMap<String, String> map = new MultiValuedTreeMap<>(String.CASE_INSENSITIVE_ORDER);
map.add("Test", "test");
assertNotNull(map.get("Test"));
assertNotNull(map.get("test"));
assertEquals(1, map.get("Test").size());

map.add("test", "test2");
assertNotNull(map.get("Test"));
assertEquals(2, map.get("Test").size());
}

@Test
public void addFirst_sameNameKey_ExpectFirstReplaced() {
MultiValuedTreeMap<String, String> map = new MultiValuedTreeMap<>();
map.add("Test", "test1");
map.add("Test", "test2");

assertNotNull(map.get("Test"));
assertEquals(2, map.get("Test").size());
assertEquals("test1", map.getFirst("Test"));

map.addFirst("Test", "test3");
assertEquals(3, map.get("Test").size());
assertEquals("test3", map.getFirst("Test"));
}
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
11 changes: 5 additions & 6 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,11 @@
<module>aws-serverless-java-container-jersey</module>
<module>aws-serverless-java-container-spark</module>
<module>aws-serverless-java-container-spring</module>
<module>aws-serverless-java-container-struts2</module>
<module>archetypes/jersey</module>
<module>archetypes/spark</module>
<module>archetypes/spring</module>
<module>archetypes/springboot</module>
<module>archetypes/struts</module>
<module>aws-serverless-struts-archetype</module>
<module>aws-serverless-jersey-archetype</module>
<module>aws-serverless-spark-archetype</module>
<module>aws-serverless-spring-archetype</module>
<module>aws-serverless-springboot-archetype</module>
</modules>

<scm>
Expand Down

0 comments on commit 8c25373

Please sign in to comment.