io.starter.ignite.generator.JavaGen Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of stackgen Show documentation
Show all versions of stackgen Show documentation
Starter StackGen CORE Service Generator
package io.starter.ignite.generator;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import javax.lang.model.element.Modifier;
import javax.tools.Diagnostic;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.squareup.javapoet.AnnotationSpec;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.FieldSpec;
import com.squareup.javapoet.JavaFile;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.TypeName;
import com.squareup.javapoet.TypeSpec;
import io.starter.ignite.generator.DMLgenerator.Table;
import io.starter.toolkit.StringTool;
import io.swagger.annotations.ApiModelProperty;
/**
* Generating Java code
*
* @author John McMahon (@TechnoCharms)
*
*/
public class JavaGen extends Gen implements Generator {
protected static final Logger logger = LoggerFactory
.getLogger(JavaGen.class);
public static Map createClasses(Class c) throws Exception {
final JavaGen gen = new JavaGen();
final Map classesToGenerate = gen.processClasses(c, null, gen);
return classesToGenerate;
}
@Override
public Object createMember(Field fld) {
return null;
}
@Override
public Object createAccessor(Field fld) {
try {
final ApiModelProperty apimp = Gen
.getApiModelPropertyAnnotation(fld);
apimp.secureField();
} catch (NoSuchMethodException | SecurityException e1) {
// no worries
}
final String fieldName = fld.getName();
if (fieldName.startsWith("ajc$") || fieldName.equals("delegate")
|| fieldName.equals("serialVersionUID")) {
return null;
}
// validate the column names for round trip compatibility
validateColumn(fieldName);
final String className = fld.getDeclaringClass().getName();
String memberName = className.substring(className.lastIndexOf(".") + 1);
memberName += "Delegate";
final Class fieldType = fld.getType();
final String fldName = StringTool.getGetMethodNameFromVar(fieldName);
try {
final MethodSpec ret = MethodSpec.methodBuilder(fldName)
.addJavadoc(GENERATED_TEXT_BLOCK + " Method: "
+ DATE_FORMAT.format(new Date()) + LINE_FEED
+ LINE_FEED + "@see "
+ fld.getDeclaringClass().getName() + LINE_FEED
+ LINE_FEED + "@return the value of: " + fieldName)
.addModifiers(Modifier.PUBLIC).returns(fieldType)
.addStatement("return " + memberName + "." + fieldName)
.build();
return ret;
} catch (final Exception e) {
logger.error("COULD NOT GENERATE FIELD: " + memberName + " "
+ e.toString());
}
return null;
}
/**
* check validity of the column name (it will survive round
* trip codegen camel/decamel)
*
* @param fieldName
* @throws IgniteException
*/
private void validateColumn(final String fieldName) throws IgniteException {
if (fieldName.equals(fieldName.toLowerCase())
|| fieldName.equals(fieldName.toUpperCase())) { // case
// insensitive
return;
}
final String checkName = Table.convertToDBSyntax(fieldName);
final String nameRoundTrip = Table.convertToJavaSyntax(checkName);
final String syntaxCheck = Table.convertToDBSyntax(nameRoundTrip);
if (!checkName.equals(syntaxCheck)) {
throw new IgniteException("COLUMN NAME IS UNSUPPORTED: " + checkName
+ ":" + nameRoundTrip + ":" + syntaxCheck);
}
}
@Override
public Object createSetter(Field fld) {
final String fieldName = fld.getName();
final String className = fld.getDeclaringClass().getName();
String memberName = className.substring(className.lastIndexOf(".") + 1);
memberName += "Delegate";
if (fieldName.startsWith("ajc$") || fieldName.equals("delegate")
|| fieldName.equals("serialVersionUID")) {
return null;
}
final Class fieldType = fld.getType();
final String fldNameSet = StringTool.getSetMethodNameFromVar(fieldName);
try {
final MethodSpec ret = MethodSpec.methodBuilder(fldNameSet)
.addJavadoc(GENERATED_TEXT_BLOCK + " Method: "
+ DATE_FORMAT.format(new Date()))
// .addModifiers(Modifier.PUBLIC).addAnnotation(AnnotationSpec.builder(DataField.class).build())
.addModifiers(Modifier.PUBLIC)
.addParameter(fieldType, fieldName + "Val")
.addStatement(memberName + "." + fieldName + " = "
+ fieldName + "Val")
.build();
return ret;
} catch (final Exception e) {
logger.error("ERROR CREATING SETTER for: " + fieldName + " "
+ e.toString());
}
return null;
}
public FieldSpec createLoggerField(String className) throws ClassNotFoundException {
final Class cx = Class.forName("org.slf4j.Logger");
return FieldSpec.builder(cx, "log").addModifiers(Modifier.PRIVATE)
.initializer("org.slf4j.LoggerFactory\n"
+ " .getLogger(" + className
+ ADD_GEN_CLASS_NAME + ".class)")
.addAnnotation(getJSONIgnoreSpec()).build();
}
// ## MYBATIS INSERT/UPDATE/DELETE/LIST
public FieldSpec createSQLSessionFactoryField() throws ClassNotFoundException {
final Class cx = Class
.forName("org.apache.ibatis.session.SqlSessionFactory");
return FieldSpec.builder(cx, "sqlSessionFactory")
.addModifiers(Modifier.PRIVATE)
.initializer("io.starter.ignite.security.dao.MyBatisConnectionFactory\n"
+ " .getSqlSessionFactory()")
.addAnnotation(getJSONIgnoreSpec()).build();
}
/**
* create get object mapper method
*
* @param className
* @return
*/
public MethodSpec createGetObjectMapper(String className) {
final String methodText = "objectMapper.setSerializationInclusion(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_EMPTY);"
+ "\n" + "return objectMapper";
try {
final ClassName cx = ClassName
.get("com.fasterxml.jackson.databind", "ObjectMapper");
return MethodSpec.methodBuilder("getObjectMapper")
.addJavadoc(GENERATED_TEXT_BLOCK + " Method: "
+ DATE_FORMAT.format(new Date()))
.addModifiers(Modifier.PUBLIC).addStatement(methodText)
.returns(cx).build();
} catch (final Exception e) {
logger.error("ERROR creating getObjectMapper method for: "
+ className + " " + e.toString());
}
return null;
}
/**
* create getAcceptHeader method
*
* @param className
* @return
*/
public MethodSpec createGetAcceptHeader(String className) {
final String methodText = "return httpServletRequest.getHeader(\"accept\")";
try {
final ClassName cx = ClassName.get("java.lang", "String");
return MethodSpec.methodBuilder("getAcceptHeader")
.addJavadoc(GENERATED_TEXT_BLOCK + " Method: "
+ DATE_FORMAT.format(new Date()))
.addModifiers(Modifier.PUBLIC).addStatement(methodText)
.addAnnotation(getJSONIgnoreSpec()).returns(cx).build();
} catch (final Exception e) {
logger.error("ERROR creating getAcceptHeader method for: "
+ className + " " + e.toString());
}
return null;
}
/**
* create getHttpServletRequest mapper method
*
* @param className
* @return
*/
public MethodSpec createGetHttpServletRequest(String className) {
final String methodText = "return httpServletRequest";
try {
final ClassName cx = ClassName
.get("javax.servlet.http", "HttpServletRequest");
return MethodSpec.methodBuilder("getHttpServletRequest")
.addJavadoc(GENERATED_TEXT_BLOCK + " Method: "
+ DATE_FORMAT.format(new Date()))
.addModifiers(Modifier.PUBLIC).addStatement(methodText)
.returns(cx).build();
} catch (final Exception e) {
logger.error("ERROR creating createGetHttpServletRequest method for: "
+ className + " " + e.toString());
}
return null;
}
/**
* create setDelegate method
*/
public MethodSpec createSetDelegate(String className) {
final String bname = getBaseJavaName(className);
final String methodText = bname + "Delegate = (" + bname + ")bx";
try {
return MethodSpec.methodBuilder("setDelegate")
.addJavadoc("Starter StackGen 'JavaGen' Generated Method: "
+ DATE_FORMAT.format(new Date()))
.addModifiers(Modifier.PUBLIC).addStatement(methodText)
.addParameter(Object.class, "bx").build();
} catch (final Exception e) {
logger.error("ERROR creating setDelegate method for: " + className + " "
+ e.toString());
}
return null;
}
/**
* create getselectByExample method
*
*/
public MethodSpec createGetselectByExample(String className) {
final String methodText = "if(selectByExample == null) " + "\r\n"
+ " selectByExample = new " + getMyBatisName(className)
+ "Example();" + "\r\n" + "return selectByExample";
try {
return MethodSpec.methodBuilder("getSelectByExample")
.addJavadoc(GENERATED_TEXT_BLOCK + " Method: "
+ DATE_FORMAT.format(new Date()))
.addModifiers(Modifier.PUBLIC).addStatement(methodText)
.returns(ClassName.get(MODEL_DAO_PACKAGE, MyBatisGen
.getMyBatisModelClassName(className) + "Example"))
.build();
} catch (final Exception e) {
logger.error("ERROR creating createGetselectByExample method for: "
+ className + " " + e.toString());
}
return null;
}
/**
* create getDelegate method
*
*/
public MethodSpec createGetDelegate(String className) {
final String bname = getBaseJavaName(className);
final String methodText = "return null"; // dealing with recursion issues // + bname + "Delegate";
try {
return MethodSpec.methodBuilder("getDelegate")
.addJavadoc(GENERATED_TEXT_BLOCK + " Method: "
+ DATE_FORMAT.format(new Date()))
.addModifiers(Modifier.PUBLIC).addStatement(methodText)
.returns(ClassName.get("java.lang", "Object")).build();
} catch (final Exception e) {
logger.error("ERROR creating getDelegate method for: " + className + " "
+ e.toString());
}
return null;
}
/**
* create MyBatis list method
*
* @param className
* @return
*/
public MethodSpec createList(String className) {
final String mapperName = getMyBatisName(className);
final String methodText = " final org.apache.ibatis.session.SqlSession session = sqlSessionFactory\n"
+ " .openSession(true);\n" + "\n"
+ " final java.util.List<" + mapperName
+ "> rows = session\n" + " .selectList(\""
+ getMyBatisSQLMapsName(className)
+ "Mapper.selectByExample\", selectByExample);\n" + "\n"
+ " session.close();\n" +
" // translate to our " + getJavaServiceName(className)
+ " class\n" + " java.util.List<"
+ getJavaServiceName(className)
+ "> ret = new java.util.ArrayList<"
+ getJavaServiceName(className) + ">();\n" + " for ("
+ mapperName + " u : rows) {\n" + " "
+ getJavaServiceName(className) + " ux = new "
+ getJavaServiceName(className) + "();\n"
+ " ux.setDelegate(u.delegate);\n"
+ " u = null; // mark for gc\n"
+ " ret.add(ux);\n" + " }\n" + "\n"
+ " return ret";
try {
final ClassName cx = ClassName.get("java.util", "List");
return MethodSpec.methodBuilder("list")
.addJavadoc(GENERATED_TEXT_BLOCK + " Method: "
+ DATE_FORMAT.format(new Date()))
.addModifiers(Modifier.PUBLIC).addStatement(methodText)
.returns(cx).build();
} catch (final Exception e) {
logger.error("ERROR creating list method for: " + className + " "
+ e.toString());
}
return null;
}
/**
* create MyBatis insert method
*
* @param className
* @return
*/
public MethodSpec createInsert(String className) {
getMyBatisName(className);
final String methodText = " final org.apache.ibatis.session.SqlSession session = sqlSessionFactory.openSession(true);\n"
+ " int rows = -1;\n" + " try {\n"
+ " rows = session.insert(\""
+ getMyBatisSQLMapsName(className)
+ "Mapper.insertSelective\", this);\n"
+ " // commit performs the actual insert\n"
+ " session.commit();\n" + " session.close();\n"
+ "} catch (Exception e) {\n"
+ " log.error(\"Could not run INSERT: \" + e.toString());\n"
+ " throw new io.starter.ignite.generator.IgniteException(\"Could not run INSERT: \" + e.toString());\n"
+ " }" + " return rows";
try {
return MethodSpec.methodBuilder("insert")
.addJavadoc(GENERATED_TEXT_BLOCK + " Method: "
+ DATE_FORMAT.format(new Date()))
.addModifiers(Modifier.PUBLIC).addStatement(methodText)
.returns(TypeName.INT).build();
} catch (final Exception e) {
logger.error("ERROR creating insert method for: " + className + " "
+ e.toString());
}
return null;
}
/**
* create MyBatis load method
* final MODEL_DAO_PACKAGE.StarterUser ret = session
.selectOne("MODEL_DAO_PACKAGE.StarterUserMapper.selectByPrimaryKey", getId());
* @param className
* @return
*/
public MethodSpec createLoad(String className) {
final String mapperName = getMyBatisName(className);
final String methodText = " final org.apache.ibatis.session.SqlSession session = sqlSessionFactory\n"
+ " .openSession(true);\n" + mapperName
+ " ret = null; if (selectByExample == null) {"
+ " ret = session.selectOne(\""
+ getMyBatisSQLMapsName(className)
+ "Mapper.selectByPrimaryKey\", getId());\n" + "} else {"
+ " ret = session\n" + " .selectOne(\""
+ getMyBatisSQLMapsName(className)
+ "Mapper.selectByExample\", selectByExample);\n" + "\n" + "}\n"
+ "if(ret!=null){ " + "\n" + "this."
+ getBaseJavaName(className) + "Delegate = ret.delegate;} else {\n"
+ "\n" + " log.error(\"no results searching " + className
+ " field for : \"+getId());" + "\n" + "}" + "\n"
+ " session.close();\n"
+ " return (ret != null ? this : null)";
try {
final ClassName cx = ClassName
.get(IGNITE_MODEL_PACKAGE, getJavaServiceName(className));
return MethodSpec.methodBuilder("load")
.addJavadoc(GENERATED_TEXT_BLOCK + " Method: "
+ DATE_FORMAT.format(new Date()))
.addModifiers(Modifier.PUBLIC).addStatement(methodText)
.returns(cx).build();
} catch (final Exception e) {
logger.error("ERROR creating load method for: " + className + " "
+ e.toString());
}
return null;
}
/**
* create MyBatis update method
*
* @param className
* @return
*/
public MethodSpec createUpdate(String className) {
final String methodText = " final org.apache.ibatis.session.SqlSession session = sqlSessionFactory.openSession(true);\n"
+ " int rows = -1;\n" + " try {\n"
+ " rows = session.update(\""
+ getMyBatisSQLMapsName(className)
+ "Mapper.updateByPrimaryKeySelective\", this);\n"
+ " // commit performs the actual update\n"
+ " session.commit();\n" + " session.close();\n"
+ "} catch (Exception e) {\n"
+ " log.error(\"Could not run UPDATE: \" + e.toString());\n"
+ " throw new io.starter.ignite.generator.IgniteException(\"Could not run INSERT: \" + e.toString());\n"
+ "}" + LINE_FEED + " return rows";
try {
return MethodSpec.methodBuilder("update")
.addJavadoc(GENERATED_TEXT_BLOCK + " Method: "
+ DATE_FORMAT.format(new Date()))
.addModifiers(Modifier.PUBLIC).addStatement(methodText)
.returns(TypeName.INT).build();
} catch (final Exception e) {
logger.error("ERROR creating update method for: " + className + " "
+ e.toString());
}
return null;
}
AnnotationSpec autoWired = null;
private AnnotationSpec getAutoWiredSpec() {
if (autoWired == null) {
autoWired = AnnotationSpec
.builder(org.springframework.beans.factory.annotation.Autowired.class)
.build();
}
return autoWired;
}
AnnotationSpec JSONIgnored;
private AnnotationSpec getJSONIgnoreSpec() {
if (JSONIgnored == null) {
JSONIgnored = AnnotationSpec
.builder(com.fasterxml.jackson.annotation.JsonIgnore.class)
.build();
}
return JSONIgnored;
}
/**
* create MyBatis delete method
*
* @param className
* @return
*/
public MethodSpec createDelete(String className) {
final String methodText = " final org.apache.ibatis.session.SqlSession session = sqlSessionFactory.openSession(true);\n"
+ " int rows = -1;\n" + " try {\n"
+ " rows = session.delete(\""
+ getMyBatisSQLMapsName(className)
+ "Mapper.deleteByPrimaryKey\", getId());\n"
+ " // commit performs the actual delete\n"
+ " session.commit();\n" + " session.close();\n"
+ "} catch (Exception e) {\n"
+ " log.error(\"Could not run DELETE: \" + e.toString());\n"
+ " throw new io.starter.ignite.generator.IgniteException(\"Could not run INSERT: \" + e.toString());\n"
+ " }" + " return rows";
try {
return MethodSpec.methodBuilder("delete")
.addJavadoc(GENERATED_TEXT_BLOCK + " Method: "
+ DATE_FORMAT.format(new Date()))
.addModifiers(Modifier.PUBLIC).addStatement(methodText)
.returns(TypeName.INT).build();
} catch (final Exception e) {
logger.error("ERROR creating delete method for: " + className + " "
+ e.toString());
}
return null;
}
private MethodSpec createToJSON(String className) {
final String mapperName = getBaseJavaName(className);
final String methodText = "return " + mapperName + "Delegate.toJSON()";
try {
final ClassName cx = ClassName.get("java.lang", "String");
return MethodSpec.methodBuilder("toJSON")
.addJavadoc("Starter StackGen 'JavaGen' Generated Method: "
+ DATE_FORMAT.format(new Date()))
.addModifiers(Modifier.PUBLIC).addStatement(methodText)
.returns(cx).build();
} catch (final Exception e) {
logger.error("ERROR creating toJSON method for: " + className + " "
+ e.toString());
}
return null;
}
private String getMyBatisSQLMapsName(String className) {
return MODEL_DAO_PACKAGE + "."
+ MyBatisGen.getMyBatisModelClassName(className);
}
private String getMyBatisName(String className) {
return MODEL_DAO_PACKAGE + "."
+ MyBatisGen.getMyBatisModelClassName(className);
}
// ## END MYBATIS INSERT/UPDATE/DELETE/LIST
@Override
public synchronized void generate(String className, List fieldList, List getters, List setters) throws IOException, InstantiationException, IllegalAccessException, ClassNotFoundException {
if (className.contains("ModelApi")) {
logger.warn("Encountered non-data class... skipping: " + className);
return;
}
// TODO: cleanup
final int dotpos = className.lastIndexOf(".");
String memberName = className.substring(dotpos + 1);
String memberType = memberName;
memberName += "Delegate";
// add the spring mvc fields
final FieldSpec objectMapper = createObjectMapperField();
final FieldSpec httpServletRequest = createHttpServletRequestField();
// add the builtins
final FieldSpec logr = createLoggerField(className);
// add the MyBatis persistence methods
final FieldSpec ssf = createSQLSessionFactoryField();
// add the MyBatis Search Example Accessor
final FieldSpec mbe = createMyBatisSearchExampleField(className);
final List methodList = new ArrayList<>();
if (ssf != null) {
fieldList.add(logr);
fieldList.add(ssf);
fieldList.add(objectMapper);
fieldList.add(httpServletRequest);
fieldList.add(mbe);
methodList.add(createGetselectByExample(className));
methodList.add(createGetHttpServletRequest(className));
methodList.add(createGetObjectMapper(className));
methodList.add(createGetAcceptHeader(className));
methodList.add(createSetDelegate(className));
methodList.add(createGetDelegate(className));
methodList.add(createList(className));
methodList.add(createLoad(className));
methodList.add(createInsert(className));
methodList.add(createUpdate(className));
methodList.add(createDelete(className));
methodList.add(createToJSON(className));
logger.info("Created " + methodList.size() + " generated methods");
}
// classes, this should point to the top of the package
final URLClassLoader classLoader = new URLClassLoader(
new URL[] { new File(JAVA_GEN_SRC_FOLDER).toURI().toURL(),
new File(JAVA_GEN_RESOURCES_FOLDER).toURI().toURL() });
String delegateInterfaceType = memberType;
delegateInterfaceType = delegateInterfaceType
.substring(delegateInterfaceType.lastIndexOf(".") + 1);
delegateInterfaceType += SPRING_DELEGATE;
ClassName delegateInterfaceClass = ClassName
.get(API_PACKAGE, delegateInterfaceType);
try {
delegateInterfaceType = API_PACKAGE + "." + delegateInterfaceType;
classLoader.loadClass(delegateInterfaceType);
} catch (final Exception x) {
// delegateInterfaceClass = null;
classLoader.close();
throw new IgniteException(
"FATAL: Could not load the delegate class: "
+ delegateInterfaceType);
}
// instantiate the delegate class
final Class cxt = classLoader.loadClass(className);
final FieldSpec member = FieldSpec.builder(cxt, memberName)
.addModifiers(Modifier.PRIVATE).addAnnotation(JSONIgnored)
.initializer("new " + memberType + "()").build();
className = className.substring(dotpos + 1);
className += ADD_GEN_CLASS_NAME;
AnnotationSpec delegateAnnotation = AnnotationSpec
.builder(org.springframework.stereotype.Service.class)
.addMember("value", "$S", getJavaVariableName(className))
.build();
// handle edge case bug where reserved name collides with
// our naming convention based code here
if (className.startsWith("Model")) {
logger.warn("Fixing name of delegate for 'Model' edge case. May break mappings that start with 'Model' ");
delegateAnnotation = AnnotationSpec
.builder(org.springframework.stereotype.Service.class)
.addMember("value", "$S", getJavaVariableName(className
.replace("Model", "")))
.build();
}
// bean constructor
final MethodSpec constructor = MethodSpec.constructorBuilder()
.addModifiers(Modifier.PUBLIC).build();
methodList.add(constructor);
// create the Java Class
final com.squareup.javapoet.TypeSpec.Builder builder = TypeSpec
.classBuilder(className).addModifiers(Modifier.PUBLIC)
.addField(member)
// .superclass(null)
.addJavadoc("Starter StackGen 'JavaGen' Generated Class: "
+ LINE_FEED + DATE_FORMAT.format(new Date()))
.addFields(fieldList).addMethods(setters).addMethods(getters)
.addMethods(methodList);
// finally associate the service class with the delegate
if (delegateInterfaceClass != null) {
builder.addSuperinterface(delegateInterfaceClass);
builder.addAnnotation(delegateAnnotation);
}
JavaFile.builder(IGNITE_MODEL_PACKAGE, builder.build()).build()
.writeTo(JAVA_GEN_SRC);
classLoader.close();
}
private FieldSpec createMyBatisSearchExampleField(String className) throws ClassNotFoundException {
Class cx;
try {
String lnx = getMyBatisName(className);
cx = loadClass(null, lnx + "Example");
} catch (MalformedURLException | InstantiationException
| IllegalAccessException e) {
throw new IgniteException("FAILED TO LINK MyBatis Model");
}
return FieldSpec.builder(cx, "selectByExample")
.addAnnotation(getJSONIgnoreSpec())
.addModifiers(Modifier.PRIVATE).build();
}
private FieldSpec createObjectMapperField() throws ClassNotFoundException {
final Class cx = Class
.forName("com.fasterxml.jackson.databind.ObjectMapper");
return FieldSpec.builder(cx, "objectMapper")
.addAnnotation(getAutoWiredSpec())
.addAnnotation(getJSONIgnoreSpec()).build();
}
private FieldSpec createHttpServletRequestField() throws ClassNotFoundException {
final AnnotationSpec ano = this.getAutoWiredSpec();
final Class cx = Class
.forName("javax.servlet.http.HttpServletRequest");
return FieldSpec.builder(cx, "httpServletRequest").addAnnotation(ano)
.addAnnotation(getJSONIgnoreSpec()).build();
}
String getJavaVariableName(String n) {
if (n.length() < 2) {
return n;
}
n = n.replace(ADD_GEN_CLASS_NAME, "");
final String firstChar = n.substring(0, 1).toLowerCase();
return firstChar + n.substring(1) + SPRING_DELEGATE;
}
String getJavaServiceName(String n) {
if (n.contains(".")) {
n = n.substring(n.lastIndexOf(".") + 1);
}
return n + ADD_GEN_CLASS_NAME;
}
String getMyBatisJavaName(String n) {
return MyBatisGen.getMyBatisModelClassName(n);
}
String getBaseJavaName(String n) {
return MyBatisGen.getBaseJavaName(n);
}
@Override
public String toString() {
return "Java Generator";
}
static void generateClassesFromModelFolder() throws Exception {
logger.info("Iterate MyBatis Entities and create Wrapper Classes...");
final String[] modelFiles = Gen.getModelFileNames();
// this should point to the top of the package structure!
final URLClassLoader classLoader = new URLClassLoader(
new URL[] { new File(JAVA_GEN_SRC_FOLDER).toURI().toURL() });
for (final String mf : modelFiles) {
String cn = mf.substring(0, mf.indexOf("."));
// cn = cn + ".class";
cn = MODEL_PACKAGE + "." + cn;
logger.info("Creating Classes from ModelFile: " + cn);
// try {
final Class loadedClass = classLoader.loadClass(cn);
createClasses(loadedClass);
// } catch (final ClassNotFoundException e) {
// logger.error("cd : " + cn + ": " + e.toString());
// }
}
classLoader.close();
}
/**
* compile all the files in the generated folder(s)
*
* thanks
* to:https://stackoverflow.com/questions/21544446/how-do-you-dynamically-compile-and-load-external-java-classes
*
* @throws IOException
* @throws ClassNotFoundException
* @throws IllegalAccessException
* @throws InstantiationException
*/
static void compile(String packageDir) throws IOException, ClassNotFoundException, InstantiationException, IgniteException, IllegalAccessException {
// test
final String sourcepath = JAVA_GEN_SRC_FOLDER + "/" + packageDir;
logger.info("JavaGen Compiling: " + sourcepath);
// prepare compiler
final DiagnosticCollector diagnostics = new DiagnosticCollector<>();
final JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
final StandardJavaFileManager fileManager = compiler
.getStandardFileManager(diagnostics, null, null);
final Properties p = System.getProperties();
p.getProperty("java.class.path");
final List optionList = new ArrayList<>();
optionList.add("-classpath");
optionList.add(System.getProperty("java.class.path")
+ System.getProperty("path.separator") + JAVA_GEN_SRC_FOLDER
+ System.getProperty("path.separator") + SOURCE_MAIN_JAVA);
final File[] fx = Gen.getJavaFiles(sourcepath, true);
final Iterable compilationUnit = fileManager
.getJavaFileObjectsFromFiles(Arrays.asList(fx));
final JavaCompiler.CompilationTask compilerTask = compiler
.getTask(null, fileManager, diagnostics, optionList, null, compilationUnit);
// Compilation Requirements
logger.info("Compiling: " + sourcepath);
if (compilerTask.call()) {
logger.info("Compilation Complete.");
// load the newly compiled classes this should point to the
// top of the package structure
final URLClassLoader classLoader = new URLClassLoader(new URL[] {
new File(JAVA_GEN_SRC_FOLDER).toURI().toURL(),
new File(JAVA_GEN_RESOURCES_FOLDER).toURI().toURL() });
for (final File f : fx) {
// Load the class from the classloader by name....
String loadClassName = f.getName().replace(".java", "");
loadClassName = packageDir.replace('/', '.') + loadClassName;
if (loadClassName.indexOf(".") == 0)
loadClassName = loadClassName.substring(1); // strip leading
// dot
loadClass(classLoader, loadClassName);
}
classLoader.close();
} else {
for (final Diagnostic diagnostic : diagnostics
.getDiagnostics()) {
String dsrc = "";
try {
dsrc = diagnostic.getSource().toUri().toString();
} catch (final NullPointerException x) {
dsrc = diagnostic.toString(); // ignore
}
if (dsrc != null && (dsrc.contains("Swagger2SpringBoot.java")
|| dsrc.contains("CAL10NAnnotationProcessor"))) {
// EXPECTED!
} else {
try {
dsrc = String
.format("Error on line %d in %s%n: %m", diagnostic
.getLineNumber(), dsrc, diagnostic);
} catch (final Exception e) {
;
}
logger.warn(dsrc);
}
}
}
fileManager.close();
}
/**
* @param classLoader
* @param loadClassName
* @throws IllegalAccessException
* @throws InstantiationException
* @throws Exception
*/
private static Class loadClass(URLClassLoader classLoader, String loadClassName) throws MalformedURLException, InstantiationException, IllegalAccessException {
if (classLoader == null) {
classLoader = new URLClassLoader(new URL[] {
new File(JAVA_GEN_SRC_FOLDER).toURI().toURL(),
new File(JAVA_GEN_RESOURCES_FOLDER).toURI().toURL() });
}
try {
final Class loadedClass = classLoader.loadClass(loadClassName);
// Create a new instance...
if (!loadedClass.isInterface()) {
final Object obj = loadedClass.newInstance();
logger.trace("Successfully compiled class: " + loadClassName); // obj.toString());
} else {
logger.info("Successfully compiled interface: "
+ loadClassName);
}
return loadedClass;
} catch (final InstantiationException nm) {
// normal for no-default constructors
} catch (final ClassNotFoundException e) {
// normal
}
return null;
}
}