mpk
dengzedong
2024-09-12 449017535241b56997db62daa8935a6db5bef44a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
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<String> getTemplates(){
        List<String> templates = new ArrayList<String>();
        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<String, Object> 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<String> 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<String, Object> 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<String, Object> 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);
    }
}