package com.iailab.module.model.mpk.common.utils; import cn.hutool.core.io.FileUtil; import com.iailab.module.model.mpk.common.MdkConstant; import com.iailab.module.model.mpk.dto.MpkFileDTO; import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.Velocity; import java.io.File; import java.io.IOException; import java.io.OutputStream; import java.io.StringWriter; import java.nio.file.Files; import java.util.*; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; @Slf4j public class GenUtils { public static List getTemplates(){ List templates = new ArrayList(); templates.add("abstract.java.vm"); templates.add("impl.java.vm"); templates.add("cpp.vm"); templates.add("Jni.cpp.vm"); templates.add("h.vm"); templates.add("Jni.h.vm"); return templates; } /** * 生成代码 */ public static void generatorCode(MpkFileDTO entity, ZipOutputStream zip){ //设置velocity资源加载器 Properties prop = new Properties(); prop.put("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"); Velocity.init(prop); //封装模板数据 Map map = new HashMap<>(); map.put("pkgName",entity.getPkgName()); map.put("modelMethods",entity.getModelMethods()); map.put("pyName",entity.getPyName()); map.put("pyModule",entity.getPyModule()); VelocityContext context = new VelocityContext(map); //获取模板列表 List templates = getTemplates(); for(String template : templates){ //渲染模板 StringWriter sw = drawTemplate(template,context); try { //添加到zip zip.putNextEntry(new ZipEntry(getFileName(template, entity.getPyName(),entity.getPkgName(),entity.getPyModule()))); IOUtils.write(sw.toString(), zip, "UTF-8"); IOUtils.closeQuietly(sw); zip.closeEntry(); if (template.equals("cpp.vm")) { File dirPath = new File("C:/DLUT/tmp/"); if (!dirPath.exists()) { dirPath.mkdirs(); } // 生成临时cpp文件 File cppFile = new File(dirPath.getAbsolutePath() + File.separator + entity.getPyName() + ".cpp"); cppFile.createNewFile(); OutputStream cppOutputStream = Files.newOutputStream(cppFile.toPath()); IOUtils.write(sw.toString(), cppOutputStream, "UTF-8"); IOUtils.closeQuietly(cppOutputStream); } if (template.equals("Jni.cpp.vm")) { File dirPath = new File("C:/DLUT/tmp/"); if (!dirPath.exists()) { dirPath.mkdirs(); } // 生成临时Jni.cpp文件 File cppFile = new File(dirPath.getAbsolutePath() + File.separator + entity.getPyName() + ".cpp"); File jniCppFile = new File(dirPath.getAbsolutePath() + File.separator + entity.getPyName() + "Jni.cpp"); jniCppFile.createNewFile(); OutputStream jniCppOutputStream = Files.newOutputStream(jniCppFile.toPath()); IOUtils.write(sw.toString(), jniCppOutputStream, "UTF-8"); IOUtils.closeQuietly(jniCppOutputStream); try { // 根据file 通过cmd命令 生成dll String dllSavePath = dirPath.getAbsolutePath() + File.separator + entity.getPyName() + ".dll"; String cppFilePath = cppFile.getAbsolutePath(); String jniCppFilePath = jniCppFile.getAbsolutePath(); // String command = "cmd.exe /c cl -o " + dllSavePath + " /LD " + jniCppFilePath + " " + cppFilePath; String command = "cmd.exe /c cl -o " + dllSavePath + " /LD D:\\work\\mdk\\code\\makeDll\\src\\main\\java\\org\\example\\MakeDll.c D:\\work\\mdk\\code\\makeDll\\src\\main\\java\\org\\example\\MakeDll2.c"; Process process = Runtime.getRuntime().exec(command); // 等待命令执行完成 process.waitFor(); File dllFile = new File(dllSavePath); //添加到zip zip.putNextEntry(new ZipEntry("dll" + File.separator + entity.getPyName() + ".dll")); IOUtils.write(FileUtils.readFileToByteArray(dllFile), zip); zip.closeEntry(); FileUtils.deleteDirectory(dirPath); } catch (InterruptedException e) { log.error("DLL生成失败" + entity.getPyName(), e); throw new RuntimeException(e); } } } catch (IOException e) { log.error("渲染模板失败,模型名称:" + entity.getPyName(), e); throw new RuntimeException("渲染模板失败,模型名称:" + entity.getPyName(), e); } } } /** * 获取文件名 */ public static String getFileName(String template, String moduleName, String pkgName, String pyModule) { // java if (template.equals("abstract.java.vm")) { return pkgName.replace(".", File.separator) + File.separator + moduleName + ".java"; } if (template.equals("impl.java.vm")) { return pkgName.replace(".", File.separator) + File.separator + MdkConstant.IMPL + File.separator + moduleName + "Impl.java"; } // c++ if (template.equals("cpp.vm")) { return pyModule.replace(".", File.separator) + File.separator + moduleName + ".cpp"; } if (template.equals("h.vm")) { return pyModule.replace(".", File.separator) + File.separator + moduleName + ".h"; } // Jni c++ if (template.equals("Jni.cpp.vm")) { return pyModule.replace(".", File.separator) + File.separator + MdkConstant.JNI + File.separator + moduleName + "Jni.cpp"; } if (template.equals("Jni.h.vm")) { return pyModule.replace(".", File.separator) + File.separator + MdkConstant.JNI + File.separator + moduleName + "Jni.h"; } return null; } /** * 渲染模板 **/ public static StringWriter drawTemplate(String template,Map map) { //模板数据 VelocityContext context = new VelocityContext(map); return drawTemplate(template,context); } public static StringWriter drawTemplate(String template,VelocityContext context) { Properties prop = new Properties(); prop.put("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"); Velocity.init(prop); StringWriter writer = new StringWriter(); Template tpl = Velocity.getTemplate("template/" + template, "UTF-8"); tpl.merge(context, writer); return writer; } public static void drawTemplate(String template,Map map,File toFile) throws IOException { VelocityContext context = new VelocityContext(map); drawTemplate(template,context,toFile); } public static void drawTemplate(String template,VelocityContext context,File toFile) throws IOException { StringWriter writer = drawTemplate(template,context); FileUtil.mkParentDirs(toFile); if (!toFile.exists()) { toFile.createNewFile(); } FileUtil.writeUtf8String(writer.toString(),toFile); } }