Skip to content

Commit

Permalink
#1001 Add stream utilities for working with Map.Entry
Browse files Browse the repository at this point in the history
  • Loading branch information
GuusLieben committed Jul 31, 2024
1 parent 4398aed commit 343dabf
Show file tree
Hide file tree
Showing 17 changed files with 609 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

import org.dockbox.hartshorn.inject.annotations.Named;
import org.dockbox.hartshorn.util.TypeUtils;
import org.dockbox.hartshorn.util.stream.EntryStream;
import org.dockbox.hartshorn.util.stream.CollectorUtilities;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
Expand Down Expand Up @@ -139,8 +141,13 @@ public int hashCode() {

@Override
public String toString() {
String metaString = this.meta.entrySet().stream()
.map(entry -> "%s=%s".formatted(entry.getKey(), entry.getValue()))
EntryStream.of(this.meta)
.mapKeys(String::toUpperCase)
.mapValues(String::valueOf)
.collect(CollectorUtilities.toMultiMap());

String metaString = EntryStream.of(this.meta)
.map((key, value) -> "%s=%s".formatted(key, value))
.collect(Collectors.joining(", "));
return "%s{%s}".formatted(this.type.getSimpleName(), metaString);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
Expand All @@ -33,6 +34,7 @@
import org.dockbox.hartshorn.inject.provider.InstantiationStrategy;
import org.dockbox.hartshorn.inject.provider.TypeAwareInstantiationStrategy;
import org.dockbox.hartshorn.util.option.Option;
import org.dockbox.hartshorn.util.stream.EntryStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -157,18 +159,15 @@ public String toString() {
qualifiers = " " + qualifier;
}

// The priorities are stored high to low, however we want to display them as low-to-high.
List<Entry<Integer, InstantiationStrategy<T>>> entries = new ArrayList<>(this.priorityProviders().entrySet());
Collections.reverse(entries);

String hierarchy = entries.stream()
.map(entry -> {
InstantiationStrategy<T> value = entry.getValue();
String target = value.toString();
if (value instanceof TypeAwareInstantiationStrategy<?> typeAwareProvider) {
// TODO: Verify order is still correct after changes (display low-to-high)
String hierarchy = EntryStream.of(this.priorityProviders())
.sortedKeys(Comparator.reverseOrder())
.map((priority, strategy) -> {
String target = strategy.toString();
if (strategy instanceof TypeAwareInstantiationStrategy<?> typeAwareProvider) {
target = typeAwareProvider.type().getSimpleName();
}
return "%s: %s".formatted(String.valueOf(entry.getKey()), target);
return "%s: %s".formatted(String.valueOf(priority), target);
})
.collect(Collectors.joining(" -> "));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,6 @@
import org.dockbox.hartshorn.launchpad.lifecycle.ObservableApplicationEnvironment;
import org.dockbox.hartshorn.launchpad.lifecycle.Observer;
import org.dockbox.hartshorn.launchpad.properties.InstantLoadingPropertyRegistryFactory;
import org.dockbox.hartshorn.launchpad.properties.PredefinedPropertySourceResolver;
import org.dockbox.hartshorn.launchpad.properties.PropertyRegistryFactory;
import org.dockbox.hartshorn.launchpad.properties.PropertySourceResolver;
import org.dockbox.hartshorn.launchpad.properties.TypeDiscoveryPropertySourceResolver;
import org.dockbox.hartshorn.launchpad.resources.FallbackResourceLookup;
import org.dockbox.hartshorn.launchpad.resources.ResourceLookup;
Expand All @@ -57,6 +54,7 @@
import org.dockbox.hartshorn.properties.loader.PredicatePropertyRegistryLoader;
import org.dockbox.hartshorn.properties.loader.PropertyRegistryLoader;
import org.dockbox.hartshorn.properties.loader.support.CompositePredicatePropertyRegistryLoader;

import org.dockbox.hartshorn.proxy.ProxyOrchestrator;
import org.dockbox.hartshorn.spi.DiscoveryService;
import org.dockbox.hartshorn.spi.ServiceDiscoveryException;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.util.concurrent.ConcurrentHashMap;

import org.dockbox.hartshorn.util.option.Option;
import org.dockbox.hartshorn.util.stream.EntryStream;

public class ConcurrentProfileRegistry implements ProfileRegistry {

Expand Down Expand Up @@ -35,9 +36,9 @@ public void unregister(EnvironmentProfile profile) {

@Override
public List<EnvironmentProfile> profiles() {
return this.prioritizedProfiles.entrySet().stream()
.sorted(Map.Entry.comparingByKey())
.map(Map.Entry::getValue)
return EntryStream.of(this.prioritizedProfiles)
.sortedKeys()
.values()
.toList();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@

import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.BiConsumer;
import java.util.stream.Collectors;
Expand All @@ -37,6 +35,7 @@
import org.dockbox.hartshorn.reporting.ConfigurableDiagnosticsReporter;
import org.dockbox.hartshorn.reporting.DiagnosticsPropertyCollector;
import org.dockbox.hartshorn.reporting.Reportable;
import org.dockbox.hartshorn.util.CollectionUtilities;

/**
* A diagnostics reporter that reports information about the application. This includes the following information:
Expand Down Expand Up @@ -144,9 +143,9 @@ protected void reportObservers(DiagnosticsPropertyCollector collector) {
.collect(Collectors.groupingBy(Observer::getClass));

collector.property("observers").writeDelegate(observerCollector -> {
for (Entry<Class<? extends Observer>, List<Observer>> entry : observers.entrySet()) {
observerCollector.property(entry.getKey().getSimpleName()).writeInts(entry.getValue().size());
}
CollectionUtilities.iterateEntries(observers.entrySet(), (type, instances) -> {
observerCollector.property(type.getSimpleName()).writeInts(instances.size());
});
});
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
package org.dockbox.hartshorn.spi;

import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.dockbox.hartshorn.util.CollectionUtilities;
import org.dockbox.hartshorn.util.collections.ConcurrentSetMultiMap;
import org.dockbox.hartshorn.util.collections.MultiMap;
Expand All @@ -27,11 +26,9 @@
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.ServiceConfigurationError;
import java.util.ServiceLoader;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,21 @@ public static <T> void indexed(Iterator<T> iterator, BiConsumer<Integer, T> cons
* @param <T> The type of the keys in the entries
* @param <U> The type of the values in the entries
*/
public static <T, U> void iterateEntries(Collection<Entry<T, U>> iterator, BiConsumer<T, U> consumer) {
iterateEntries(iterator.iterator(), consumer);
}

/**
* Iterates over the given iterator of {@link java.util.Map.Entry entries} and applies the given
* consumer to each entry. This is no different from iterating over the entries and applying a
* consumer to each entry, except for the fact that this method allows a bi-consumer to be used
* instead.
*
* @param iterator The iterator to iterate over
* @param consumer The consumer to apply to each entry
* @param <T> The type of the keys in the entries
* @param <U> The type of the values in the entries
*/
public static <T, U> void iterateEntries(Iterator<Entry<T, U>> iterator, BiConsumer<T, U> consumer) {
while (iterator.hasNext()) {
Entry<T, U> entry = iterator.next();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Map.Entry;

/**
* An {@link InvocationHandler} for an annotation which is backed by a {@link Map} of values.
Expand Down Expand Up @@ -78,17 +77,17 @@ private Map<String, Object> checkValues(Class<?> type, Map<String, Object> value
if (type == null) {
throw new IllegalStateException("Type is null");
}
for (Entry<String, Object> entry : values.entrySet()) {
CollectionUtilities.iterateEntries(values.entrySet(), (property, value) -> {
try {
Method method = type.getDeclaredMethod(entry.getKey());
if (!TypeUtils.isAssignable(method.getReturnType(), entry.getValue().getClass())) {
throw new IllegalStateException("Value " + entry.getValue() + " is not assignable to " + method.getReturnType());
Method method = type.getDeclaredMethod(property);
if (!TypeUtils.isAssignable(method.getReturnType(), value.getClass())) {
throw new IllegalStateException("Value " + value + " is not assignable to " + method.getReturnType());
}
}
catch (NoSuchMethodException e) {
throw new IllegalStateException("No such method " + entry.getKey() + " on annotation " + type.getCanonicalName());
throw new IllegalStateException("No such method " + property + " on annotation " + type.getCanonicalName());
}
}
});
return values;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package org.dockbox.hartshorn.util;

import java.time.Duration;
import java.util.Collections;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import java.util.Collection;
import java.util.Map.Entry;
import java.util.Set;
import org.dockbox.hartshorn.util.CollectionUtilities;

/**
* A base implementation of a {@link BiMultiMap}. This implementation handles the inverse map
Expand All @@ -44,13 +45,11 @@ protected AbstractBiMultiMap(MultiMap<K, V> map) {
public MultiMap<V, K> inverse() {
Set<Entry<K, Collection<V>>> entries = this.entrySet();
MultiMap<V, K> inverseMap = this.createEmptyInverseMap();
for (Entry<K, Collection<V>> entry : entries) {
K key = entry.getKey();
Collection<V> values = entry.getValue();
CollectionUtilities.iterateEntries(entries, (key, values) -> {
for (V value : values) {
inverseMap.put(value, key);
}
}
});
return inverseMap;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,12 @@

package org.dockbox.hartshorn.util.collections;

import org.dockbox.hartshorn.util.CollectionUtilities;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.function.BiConsumer;
import org.dockbox.hartshorn.util.CollectionUtilities;

/**
* A base implementation of {@link MultiMap} that provides default implementations for most methods.
Expand Down Expand Up @@ -62,9 +60,7 @@ public void putAll(K key, Collection<V> values) {

@Override
public void putAll(MultiMap<K, V> map) {
for (Entry<K, Collection<V>> collection : map.entrySet()) {
this.putAll(collection.getKey(), collection.getValue());
}
CollectionUtilities.iterateEntries(map.entrySet(), this::putAll);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import java.util.Map.Entry;
import java.util.Set;
import java.util.function.BiConsumer;

import org.dockbox.hartshorn.util.CollectionUtilities;

public class UnmodifiableMultiMap<K, V> implements MultiMap<K, V> {
Expand Down
Loading

0 comments on commit 343dabf

Please sign in to comment.