/* * souche.com * Copyright (C) 2013-2019 All Rights Reserved. */ package com.uifuture.maven.plugins; import com.thoughtworks.qdox.model.JavaClass; import com.thoughtworks.qdox.model.JavaMethod; import com.uifuture.maven.plugins.core.build.BuildClass; import com.uifuture.maven.plugins.core.common.BaseConstant; import com.uifuture.maven.plugins.core.common.ConfigConstant; import com.uifuture.maven.plugins.core.dto.JavaClassDTO; import com.uifuture.maven.plugins.core.util.StringUtil; import com.uifuture.maven.plugins.core.util.UUIDUtil; import freemarker.template.Configuration; import freemarker.template.TemplateException; import freemarker.template.TemplateExceptionHandler; import org.apache.maven.plugin.logging.Log; import org.apache.maven.plugin.logging.SystemStreamLog; import java.io.BufferedReader; import java.io.File; import java.io.FileOutputStream; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.PrintStream; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; /** * @author chenhx * @version GenJava.java, v 0.1 2019-06-24 16:47 chenhx */ public class GenJava { private static Log log = new SystemStreamLog(); /** * 开始生成测试类入口 * @param javaName 当前需要生成测试类的类全限定名称 */ public static void genTest(String javaName) { try { //类名 String className = javaName.substring(javaName.lastIndexOf("/") + 1, javaName.lastIndexOf(".")); //设置配置文件 Configuration cfg = getConfiguration(); String testJavaName = ConfigConstant.CONFIG_ENTITY.getBasedir() + BaseConstant.JAVA_TEST_SRC + ConfigConstant.CONFIG_ENTITY.getTestPackageName().replace(".", "/") + "/" + className + "Test.java"; log.info("生成的文件路径:" + testJavaName + ", className:" + className); //已经生成的测试类的方法名称 Set<String> testMethodNameSet = new HashSet<>(); boolean fileIsExists = false; File file = new File(testJavaName); //已经存在文件 if (file.exists()) { log.info(file + "已经存在,进行类方法追加生成"); //获取当前测试的类信息 String testClassName = ConfigConstant.CONFIG_ENTITY.getTestPackageName() + "." + className + "Test"; JavaClass testJavaClass = BaseConstant.javaProjectBuilder.getClassByName(testClassName); //遍历方法 List<JavaMethod> javaMethodList = testJavaClass.getMethods(); for (JavaMethod javaMethod : javaMethodList) { testMethodNameSet.add(javaMethod.getName()); log.info("获取测试类的方法名称:" + javaMethod.getName()); } log.info("获取的已经生成的类方法名称为:" + javaMethodList + ",测试类:" + testClassName); fileIsExists = true; } else { if (!file.getParentFile().exists() && !file.getParentFile().mkdirs()) { log.error(file.getParentFile() + "生成失败"); return; } } JavaClassDTO javaClassDTO = new JavaClassDTO(); javaClassDTO.setDate(BaseConstant.DATE); javaClassDTO.setAuthor(ConfigConstant.CONFIG_ENTITY.getAuthor()); javaClassDTO.setModelNameUpperCamel(className); javaClassDTO.setModelNameLowerCamel(StringUtil.strConvertLowerCamel(className)); javaClassDTO.setModelNameUpperCamelTestClass(className + "Test"); javaClassDTO.setModelNameLowerCamelTestClass(StringUtil.strConvertLowerCamel(className + "Test")); //获取类中方法 if(!BuildClass.build(ConfigConstant.CONFIG_ENTITY.getTestPackageName() + "." + className,javaClassDTO)){ return; } Map<String, Object> data = new HashMap<>(2); data.put("javaClassDTO", javaClassDTO); //获取mock的类 if (!fileIsExists) { cfg.getTemplate(ConfigConstant.CONFIG_ENTITY.getConfigFileName()).process(data, new FileWriter(file)); log.info(file + "生成成功"); } else { File newFile = fileIsExists(className, cfg, testMethodNameSet, file, javaClassDTO, data); if (newFile == null) { log.error("追加方法失败"); return; } log.info(file + ", 追加方法成功,生成的临时文件:" + newFile); } } catch (Exception e) { log.error("生成失败,出现异常", e); } } /** * 文件存在时,进行追加生成的方法 * * @param className 类名 * @param configuration Template模板生成文件 * @param testMethodNameSet 已有测试方法的名称 * @param file 原有已生成的文件 * @param javaClassDTO 生成的临时文件信息 * @param data 模板的数据 * @return 临时生成的文件 * @throws TemplateException 模板异常 * @throws IOException 流异常 */ private static File fileIsExists(String className, Configuration configuration, Set<String> testMethodNameSet, File file, JavaClassDTO javaClassDTO, Map<String, Object> data) throws TemplateException, IOException { String testJavaName;//测试类已经存在了 String randId = UUIDUtil.getID(); testJavaName = ConfigConstant.CONFIG_ENTITY.getBasedir() + BaseConstant.JAVA_TEST_SRC + ConfigConstant.CONFIG_ENTITY.getTestPackageName().replace(".", "/") + "/" + className + randId + "Test.java"; javaClassDTO.setModelNameUpperCamelTestClass(className + randId + "Test"); javaClassDTO.setModelNameLowerCamelTestClass(StringUtil.strConvertLowerCamel(className + randId + "Test")); File newFile = new File(testJavaName); if (!newFile.getParentFile().exists() && !newFile.getParentFile().mkdirs()) { log.error(newFile.getParentFile() + "生成失败,请检查是否有权限"); return null; } configuration.getTemplate(ConfigConstant.CONFIG_ENTITY.getConfigFileName()).process(data, new FileWriter(newFile)); //读取类的方法 String newClassName = ConfigConstant.CONFIG_ENTITY.getTestPackageName() + "." + className + randId + "Test"; log.info("获取临时生成的类名:" + newClassName); //读取包下所有的测试的java类文件 BaseConstant.javaProjectBuilder.addSourceTree(newFile); JavaClass testJavaClass = BaseConstant.javaProjectBuilder.getClassByName(newClassName); List<JavaMethod> javaMethodList = testJavaClass.getMethods(); log.info("获取的方法名称:" + javaMethodList); for (JavaMethod javaMethod : javaMethodList) { if (!testMethodNameSet.contains(javaMethod.getName())) { //新增的方法 - 测试方法的源码 String code = javaMethod.getSourceCode(); log.debug("获取追加的方法源码为:" + code); //原来的文件进行追加方法 String methodStr = "\n @Test\n" + " public void " + javaMethod.getName() + "(){\n" + code + "\n" + " }\n}"; //文件追加 FileReader fileReader = new FileReader(file); BufferedReader br = new BufferedReader(fileReader); String lineContent = null; List<String> oldFileStr = new ArrayList<>(); while ((lineContent = br.readLine()) != null) { oldFileStr.add(lineContent); } br.close(); fileReader.close(); //文件覆盖 for (int i = oldFileStr.size() - 1; i >= 0; i--) { String line = oldFileStr.get(i).trim(); if (StringUtil.isEmpty(line)) { continue; } if ("}".equals(line)) { //删除该行 oldFileStr.remove(i); break; } if (line.endsWith("}")) { //删除该行最后一个}字符 oldFileStr.set(i, oldFileStr.get(i).substring(0, oldFileStr.get(i).lastIndexOf("}"))); break; } } StringBuilder fileStr = new StringBuilder(); //覆盖保存文件 for (String line : oldFileStr) { fileStr.append(line).append("\n"); } fileStr.append(methodStr); //写入文件 PrintStream ps = new PrintStream(new FileOutputStream(file)); // 往文件里写入字符串 ps.println(fileStr); ps.close(); } log.info("获取临时测试类的方法名称:" + javaMethod.getName()); } //删除文件 if (!newFile.delete()) { log.error("删除临时文件失败,请检查是否有权限。文件:" + newFile); } return newFile; } private static Configuration getConfiguration() throws IOException { Configuration cfg = new Configuration(Configuration.VERSION_2_3_28); ConfigConstant.CONFIG_ENTITY.setConfigPath(StringUtil.addSeparator(ConfigConstant.CONFIG_ENTITY.getConfigPath())); File file = new File(ConfigConstant.CONFIG_ENTITY.getBasedir() + ConfigConstant.CONFIG_ENTITY.getConfigPath()); if (!file.exists()) { log.error(file + "配置文件不存在"); throw new RuntimeException("配置文件不存在"); } cfg.setDirectoryForTemplateLoading(file); cfg.setDefaultEncoding("UTF-8"); cfg.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER); return cfg; } }