io.jexxa.core.convention.AdapterConvention Maven / Gradle / Ivy
package io.jexxa.core.convention;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
public final class AdapterConvention
{
public static void validate(Class clazz)
{
if (
isDefaultConstructorAvailable(clazz)
|| isPropertiesConstructorAvailable(clazz)
|| isDefaultFactoryMethodAvailable(clazz)
|| isPropertiesFactoryMethodAvailable(clazz)
)
{
return;
}
throw new AdapterConventionViolation(clazz);
}
public static boolean isPortAdapter(Class
port, List acceptedInfrastructure)
{
//Check constructor with one single application/domain service
if ( Arrays.stream(port.getConstructors())
.filter(constructor -> constructor.getParameterTypes().length == 1)
.anyMatch(constructor -> !constructor.getParameterTypes()[0].isInterface())
&&
isInInfrastructurePackage(port, acceptedInfrastructure))
{
return true;
}
//Check constructor with one single application/domain service and a properties-parameter
return Arrays.stream(port.getConstructors())
.filter(constructor -> constructor.getParameterTypes().length == 2)
.anyMatch(constructor -> !constructor.getParameterTypes()[0].isInterface()
&& constructor.getParameterTypes()[1].isAssignableFrom(Properties.class)
)
&&
isInInfrastructurePackage(port, acceptedInfrastructure);
}
private static boolean isDefaultConstructorAvailable(Class clazz)
{
try
{
clazz.getConstructor();
return true; //Default constructor available
}
catch (NoSuchMethodException | SecurityException ignored)
{
//If exception is thrown go on to check if another suitable constructor is available
}
return false;
}
private static boolean isPropertiesConstructorAvailable(Class clazz)
{
try
{
clazz.getConstructor(Properties.class);
return true; //Constructor with Properties argument available
}
catch (NoSuchMethodException | SecurityException ignored)
{
//If exception is thrown go on to check if another suitable constructor is available
}
return false;
}
private static boolean isDefaultFactoryMethodAvailable(Class clazz)
{
var factoryMethods = Arrays
.stream(clazz.getMethods())
.filter(method -> Modifier.isStatic(method.getModifiers()))
.filter(method -> method.getReturnType().isAssignableFrom(clazz))
.toList();
return factoryMethods.stream().anyMatch(method -> method.getParameterCount() == 0); //Factory method with no arguments available
}
private static boolean isPropertiesFactoryMethodAvailable(Class clazz)
{
var factoryMethods = Arrays
.stream(clazz.getMethods())
.filter(method -> Modifier.isStatic(method.getModifiers()))
.filter(method -> method.getReturnType().isAssignableFrom(clazz))
.toList();
return factoryMethods.stream().anyMatch(method -> (
method.getParameterCount() == 1 &&
method.getParameterTypes()[0].isAssignableFrom(Properties.class))); //Factory method with Properties argument available
}
private static boolean isInInfrastructurePackage( Class clazz, List acceptedInfrastructure)
{
return acceptedInfrastructure
.stream()
.anyMatch( element -> clazz.getPackage().toString().contains( element ) );
}
private AdapterConvention()
{
//Private Constructor
}
}