122 lines
3.7 KiB
Java
122 lines
3.7 KiB
Java
package net.tomatentum.cutin.container;
|
|
|
|
import java.lang.reflect.Method;
|
|
import java.util.Collection;
|
|
import java.util.HashSet;
|
|
import java.util.Optional;
|
|
import java.util.Set;
|
|
import java.util.stream.Collectors;
|
|
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
import net.tomatentum.cutin.factory.ReflectedMethodFactory;
|
|
import net.tomatentum.cutin.method.ReflectedMethod;
|
|
import net.tomatentum.cutin.util.ReflectionUtil;
|
|
|
|
public class MultiMethodContainer<I extends Object, C extends Object> implements MethodContainer<I, C> {
|
|
|
|
private Set<Entry<I, C>> entries;
|
|
private ReflectedMethodFactory<I, C> factory;
|
|
|
|
public MultiMethodContainer(ReflectedMethodFactory<I, C> factory) {
|
|
this.entries = new HashSet<>();
|
|
this.factory = factory;
|
|
}
|
|
|
|
@Override
|
|
public MethodContainer<I, C> addMethod(ReflectedMethod<I, C> method) {
|
|
Optional<Entry<I, C>> oentry = this.entries.stream()
|
|
.filter(e -> method.identifier().equals(e.identifier()))
|
|
.findFirst();
|
|
Entry<I, C> entry = oentry.orElse(new Entry<>(method.identifier())).addMethod(method);
|
|
if (oentry.isEmpty()) this.entries.add(entry);
|
|
return this;
|
|
}
|
|
|
|
@Override
|
|
public MethodContainer<I, C> addMethods(Object containingObject, Method... methods) {
|
|
for (Method method : methods)
|
|
this.factory.produce(method, containingObject)
|
|
.ifPresent(this::addMethod);
|
|
return this;
|
|
}
|
|
|
|
@Override
|
|
public Set<I> identifiers() {
|
|
return entries().stream()
|
|
.map(Entry::identifier)
|
|
.collect(Collectors.toSet());
|
|
}
|
|
|
|
@Override
|
|
public Collection<ReflectedMethod<I, C>> methods() {
|
|
return this.entries.stream()
|
|
.flatMap(e -> e.methods.stream())
|
|
.toList();
|
|
}
|
|
|
|
@Override
|
|
public Collection<ReflectedMethod<I, C>> findFor(I identifier) {
|
|
return this.entries.stream()
|
|
.filter(e -> e.identifier().equals(identifier))
|
|
.flatMap(e -> e.methods.stream())
|
|
.toList();
|
|
}
|
|
|
|
@Override
|
|
public Optional<ReflectedMethod<I, C>> findFirstFor(I identifier) {
|
|
return this.entries.stream()
|
|
.filter(e -> e.identifier().equals(identifier))
|
|
.flatMap(e -> e.methods.stream())
|
|
.findFirst();
|
|
}
|
|
|
|
protected Set<Entry<I, C>> entries() {
|
|
return this.entries;
|
|
}
|
|
|
|
public ReflectedMethodFactory<I, C> factory() {
|
|
return this.factory;
|
|
}
|
|
|
|
public static record Entry<I extends Object, C extends Object>(I identifier, Set<ReflectedMethod<I, C>> methods) {
|
|
|
|
public Entry(I identifier) {
|
|
this(identifier, new HashSet<>());
|
|
}
|
|
|
|
private static Logger logger = LoggerFactory.getLogger(Entry.class);
|
|
|
|
public Entry<I, C> addMethod(ReflectedMethod<I, C> method) {
|
|
I midentifier = method.identifier();
|
|
|
|
if (!this.identifier().equals(midentifier))
|
|
throw new IllegalArgumentException("Method's identifier did not equal the entry's identifier");
|
|
|
|
this.methods.add(method);
|
|
logger.debug("Added method {} to entry {}", ReflectionUtil.getFullMethodName(method.method()), this);
|
|
return this;
|
|
}
|
|
|
|
@Override
|
|
public boolean equals(Object obj) {
|
|
if (!(obj instanceof Entry))
|
|
return false;
|
|
Entry<?, ?> other = (Entry<?, ?>) obj;
|
|
return other.identifier().equals(identifier());
|
|
}
|
|
|
|
@Override
|
|
public int hashCode() {
|
|
return this.identifier().hashCode();
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
return "Ident(%s)".formatted(identifier().toString());
|
|
}
|
|
}
|
|
|
|
}
|