Skip to content

Commit

Permalink
Remove commons-collections and add Multimaps (#795)
Browse files Browse the repository at this point in the history
  • Loading branch information
yahavi committed Jun 17, 2024
1 parent 6dfb4e9 commit 90ef814
Show file tree
Hide file tree
Showing 31 changed files with 608 additions and 125 deletions.
2 changes: 0 additions & 2 deletions .github/workflows/integrationTests.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
name: Integration Tests
on:
push:
branches:
- master
# Triggers the workflow on labeled PRs only.
pull_request_target:
types: [ labeled ]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;

/**
* @author Noam Y. Tenne
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package org.jfrog.build.api.multiMap;

import java.util.Collection;
import java.util.LinkedList;
import java.util.Map;

/**
* A multimap that uses a {@link LinkedList} to store the values.
*/
public class ListMultimap<Key, Value> extends Multimap<Key, Value> {

/**
* Default constructor.
*/
public ListMultimap() {
super();
}

/**
* Constructor that accepts a map.
*
* @param map the map
*/
public ListMultimap(Map<Key, Value> map) {
super(map);
}

/**
* Put a key-value pair into the multimap.
*
* @param key the key
* @param value the value
*/
public void put(Key key, Value value) {
Collection<Value> currentValue = multiMap.getOrDefault(key, new LinkedList<>());
currentValue.add(value);
multiMap.put(key, currentValue);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
package org.jfrog.build.api.multiMap;

import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;

import java.io.Serializable;
import java.util.*;

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
@JsonSubTypes({
@JsonSubTypes.Type(value = ListMultimap.class, name = "list"),
@JsonSubTypes.Type(value = SetMultimap.class, name = "set"),
})
public abstract class Multimap<Key, Value> implements Serializable {
private static final long serialVersionUID = 1L;
Map<Key, Collection<Value>> multiMap = new HashMap<>();

/**
* Default constructor.
*/
Multimap() {
}

/**
* Constructor that accepts a map.
*
* @param map the map
*/
Multimap(Map<Key, Value> map) {
map.forEach(this::put);
}

/**
* Put a key-value pair into the multimap.
*
* @param key the key
* @param value the value
*/
public abstract void put(Key key, Value value);

/**
* Get all values for a key.
*
* @param key the key
* @return a collection of values for the key
*/
public Collection<Value> get(Key key) {
return multiMap.get(key);
}

/**
* Put all key-value pairs from a map into the multimap.
*
* @param map the map
*/
public void putAll(Map<Key, Value> map) {
for (Map.Entry<Key, Value> entry : map.entrySet()) {
put(entry.getKey(), entry.getValue());
}
}

/**
* Put all key-value pairs from a multimap into the multimap.
*
* @param multimap the multimap
*/
public void putAll(Multimap<Key, Value> multimap) {
for (Map.Entry<Key, Collection<Value>> entry : multimap.multiMap.entrySet()) {
for (Value value : entry.getValue()) {
put(entry.getKey(), value);
}
}
}

/**
* Put all values for a key into the multimap.
*
* @param key the key
* @param values the values
*/
public void putAll(Key key, Collection<Value> values) {
for (Value value : values) {
put(key, value);
}
}

/**
* Get all key-value pairs in the multimap.
*
* @return a set of key-value pairs
*/
public Set<Map.Entry<Key, Value>> entries() {
Set<Map.Entry<Key, Value>> entries = new HashSet<>();
for (Map.Entry<Key, Collection<Value>> entry : multiMap.entrySet()) {
for (Value value : entry.getValue()) {
entries.add(new AbstractMap.SimpleEntry<>(entry.getKey(), value));
}
}
return entries;
}

/**
* Get the underlying map.
*
* @return the map
*/
public Map<Key, Collection<Value>> asMap() {
return multiMap;
}

/**
* Get all keys in the multimap.
*
* @return a set of keys
*/
public Set<Key> keySet() {
return multiMap.keySet();
}

/**
* Check if the multimap contains a value.
*
* @param value the value
* @return true if the multimap contains the value
*/
public boolean containsValue(Value value) {
for (Collection<Value> values : multiMap.values()) {
if (values.contains(value)) {
return true;
}
}
return false;
}

/**
* Get the number of key-value pairs in the multimap.
*
* @return the number of key-value pairs
*/
public int size() {
int size = 0;
for (Collection<Value> values : multiMap.values()) {
size += values.size();
}
return size;
}

/**
* Check if the multimap is empty.
*
* @return true if the multimap is empty
*/
public boolean isEmpty() {
return multiMap.isEmpty();
}

/**
* Clear the multimap.
*/
public void clear() {
multiMap.clear();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package org.jfrog.build.api.multiMap;

import java.util.Collection;
import java.util.HashSet;
import java.util.Map;

/**
* A multimap that uses a {@link HashSet} to store the values.
*/
public class SetMultimap<Key, Value> extends Multimap<Key, Value> {
public SetMultimap() {
super();
}

/**
* Constructor that accepts a map.
*
* @param map the map
*/
public SetMultimap(Map<Key, Value> map) {
super(map);
}

/**
* Put a key-value pair into the multimap.
*
* @param key the key
* @param value the value
*/
public void put(Key key, Value value) {
Collection<Value> currentValue = multiMap.getOrDefault(key, new HashSet<>());
currentValue.add(value);
multiMap.put(key, currentValue);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package org.jfrog.build.api.multiMap;

import org.testng.annotations.Test;

import java.util.HashMap;
import java.util.Map;

import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;

@Test
public class ListMultimapTest {

public void testDefaultConstructor() {
// Create a new multimap
Multimap<String, String> multimap = new ListMultimap<>();

// Assert that the multimap is empty
assertEquals(multimap.size(), 0);
}

public void testConstructorWithMap() {
// Create a new map
Map<String, String> map = new HashMap<>();
map.put("key", "value");

// Create a new multimap with the map
Multimap<String, String> multimap = new ListMultimap<>(map);

// Assert that the multimap contains the value
assertTrue(multimap.containsValue("value"));
}

public void testPutDuplicated() {
// Populate multimap with duplicated values
Multimap<String, String> multimap = new ListMultimap<>();
multimap.put("key", "value");
multimap.put("key", "value");

// Convert the collection to an array
String[] values = multimap.get("key").toArray(new String[0]);

// Assert that the values were added
assertEquals(values.length, 2);
assertEquals(values[0], "value");
assertEquals(values[1], "value");
}
}
Loading

0 comments on commit 90ef814

Please sign in to comment.