All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.datakernel.di.core.BindingTransformer Maven / Gradle / Ivy

package io.datakernel.di.core;

import io.datakernel.di.impl.BindingLocator;
import org.jetbrains.annotations.NotNull;

import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import static java.util.stream.Collectors.toList;

/**
 * This is a transformation function that is applied by the {@link Injector injector} to each binding once.
 */
@FunctionalInterface
public interface BindingTransformer {
	BindingTransformer IDENTITY = (bindings, scope, key, binding) -> binding;

	@NotNull Binding transform(BindingLocator bindings, Scope[] scope, Key key, Binding binding);

	@SuppressWarnings("unchecked")
	static  BindingTransformer identity() {
		return (BindingTransformer) IDENTITY;
	}

	/**
	 * Modules export a priority multimap of transformers.
	 * 

* This transformer aggregates such map into one big generator to be used by {@link Injector#compile} method. * The map is converted to a sorted list of sets. * Then for each of those sets, similar to {@link BindingGenerator#combinedGenerator generators}, * only zero or one transformer from that set are allowed to return anything but the binding is was given (being an identity transformer). *

* So if two transformers differ in priority then they can be applied both in order of their priority. */ @SuppressWarnings("unchecked") static BindingTransformer combinedTransformer(Map>> transformers) { List>> transformerList = transformers.entrySet().stream() .sorted(Comparator.comparing(Entry::getKey)) .map(Entry::getValue) .collect(toList()); return (bindings, scope, key, binding) -> { Binding result = binding; for (Set> localTransformers : transformerList) { Binding transformed = null; for (BindingTransformer transformer : localTransformers) { Binding b = ((BindingTransformer) transformer).transform(bindings, scope, key, result); if (b.equals(binding)) { continue; } if (transformed != null) { throw new DIException("More than one transformer with the same priority transformed a binding for key " + key.getDisplayString()); } transformed = b; } if (transformed != null) { result = transformed; } } return result; }; } }