BuiltInHandlerFactory.java
package com.github.dakusui.osynth.annotations;
import com.github.dakusui.osynth.core.*;
import java.lang.annotation.Retention;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Objects;
import java.util.function.Supplier;
import java.util.stream.Stream;
import static com.github.dakusui.osynth.core.utils.AssertionUtils.methodIsAnnotationPresent;
import static com.github.dakusui.osynth.core.utils.MethodUtils.execute;
import static com.github.dakusui.osynth.core.utils.MethodUtils.withName;
import static com.github.dakusui.pcond.forms.Predicates.and;
import static com.github.dakusui.pcond.forms.Predicates.isNotNull;
import static com.github.dakusui.valid8j.Assertions.that;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import static java.util.stream.Collectors.joining;
@Retention(RUNTIME)
public @interface BuiltInHandlerFactory {
Class<? extends MethodHandlerFactory> value();
interface MethodHandlerFactory {
MethodHandler create(Supplier<SynthesizedObject.Descriptor> descriptorSupplier);
static MethodHandler createBuiltInMethodHandlerFor(Method method, Supplier<SynthesizedObject.Descriptor> descriptorSupplier) {
assert that(method, and(
isNotNull(),
methodIsAnnotationPresent(BuiltInHandlerFactory.class)));
BuiltInHandlerFactory annotation = method.getAnnotation(BuiltInHandlerFactory.class);
return execute(() -> withName("builtIn-" + method.getName(), annotation.value().newInstance().create(descriptorSupplier)));
}
static Stream<MethodHandlerEntry> createMethodHandlersForBuiltInMethods(Supplier<SynthesizedObject.Descriptor> descriptorSupplier) {
return Arrays.stream(SynthesizedObject.class.getMethods())
.filter(each -> each.isAnnotationPresent(BuiltInHandlerFactory.class))
.map((Method eachMethod) -> {
MethodSignature targetMethodSignature = MethodSignature.create(eachMethod);
return MethodHandlerEntry.create(
MethodMatcher.create(mm -> String.format("builtInFor:%s%s", eachMethod.getName(), Arrays.toString(eachMethod.getParameterTypes())),
(Method candidate) -> targetMethodSignature.equals(MethodSignature.create(candidate))),
createBuiltInMethodHandlerFor(eachMethod, descriptorSupplier), true);
});
}
}
class ForToString implements MethodHandlerFactory {
@Override
public MethodHandler.BuiltIn create(Supplier<SynthesizedObject.Descriptor> descriptorSupplier) {
return (synthesizedObject, objects) -> composeFormattedString(synthesizedObject);
}
private static String composeFormattedString(SynthesizedObject synthesizedObject) {
return String.format("osynth(%s):%s",
synthesizedObject.descriptor().interfaces()
.stream()
.map(Class::getSimpleName)
.collect(joining(",")),
synthesizedObject.descriptor());
}
}
class ForHashCode implements MethodHandlerFactory {
@Override
public MethodHandler.BuiltIn create(Supplier<SynthesizedObject.Descriptor> descriptorSupplier) {
return (synthesizedObject, objects) -> synthesizedObject.descriptor().hashCode();
}
}
class ForEquals implements MethodHandlerFactory {
@Override
public MethodHandler.BuiltIn create(Supplier<SynthesizedObject.Descriptor> descriptorSupplier) {
return (synthesizedObject, objects) -> {
if (synthesizedObject == objects[0])
return true;
if (!(objects[0] instanceof SynthesizedObject))
return false;
SynthesizedObject another = (SynthesizedObject) objects[0];
return Objects.equals(synthesizedObject.descriptor(), another.descriptor());
};
}
}
class ForDescriptor implements MethodHandlerFactory {
@Override
public MethodHandler.BuiltIn create(Supplier<SynthesizedObject.Descriptor> descriptorSupplier) {
return (synthesizedObject, objects) -> descriptorSupplier.get();
}
}
}