package com.lambdaworks.apigenerator;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.ast.body.MethodDeclaration;
import com.github.javaparser.ast.type.ClassOrInterfaceType;
import com.github.javaparser.ast.type.ReferenceType;
import com.github.javaparser.ast.type.Type;
import com.lambdaworks.redis.internal.LettuceSets;
/**
* Create sync API based on the templates.
*
* @author Mark Paluch
*/
@RunWith(Parameterized.class)
public class CreateSyncNodeSelectionClusterApi {
private Set<String> FILTER_METHODS = LettuceSets.unmodifiableSet("shutdown", "debugOom", "debugSegfault", "digest", "close",
"isOpen", "BaseRedisCommands.reset", "readOnly", "readWrite", "dispatch");
private CompilationUnitFactory factory;
@Parameterized.Parameters(name = "Create {0}")
public static List<Object[]> arguments() {
List<Object[]> result = new ArrayList<>();
for (String templateName : Constants.TEMPLATE_NAMES) {
if (templateName.contains("Transactional") || templateName.contains("Sentinel")) {
continue;
}
result.add(new Object[] { templateName });
}
return result;
}
/**
* @param templateName
*/
public CreateSyncNodeSelectionClusterApi(String templateName) {
String targetName = templateName.replace("Redis", "NodeSelection");
File templateFile = new File(Constants.TEMPLATES, "com/lambdaworks/redis/api/" + templateName + ".java");
String targetPackage = "com.lambdaworks.redis.cluster.api.sync";
// todo: remove AutoCloseable from BaseNodeSelectionAsyncCommands
factory = new CompilationUnitFactory(templateFile, Constants.SOURCES, targetPackage, targetName, commentMutator(),
methodTypeMutator(), methodFilter(), importSupplier(), null, null);
}
/**
* Mutate type comment.
*
* @return
*/
protected Function<String, String> commentMutator() {
return s -> s.replaceAll("\\$\\{intent\\}", "Synchronous executed commands on a node selection") + "* @generated by "
+ getClass().getName() + "\r\n ";
}
/**
* Mutate type to async result.
*
* @return
*/
protected Predicate<MethodDeclaration> methodFilter() {
return method -> {
ClassOrInterfaceDeclaration classOfMethod = (ClassOrInterfaceDeclaration) method.getParentNode();
if (FILTER_METHODS.contains(method.getName())
|| FILTER_METHODS.contains(classOfMethod.getName() + "." + method.getName())) {
return false;
}
return true;
};
}
/**
* Mutate type to async result.
*
* @return
*/
protected Function<MethodDeclaration, Type> methodTypeMutator() {
return method -> {
ClassOrInterfaceDeclaration classOfMethod = (ClassOrInterfaceDeclaration) method.getParentNode();
if (FILTER_METHODS.contains(method.getName())
|| FILTER_METHODS.contains(classOfMethod.getName() + "." + method.getName())) {
return method.getType();
}
String typeAsString = method.getType().toStringWithoutComments().trim();
if (typeAsString.equals("void")) {
typeAsString = "Void";
}
return new ReferenceType(new ClassOrInterfaceType("Executions<" + typeAsString + ">"));
};
}
/**
* Supply additional imports.
*
* @return
*/
protected Supplier<List<String>> importSupplier() {
return () -> Collections.emptyList();
}
@Test
public void createInterface() throws Exception {
factory.createInterface();
}
}