/* * 功能描述: * * 版本历史: 2005-11-19 19:16:49 创建1.0.0版 (baixiaoyong) * */ package org.quickbundle.mda.mvm; import java.io.File; import java.io.StringReader; import java.net.MalformedURLException; import java.sql.Timestamp; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.io.SAXReader; import org.eclipse.core.runtime.FileLocator; import org.eclipse.core.runtime.IProgressMonitor; import org.quickbundle.mda.RmTransform; import org.quickbundle.tools.helper.RmStringHelper; import org.quickbundle.tools.helper.io.RmFileHelper; import org.quickbundle.tools.helper.xml.RmXmlHelper; /** * @author 白小勇 */ public class CodegenEngine { public final static String FILE_CONCAT = "/"; /** * mainRule 表示: 规则Document */ private Document mainRule = null; /** * baseXsltSourcePath 表示: xslt文件的路径, 一般在插件安装目录下 */ private String templatePath = null; /** * baseProjectPath 表示: 生成的目标项目路径,可能在任何目录 */ private String baseProjectPath = null; /** * quickbundleHome 表示: 可能随时改变的rule.xml路径,一般在临时目录下 */ private String quickbundleHome = null; private Document mvmDoc = null; /** * 构造函数: * * @param ruleXml * @param codegenConfig */ public CodegenEngine(String ruleXml) { try { this.quickbundleHome = new File(RmXmlHelper.formatToFile(ruleXml)).getParent(); this.mainRule = RmXmlHelper.parse(ruleXml); //初始化java路径 this.templatePath = RmXmlHelper.formatToUrl(FileLocator.toFileURL(this.getClass().getClassLoader().getResource("template")).toString()); this.baseProjectPath = RmXmlHelper.formatToUrl(mainRule.getRootElement().valueOf("//rules/codegen//@baseProjectPath")); String codegenConfig = mainRule.valueOf("/rules/codegen/mvms/mvm[contextName=../@contextName]/@codegenConfig"); if(codegenConfig == null || codegenConfig.length() == 0) { codegenConfig = mainRule.valueOf("/rules/codegen/mvms/mvm[1]/codegenConfig"); } this.mvmDoc = RmXmlHelper.parse(this.templatePath + "/" + codegenConfig); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(e); } } private String getFilterTableName(String currentTableXmlPath) { String filterTableName = ""; currentTableXmlPath = RmXmlHelper.formatToUrl(currentTableXmlPath); try { String finalTemplatePath = templatePath + "buildFilterTableName.xsl"; String result = RmTransform.getStringFromTransform(finalTemplatePath, currentTableXmlPath); Document tempResultsDoc = new SAXReader().read(new StringReader(result)); filterTableName = tempResultsDoc.valueOf("/results/result[position()=1]/@tableFormatNameUpperFirst"); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(e); } return filterTableName; } @SuppressWarnings("unchecked") public Object[] generateFiles(IProgressMonitor monitor) throws DocumentException, MalformedURLException { Object[] aObj = new Object[2]; int index = 0; //统计文件数 StringBuilder returnLog = new StringBuilder(); List<Element> lTableXmls = mainRule.selectNodes("/rules/database/tableTos/tableTo"); if(monitor != null) { monitor.beginTask("begin generate code......", mvmDoc.selectNodes(".//file").size() * lTableXmls.size()); } for (Element thisTableTo : lTableXmls) { int result = doGenerate(monitor, thisTableTo, returnLog); index += result; } log(returnLog.toString()); aObj[0] = String.valueOf(index); aObj[1] = returnLog; return aObj; } @SuppressWarnings("unchecked") private int doGenerate(IProgressMonitor monitor, Element thisTableTo, StringBuilder returnLog) throws MalformedURLException, DocumentException { int result = 0; String toTableNameKeyword = mainRule.valueOf("/rules/codegen/@toTableNameKeyword"); String originalTableName = thisTableTo.getText(); String currentTableXmlPath = RmXmlHelper.formatToUrl(quickbundleHome + FILE_CONCAT + thisTableTo.valueOf("@xmlName")); Document docCurrentTable = RmXmlHelper.parse(currentTableXmlPath); String filterTableName = getFilterTableName(currentTableXmlPath); String tableDirName = docCurrentTable.valueOf("/meta/tables/table[1]/@tableDirName"); List<Element> lFile = mvmDoc.selectNodes(".//file"); for (Element eleFile : lFile) { //取出当前rule的组件编码 String bundleCode = eleFile.valueOf("@bundleCode"); if(bundleCode != null && bundleCode.length() > 0 && docCurrentTable != null) { String customBundleCode = docCurrentTable.valueOf("/meta/tables/table[@tableName='" + originalTableName + "']/@customBundleCode"); //如果定制编码不包含当前rule的组件编码,跳过 if(!customBundleCode.matches("^[\\w,]*" + bundleCode + "[\\w,]*$")) { continue; } } //得到当前这组的基本路径 String outPutPath = getOutPutPath(eleFile); //得到最终路径 String xsltPath = templatePath + eleFile.valueOf("@xsltPath"); String outputFile = eleFile.valueOf("@outputFile"); outputFile = fillUpOutput(outputFile, toTableNameKeyword, eleFile, filterTableName, tableDirName, outPutPath); String afterKeyWord = eleFile.valueOf("@afterKeyWord"); if (afterKeyWord.length() == 0) { //java和jsp文件 if("true".equals(eleFile.valueOf("@result-document"))) { String outputFolder = eleFile.valueOf("@outputFolder"); outputFolder = fillUpOutput(outputFolder, toTableNameKeyword, eleFile, filterTableName, tableDirName, outPutPath); if("".equals(eleFile.valueOf("@outputFile"))) { TemplateHelper.outPutFile4ResultDocument(xsltPath, currentTableXmlPath, outputFolder); } else { if("".equals(eleFile.valueOf("@outputFolder"))) { outputFolder = new File(RmFileHelper.formatToFile(outputFile)).getParent(); } TemplateHelper.outPutFile4ResultDocument(xsltPath, currentTableXmlPath, outputFolder, outputFile); } } else { TemplateHelper.outPutFile(xsltPath, currentTableXmlPath, outputFile); } } else { //配置文件 TemplateHelper.outPutFile(xsltPath, currentTableXmlPath, outputFile, afterKeyWord, "true".equals(eleFile.valueOf("@rowIsUnique"))); } returnLog.append("\r\nxslt = ") .append(RmFileHelper.formatToFile(xsltPath)) .append("\r\nmetaXml = ") .append(RmFileHelper.formatToFile(currentTableXmlPath)) .append("\r\noutput=") .append(RmFileHelper.formatToFile(outputFile)); if(afterKeyWord != null && afterKeyWord.length() > 0) { returnLog.append("\r\nposition = ") .append(afterKeyWord); } returnLog.append("\r\n"); result++; if(monitor != null) { monitor.worked(1); String displayOutputFile = RmXmlHelper.formatToUrlNoPrefix(outputFile); String tempStr = displayOutputFile; if(displayOutputFile.length() > 140) { tempStr = displayOutputFile.substring(0,12) + "..." + displayOutputFile.substring(displayOutputFile.length()-125); } monitor.setTaskName(tempStr); } } return result; } private String fillUpOutput(String output, String toTableNameKeyword, Element eleFile, String filterTableName, String tableDirName, String baseTargetPath) { StringBuilder result = new StringBuilder(); if (toTableNameKeyword != null && toTableNameKeyword.length() > 0) { //把TableName替换成表名 output = RmStringHelper.replaceFirst(output, toTableNameKeyword, filterTableName); } if ("java".equals(eleFile.valueOf("../@filesType")) || "jsp".equals(eleFile.valueOf("../@filesType"))) { output = tableDirName + FILE_CONCAT + output; } else if ("config".equals(eleFile.valueOf("../@filesType"))) { } result.append(baseProjectPath) .append(FILE_CONCAT) .append(baseTargetPath) .append(FILE_CONCAT) .append(output); return result.toString(); } private String getOutPutPath(Element eleFile) { String outputPath = eleFile.valueOf("../@outputPath"); if(outputPath == null || outputPath.trim().length() == 0) { return ""; } StringBuffer result = new StringBuffer(); Pattern pData = Pattern.compile("\\$\\{(.*?)\\}"); Matcher mData = pData.matcher(outputPath); while(mData.find()) { //在循环中找出{}的表达式 String exp = mData.toMatchResult().group(1); //处理表达式,添加到结果 mData.appendReplacement(result, mainRule.valueOf("/rules/project/" + exp)); } mData.appendTail(result); return result.toString(); } /** * 功能: 写入日志 * * @param traceMessage */ public void log(String traceMessage) { System.out.println("\n" + new Timestamp(System.currentTimeMillis()) + ": " + traceMessage); } /** * 功能: java -jar ranminXmlGenerateCode.jar C:\Docume~1\Administrator\LocalS~1\Temp\ranminXmlGenerateCode\rule***.xml * * @param args */ public static void main(String[] args) { long t = System.currentTimeMillis(); String rulesXmlPath = null; String baseXsltSourcePath = null; if (args != null && args.length >= 1) { rulesXmlPath = args[0]; File tempFile = new File(rulesXmlPath); baseXsltSourcePath = tempFile.getParent() + "\\"; System.out.println(baseXsltSourcePath); } else { System.out.println("usage: java -jar ranminXmlGenerateCode.jar rulesXmlPath!"); return; } try { CodegenEngine ce = new CodegenEngine(rulesXmlPath); Object[] rtObj = ce.generateFiles(null); System.out.println("一共生成了" + String.valueOf(rtObj[0]) + "个文件!"); } catch (Exception e) { e.printStackTrace(); } t = System.currentTimeMillis() - t; System.out.println("耗时" + t / 1000 + "秒!"); } }