Skip to content

Commit

Permalink
add override functions for accepting suppliers.
Browse files Browse the repository at this point in the history
it be needed as something like: query several mongo collections one by one, etc.
  • Loading branch information
XenoAmess committed Jan 11, 2025
1 parent 3851d44 commit 0dbf285
Show file tree
Hide file tree
Showing 2 changed files with 156 additions and 1 deletion.
49 changes: 48 additions & 1 deletion src/main/java/org/apache/commons/collections4/IterableUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.function.Supplier;

import org.apache.commons.collections4.functors.EqualPredicate;
import org.apache.commons.collections4.iterators.LazyIteratorChain;
Expand Down Expand Up @@ -140,6 +141,39 @@ protected Iterator<? extends E> nextIterator(final int count) {
};
}

/**
* Combines the provided iterables into a single iterable.
* <p>
* The returned iterable has an iterator that traverses the elements in the order
* of the arguments, i.e. iterables[0], iterables[1], .... The source iterators
* are not polled until necessary.
* <p>
* The returned iterable's iterator supports {@code remove()} when the corresponding
* input iterator supports it.
*
* @param <E> the element type
* @param iterableSuppliers the iterables to combine, may not be null
* @return a new iterable, combining the provided iterables
* @throws NullPointerException if either of the provided iterables is null
*/
public static <E> Iterable<E> chainedIterable(final Supplier<Iterable<? extends E>>... iterableSuppliers) {
checkNotNull(iterableSuppliers);
return new FluentIterable<E>() {
@Override
public Iterator<E> iterator() {
return new LazyIteratorChain<E>() {
@Override
protected Iterator<? extends E> nextIterator(final int count) {
if (count > iterableSuppliers.length) {
return null;
}
return iterableSuppliers[count - 1].get().iterator();
}
};
}
};
}

/**
* Combines two iterables into a single iterable.
* <p>
Expand Down Expand Up @@ -231,6 +265,19 @@ static void checkNotNull(final Iterable<?>... iterables) {
}
}

/**
* Fail-fast check for null arguments.
*
* @param suppliers the suppliers to check
* @throws NullPointerException if the argument or any of its contents is null
*/
static void checkNotNull(final Supplier<?>... suppliers) {
Objects.requireNonNull(suppliers, "suppliers");
for (final Supplier<?> supplier : suppliers) {
Objects.requireNonNull(supplier, "supplier");
}
}

/**
* Combines the two provided iterables into an ordered iterable using the
* provided comparator. If the comparator is null, natural ordering will be
Expand Down Expand Up @@ -384,7 +431,7 @@ public static <E> Set<E> duplicateSet(final Iterable<E> iterable) {
}

/**
* Worker method for {@link #duplicateSet(Collection)} and friends.
* Worker method for {@link #duplicateSet(Iterable)} and friends.
*
* @param <C> the type of Collection.
* @param <E> the type of elements in the Collection.
Expand Down
108 changes: 108 additions & 0 deletions src/test/java/org/apache/commons/collections4/IterableUtilsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,21 @@
import java.util.Collections;
import java.util.Deque;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;

import org.apache.commons.collections4.bag.HashBag;
import org.apache.commons.collections4.functors.EqualPredicate;
import org.apache.commons.lang3.StringUtils;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

Expand Down Expand Up @@ -653,4 +660,105 @@ public void testToStringWithNullArguments() {
}, StringUtils.EMPTY, "(", null), "expecting NullPointerException"));
}

static final class MockMongoAlertQueryService {

public Iterable<Map<String, Object>> query(String table) {
switch (table) {
case "alerts_tenant_1": {
LinkedHashMap<String, Object> map1 = new LinkedHashMap<>();
map1.put("uuId", "alert-23132158");
map1.put("property1", "xxxxxx");
map1.put("property2", "xxxxxx");
map1.put("property3", "xxxxxx");
LinkedHashMap<String, Object> map2 = new LinkedHashMap<>();
map2.put("uuId", "alert-23132159");
map2.put("property1", "xxxxxx");
map2.put("property2", "xxxxxx");
map2.put("property3", "xxxxxx");
return Arrays.asList(
map1,
map2
);
}
case "alerts_tenant_2": {
return new HashSet<>();
}
case "alerts_tenant_3": {
LinkedHashMap<String, Object> map1 = new LinkedHashMap<>();
map1.put("uuId", "alert-23154789");
map1.put("property1", "xxxxxx");
map1.put("property2", "xxxxxx");
map1.put("property3", "xxxxxx");
LinkedHashMap<String, Object> map2 = new LinkedHashMap<>();
map2.put("uuId", "alert-32651147");
map2.put("property1", "xxxxxx");
map2.put("property2", "xxxxxx");
map2.put("property3", "xxxxxx");
LinkedHashMap<String, Object> map3 = new LinkedHashMap<>();
map3.put("uuId", "alert-34321523");
map3.put("property1", "xxxxxx");
map3.put("property2", "xxxxxx");
map3.put("property3", "xxxxxx");
return Arrays.asList(
map1,
map2,
map3
);
}
default:
return new ArrayList<>();
}

}

}

@Test
public void testChainedIterable() {
MockMongoAlertQueryService mockMongoAlertQueryService = new MockMongoAlertQueryService();
List<Supplier<Iterable<Map<String, Object>>>> suppliers =
Arrays.asList(
"alerts_tenant_1",
"alerts_tenant_2",
"alerts_tenant_3",
"alerts_tenant_4",
"alerts_tenant_5"
).stream().map(
new Function<String, Supplier<Iterable<Map<String, Object>>>>() {
@Override
public Supplier<Iterable<Map<String, Object>>> apply(String tableName) {
return () -> mockMongoAlertQueryService.query(
tableName
);
}
}
).collect(
Collectors.toList()
);
Iterable<Map<String, Object>> totalAlertsIterable
= IterableUtils.chainedIterable(
suppliers.toArray(new Supplier[0])
);
ArrayList<Object> resultUuids = new ArrayList<>(0);
totalAlertsIterable.forEach(
new Consumer<Map<String, Object>>() {
@Override
public void accept(Map<String, Object> stringObjectMap) {
resultUuids.add(stringObjectMap.get("uuId"));
}
}
);
Assertions.assertArrayEquals(
new Object[]{
"alert-23132158",
"alert-23132159",
"alert-23154789",
"alert-32651147",
"alert-34321523"
},
resultUuids.toArray(new Object[0])
);

}

}

0 comments on commit 0dbf285

Please sign in to comment.