Purge warnings in IDE

This commit is contained in:
Dave Syer
2017-03-14 16:51:23 +00:00
parent 915ff401be
commit da013c1015
8 changed files with 109 additions and 69 deletions

View File

@@ -35,7 +35,8 @@ import org.springframework.util.StringUtils;
*/
public abstract class AbstractFunctionCompiler<F> {
private static Logger logger = LoggerFactory.getLogger(AbstractFunctionCompiler.class);
private static Logger logger = LoggerFactory
.getLogger(AbstractFunctionCompiler.class);
// Newlines in the property are escaped
private static final String NEWLINE_ESCAPE = Matcher.quoteReplacement("\\n");
@@ -44,20 +45,25 @@ public abstract class AbstractFunctionCompiler<F> {
private static final String DOUBLE_DOUBLE_QUOTE = Matcher.quoteReplacement("\"\"");
/**
* The user supplied code snippet is inserted into the template and then the result is compiled
* The user supplied code snippet is inserted into the template and then the result is
* compiled
*/
private static String SOURCE_CODE_TEMPLATE =
"package " + AbstractFunctionCompiler.class.getPackage().getName() + ";\n" +
"import java.util.*;\n" + // Helpful to include this
"import java.util.function.*;\n" +
"import reactor.core.publisher.Flux;\n" +
"public class %s implements %sFactory {\n" +
" public %s<%s> getResult() {\n" +
" %s\n" +
" }\n" +
"}\n";
// @formatter:off
private static String SOURCE_CODE_TEMPLATE = "package "
+ AbstractFunctionCompiler.class.getPackage().getName() + ";\n"
+ "import java.util.*;\n" // Helpful to include this
+ "import java.util.function.*;\n"
+ "import reactor.core.publisher.Flux;\n"
+ "public class %s implements %sFactory {\n"
+ " public %s<%s> getResult() {\n"
+ " %s\n"
+ " }\n"
+ "}\n";
// @formatter:on
static enum ResultType { Consumer, Function, Supplier }
static enum ResultType {
Consumer, Function, Supplier
}
private final ResultType resultType;
@@ -65,82 +71,98 @@ public abstract class AbstractFunctionCompiler<F> {
private final RuntimeJavaCompiler compiler = new RuntimeJavaCompiler();
AbstractFunctionCompiler(ResultType type, String... defaultResultTypeParameterizations) {
AbstractFunctionCompiler(ResultType type,
String... defaultResultTypeParameterizations) {
this.resultType = type;
this.defaultResultTypeParameterizations = defaultResultTypeParameterizations;
}
/**
* Produce a factory instance by:<ul>
* Produce a factory instance by:
* <ul>
* <li>Decoding the code String to process any newlines/double-double-quotes
* <li>Insert the code into the source code template for a class
* <li>Compiling the class using the JDK provided Java Compiler
* <li>Loading the compiled class
* <li>Invoking a well known method on the factory class to produce a Consumer, Function, or Supplier instance
* <li>Invoking a well known method on the factory class to produce a Consumer,
* Function, or Supplier instance
* <li>Returning that instance.
* </ul>
*
* @return a factory instance
*/
public CompiledFunctionFactory<F> compile(String name, String code, String... resultTypeParameterizations) {
public CompiledFunctionFactory<F> compile(String name, String code,
String... resultTypeParameterizations) {
if (name == null || name.length() == 0) {
throw new IllegalArgumentException("name must not be empty");
}
logger.info("Initial code property value :'{}'", code);
String parameterizations = StringUtils.arrayToCommaDelimitedString(
(!ObjectUtils.isEmpty(resultTypeParameterizations)) ? resultTypeParameterizations : this.defaultResultTypeParameterizations);
code = decode(code);
if (code.startsWith("\"") && code.endsWith("\"")) {
code = code.substring(1,code.length()-1);
}
if (!code.startsWith("return ") && !code.endsWith(";")) {
code = String.format("return (%s<%s> & java.io.Serializable) %s;", resultType, parameterizations, code);
String parameterizations = StringUtils.arrayToCommaDelimitedString(
(!ObjectUtils.isEmpty(resultTypeParameterizations))
? resultTypeParameterizations
: this.defaultResultTypeParameterizations);
code = decode(code);
if (code.startsWith("\"") && code.endsWith("\"")) {
code = code.substring(1, code.length() - 1);
}
if (!code.startsWith("return ") && !code.endsWith(";")) {
code = String.format("return (%s<%s> & java.io.Serializable) %s;", resultType,
parameterizations, code);
}
logger.info("Processed code property value :\n{}\n", code);
String firstLetter = name.substring(0, 1).toUpperCase();
name = (name.length() > 1) ? firstLetter + name.substring(1) : firstLetter;
String className = String.format("%s.%s%sFactory", this.getClass().getPackage().getName(), name, resultType);
CompilationResult compilationResult = buildAndCompileSourceCode(className, code, parameterizations);
String className = String.format("%s.%s%sFactory",
this.getClass().getPackage().getName(), name, resultType);
CompilationResult compilationResult = buildAndCompileSourceCode(className, code,
parameterizations);
if (compilationResult.wasSuccessful()) {
return new CompiledFunctionFactory(className, compilationResult);
return new CompiledFunctionFactory<F>(className, compilationResult);
}
List<CompilationMessage> compilationMessages = compilationResult.getCompilationMessages();
List<CompilationMessage> compilationMessages = compilationResult
.getCompilationMessages();
throw new CompilationFailedException(compilationMessages);
}
/**
* Create the source for and then compile and load a class that embodies
* the supplied methodBody. The methodBody is inserted into a class template that
* returns the specified parameterized type.
* This method can return more than one class if the method body includes local class
* declarations. An example methodBody would be <tt>return input -> input.buffer(5).map(list->list.get(0));</tt>.
* Create the source for and then compile and load a class that embodies the supplied
* methodBody. The methodBody is inserted into a class template that returns the
* specified parameterized type. This method can return more than one class if the
* method body includes local class declarations. An example methodBody would be
* <tt>return input -> input.buffer(5).map(list->list.get(0));</tt>.
*
* @param className the name of the class
* @param methodBody the source code for a method
* @param parameterTypeString the String representation for the parameterized return type, e.g.:
* <tt>&lt;Flux&lt;Object&gt;,Flux&lt;Object&gt;</tt>
* @return the list of Classes produced by compiling and then loading the snippet of code
* @param parameterTypeString the String representation for the parameterized return
* type, e.g.: <tt>&lt;Flux&lt;Object&gt;,Flux&lt;Object&gt;</tt>
* @return the list of Classes produced by compiling and then loading the snippet of
* code
*/
private CompilationResult buildAndCompileSourceCode(String className, String methodBody, String parameterTypeString) {
String sourceCode = makeSourceClassDefinition(className, methodBody, parameterTypeString);
private CompilationResult buildAndCompileSourceCode(String className,
String methodBody, String parameterTypeString) {
String sourceCode = makeSourceClassDefinition(className, methodBody,
parameterTypeString);
return compiler.compile(className, sourceCode);
}
private static String decode(String input) {
return input.replaceAll(NEWLINE_ESCAPE, "\n").replaceAll(DOUBLE_DOUBLE_QUOTE, "\"");
return input.replaceAll(NEWLINE_ESCAPE, "\n").replaceAll(DOUBLE_DOUBLE_QUOTE,
"\"");
}
/**
* Make a full source code definition for a class by applying the specified method body
* to the Reactive template.
* Make a full source code definition for a class by applying the specified method
* body to the Reactive template.
*
* @param className the name of the class
* @param methodBody the code to insert into the Reactive source class template
* @return a complete Java Class definition
*/
private String makeSourceClassDefinition(String className, String methodBody, String types) {
private String makeSourceClassDefinition(String className, String methodBody,
String types) {
String shortClassName = className.substring(className.lastIndexOf('.') + 1);
String s = String.format(SOURCE_CODE_TEMPLATE, shortClassName, resultType, resultType, types, methodBody);
String s = String.format(SOURCE_CODE_TEMPLATE, shortClassName, resultType,
resultType, types, methodBody);
System.out.println(s);
return s;
}