package org.quickbundle.mda.gc; import java.math.BigDecimal; import java.sql.Connection; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.regex.MatchResult; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.dom4j.Document; import org.dom4j.DocumentHelper; import org.dom4j.Element; import org.quickbundle.tools.helper.RmStringHelper; import org.quickbundle.tools.helper.xml.RmXmlHelper; public class MetadataHelper { /** * 从rule.xml中读配置,取出table_name表的元数据 * @param myConn * @param catalog * @param schemaPattern * @param table_name * @param docRules * @param pdmParser * @return * @throws Exception */ public static Document getMetaDataXml(Connection myConn, String catalog, String schemaPattern, String table_name, Document docRules, PdmParser pdmParser) throws Exception { Document doc = DocumentHelper.createDocument(); Element meta = doc.addElement("meta"); Element project = meta.addElement("project"); Element database = meta.addElement("database"); Element relations = meta.addElement("relations"); Element tables = meta.addElement("tables"); initDatabase(database, myConn, catalog, schemaPattern, table_name, docRules, pdmParser); initProject(project, myConn, catalog, schemaPattern, table_name, docRules, pdmParser); Element table = tables.addElement("table"); initTable(table, myConn, catalog, schemaPattern, table_name, docRules, pdmParser); return doc; } private static void initTable(Element table, Connection myConn, String catalog, String schemaPattern, String table_name, Document docRules, PdmParser pdmParser) throws SQLException { table.addAttribute("tableName", table_name); if (pdmParser != null && pdmParser.getMPdmColumn() != null && pdmParser.getMPdmColumn().containsKey(table_name)) { String[] aColumnInfo = (String[]) pdmParser.getMPdmColumn().get(table_name); table.addAttribute("tableNameDisplay", aColumnInfo[0]); table.addAttribute("comment", aColumnInfo[1]); table.addAttribute("attachedRules", aColumnInfo[2]); } else { table.addAttribute("tableNameDisplay", table_name); table.addAttribute("comment", ""); table.addAttribute("attachedRules", ""); } table.addAttribute("tableFilterKeyword", getFormatTableName(table_name)); table.addAttribute("tableDirName", getFormatTableName(table_name).toLowerCase()); table.addAttribute("tablePk", ""); table.addAttribute("statisticColumn", ""); table.addAttribute("keyColumn", ""); String firstCatalog_schema_tableName = null; // 定义第一个遇到的表名 // 设置table注释 ResultSet rsTableComment = myConn.getMetaData().getTables(catalog, schemaPattern, table_name, null); while (rsTableComment.next()) { String currentCatalog_schema_tableName = rsTableComment.getString(1) + rsTableComment.getString(2) + rsTableComment.getString(3); if (firstCatalog_schema_tableName == null) { firstCatalog_schema_tableName = currentCatalog_schema_tableName; } else if (currentCatalog_schema_tableName.equals(firstCatalog_schema_tableName)) { } else { // 如果这次取到的表空间不等于上次,则弃之 // QbXmlGenerateCodePlugin.log("在这次生成代码的会话中," + table_name + // "表在不同的catalog或schema中出现多次!"); continue; } table.addAttribute("tableComment", RmStringHelper.prt(rsTableComment.getString(5))); } // 设置每列属性 ResultSet rsColumns = myConn.getMetaData().getColumns(catalog, schemaPattern, table_name, null); while (rsColumns.next()) { String currentCatalog_schema_tableName = rsColumns.getString(1) + rsColumns.getString(2) + rsColumns.getString(3); if (firstCatalog_schema_tableName == null) { firstCatalog_schema_tableName = currentCatalog_schema_tableName; } else if (currentCatalog_schema_tableName.equals(firstCatalog_schema_tableName)) { } else { // 如果这次取到的表空间不等于上次,则弃之 continue; } Element elementColumn = table.addElement("column"); elementColumn.addAttribute("columnName", RmStringHelper.prt(rsColumns.getString(4))); String tempColumnName = rsColumns.getString(4); String tempColumnNameDisplay = RmStringHelper.prt(rsColumns.getString(4)).toLowerCase(); String tempComment = RmStringHelper.prt(rsColumns.getString(12)); String tempAttachedRules = ""; if (pdmParser != null && pdmParser.getMPdmColumn() != null && pdmParser.getMPdmColumn().containsKey(table_name + ":" + tempColumnName)) { String[] aColumnInfo = (String[]) pdmParser.getMPdmColumn().get(table_name + ":" + tempColumnName); tempColumnNameDisplay = aColumnInfo[0]; if (aColumnInfo[1] != null && aColumnInfo[1].trim().length() > 0) { tempComment = aColumnInfo[1]; } tempAttachedRules = aColumnInfo[2]; } elementColumn.addAttribute("columnNameDisplay", tempColumnNameDisplay); // 临时 elementColumn.addAttribute("dataType", RmStringHelper.prt(rsColumns.getString(5))); elementColumn.addAttribute("isBuild", "true"); // 临时 elementColumn.addAttribute("isBuild_list", "true"); // 临时 elementColumn.addAttribute("filterKeyword", ""); elementColumn.addAttribute("filterType", "default"); // 临时 elementColumn.addAttribute("maxLength", RmStringHelper.prt(rsColumns.getString(7))); elementColumn.addAttribute("decimalDigits", RmStringHelper.prt(rsColumns.getString(9))); elementColumn.addAttribute("comment", tempComment); elementColumn.addAttribute("dataTypeDb", RmStringHelper.prt(rsColumns.getString(6))); String defaultValue = RmStringHelper.prt(rsColumns.getString(13)); if (defaultValue != null) { defaultValue = defaultValue.trim(); if (defaultValue.matches("^\\s*'.*'\\s*$")) { defaultValue = defaultValue.replaceAll("^\\s*'(.*)'\\s*$", "$1"); } } elementColumn.addAttribute("defaultValue", RmStringHelper.prt(defaultValue)); elementColumn.addAttribute("nullable", RmStringHelper.prt(rsColumns.getString(18))); String[] aStr = getHumanCodeTypeData(tempComment); elementColumn.addAttribute("humanDisplayType", aStr[0]); elementColumn.addAttribute("humanDisplayTypeKeyword", aStr[1]); elementColumn.addAttribute("humanDisplayTypeData", aStr[2]); elementColumn.addAttribute("attachedRules", tempAttachedRules); } { // get pk ResultSet rsPk = myConn.getMetaData().getPrimaryKeys(null, null, table_name); String pkStr = ""; while (rsPk.next()) { String currentCatalog_schema_tableName = rsPk.getString(1) + rsPk.getString(2) + rsPk.getString(3); if (firstCatalog_schema_tableName == null) { firstCatalog_schema_tableName = currentCatalog_schema_tableName; } else if (currentCatalog_schema_tableName.equals(firstCatalog_schema_tableName)) { } else { // 如果这次取到的表空间不等于上次,则弃之 continue; } if (!"".equals(pkStr)) { pkStr += ","; } pkStr += rsPk.getString(4); } /* * 显示到外边,小地雷 if (pkStr.indexOf(",") > 0) { throw new * Exception("暂不支持生成复合主键的单表"); } if (pkStr.length() == 0) { throw * new Exception("暂不支持生成没有任何主键的单表"); } */ table.addAttribute("tablePk", pkStr); // 主键默认不生成 if (table.selectSingleNode("column[@columnName='" + pkStr + "']/@isBuild") != null) { table.selectSingleNode("column[@columnName='" + pkStr + "']/@isBuild").setText("false"); table.selectSingleNode("column[@columnName='" + pkStr + "']/@isBuild_list").setText("false"); } } Map<String, String> mFk_parentTablename = new HashMap<String, String>(); { // TODO get fk // String parentTableName = ""; String statisticColumn = ""; String firstCatalog_schema_tableName_fk = null; // 定义第一个遇到的表名 ResultSet rsFk = myConn.getMetaData().getImportedKeys(catalog, schemaPattern, table_name); if (!rsFk.next()) { rsFk = myConn.getMetaData().getImportedKeys(catalog, schemaPattern, table_name.toLowerCase()); } else { rsFk = myConn.getMetaData().getImportedKeys(catalog, schemaPattern, table_name); } while (rsFk.next()) { String currentCatalog_schema_tableName = rsFk.getString(5) + rsFk.getString(6) + rsFk.getString(7); if (firstCatalog_schema_tableName_fk == null) { firstCatalog_schema_tableName_fk = currentCatalog_schema_tableName; } else if (currentCatalog_schema_tableName.equals(firstCatalog_schema_tableName_fk)) { } else { // 如果这次取到的表空间不等于上次,则弃之 continue; } if (!"".equals(statisticColumn)) { statisticColumn += ","; } mFk_parentTablename.put(rsFk.getString(8), rsFk.getString(3)); statisticColumn += rsFk.getString(8); break; // 重要!只取第一个统计列 } if ("".equals(statisticColumn)) { // 默认等于主键 statisticColumn = table.attributeValue("tablePk"); } table.addAttribute("statisticColumn", statisticColumn); } { // 初始化关键列 table.addAttribute("keyColumn", table.attributeValue("tablePk")); // 让关键列默认等于pk List<Element> lEleColumn = table.selectNodes("column"); String keyColumnMatch = docRules.valueOf("/rules/profileConfig/keyColumnMatch/text()"); Pattern pKeyColumn = Pattern.compile(keyColumnMatch, Pattern.DOTALL | Pattern.CASE_INSENSITIVE); for (Element eleColumn : lEleColumn) { if (pKeyColumn.matcher(eleColumn.valueOf("@columnName")).find()) { // 如果有NAME或TITLE,赋值给关键列 table.addAttribute("keyColumn", eleColumn.valueOf("@columnName")); } } } ResultSetMetaData rsColumns4JavaDataType = myConn.prepareStatement("SELECT * FROM " + table_name).executeQuery().getMetaData(); for (int i = 1; i <= rsColumns4JavaDataType.getColumnCount(); i++) { String columnName = rsColumns4JavaDataType.getColumnName(i); Element column = (Element) table.selectSingleNode("column[@columnName='" + columnName + "']"); column.addAttribute("dataType", rsColumns4JavaDataType.getColumnClassName(i)); {// 针对number(19),将其强制转化为Long if ((BigDecimal.class.getName().equals(column.valueOf("@dataType")) || Long.class.getName().equals(column.valueOf("@dataType"))) && "19".equals(column.valueOf("@maxLength")) && "0".equals(column.valueOf("@decimalDigits"))) { column.addAttribute("dataType", "java.lang.Long"); } } } // 把外键一律定义为rm.listReference for (Iterator<String> itMFk_ptn = mFk_parentTablename.keySet().iterator(); itMFk_ptn.hasNext();) { String fk = itMFk_ptn.next().toString(); if (table.selectSingleNode("column[@columnName='" + fk + "']") != null) { Element eleFk = (Element) table.selectSingleNode("column[@columnName='" + fk + "']"); eleFk.addAttribute("humanDisplayType", "rm.listReference"); eleFk.addAttribute("humanDisplayTypeKeyword", getFormatTableName(mFk_parentTablename.get(fk).toString()).toLowerCase()); eleFk.addAttribute("humanDisplayTypeData", ""); } } { // 初始化默认勾选的组件 Set<String> sBundleCode = new HashSet<String>(); if (!table.valueOf("@statisticColumn").equals(table.valueOf("@tablePk"))) { sBundleCode.add("condition"); } List<Element> lBundle = docRules.selectNodes("/rules/customBundleCode/bundle"); for (Element bundle : lBundle) { if ("true".equals(bundle.valueOf("@checked"))) { sBundleCode.add(bundle.valueOf("@code")); } else if ("false".equals(bundle.valueOf("@checked"))) { sBundleCode.remove(bundle.valueOf("@code")); } } StringBuilder sbCustomBundleCode = new StringBuilder(); for (String code : sBundleCode) { if (sbCustomBundleCode.length() > 0) { sbCustomBundleCode.append(","); } sbCustomBundleCode.append(code); } table.addAttribute("customBundleCode", sbCustomBundleCode.toString()); } } private static void initDatabase(Element database, Connection myConn, String catalog, String schemaPattern, String table_name, Document docRules, PdmParser pdmParser) throws SQLException { database.addElement("driver").setText(docRules.valueOf("/rules/database/@driver")); database.addElement("url").setText(docRules.valueOf("/rules/database/@url")); database.addElement("userName").setText(docRules.valueOf("/rules/database/@userName")); database.addElement("password").setText(docRules.valueOf("/rules/database/@password")); database.addElement("dbProductName").setText(myConn.getMetaData().getDatabaseProductName()); } private static void initProject(Element project, Connection myConn, String catalog, String schemaPattern, String table_name, Document docRules, PdmParser pdmParser) { RmXmlHelper.deepCopyElementWithClear((Element)docRules.selectSingleNode("/rules/project"), project); } /** * 功能: 获得Java规范后的表名 * * @param table_name * @return */ public static String getFormatTableName(String table_name) { if (table_name == null || table_name.length() == 0) { return table_name; } String str = ""; String[] aName = table_name.split("_"); for (int i = 0; i < aName.length; i++) { str += toUpperFirst(aName[i]); } return str; } private static String toUpperFirst(String str) { if (str == null || str.length() == 0) { return str; } else { return str.substring(0, 1).toUpperCase() + str.substring(1).toLowerCase(); } } public static String[] getTableNames(Connection conn) throws SQLException { List<String> lTableName = new ArrayList<String>(); ResultSet rsTable = conn.getMetaData().getTables("", "", "", new String[] { "TABLE" }); while (rsTable.next()) { lTableName.add(rsTable.getString(3)); } return lTableName.toArray(new String[0]); } private static String[] getHumanCodeTypeData(String comment) { String[] aStr = new String[] { "default", "", "" }; try { Pattern p = Pattern.compile("^.*\\$(\\w+?)=(.*?)\\{(.*?)\\}.*$", Pattern.DOTALL); Matcher matchKey = p.matcher(comment); if (matchKey.find()) { MatchResult mr = matchKey.toMatchResult(); if ("RM_YES_NOT".equals(mr.group(1))) { aStr[0] = "rm.dictionary.checkbox"; } else { aStr[0] = "rm.dictionary.select"; } aStr[1] = mr.group(1) + "=" + mr.group(2); aStr[2] = mr.group(3); } } catch (Exception e) { QbXmlGenerateCodePlugin.log(e.toString()); } return aStr; } }