package cn.org.rapid_framework.jdbc.sqlgenerator.metadata; import java.beans.BeanInfo; import java.beans.IntrospectionException; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import javax.persistence.Id; import javax.persistence.Transient; /** * 用于生成Table对象实例的工具类 * * @see Table * @author badqiu * */ public class MetadataCreateUtils { public static Table createTable(Class clazz) { BeanInfo info = getBeanInfo(clazz); PropertyDescriptor[] pds = info.getPropertyDescriptors(); List<Column> columns = new ArrayList(); for(PropertyDescriptor pd : pds) { if("class".equals(pd.getName())) continue; Method readMethod = pd.getReadMethod(); if(readMethod == null || pd.getWriteMethod() == null){ continue; } if(isTransientProperty(readMethod,pd.getWriteMethod())) { continue; } if(!isNativeJavaType(readMethod.getReturnType())) { continue; } boolean isPrimaryKey = isPrimaryKeyColumn(readMethod); String sqlName = getColumnSqlName(pd,readMethod); Column column = new Column(sqlName,pd.getName(),isPrimaryKey); column.setInsertable(getColumnInsertable(pd, readMethod)); column.setUpdatable(getColumnUpdatable(pd, readMethod)); column.setUnique(getColumnUnique(pd, readMethod)); columns.add(column); } Table t = new Table(getTableName(clazz),columns); return t; } static boolean isNativeJavaType(Class clazz) { if(clazz == null) return false; if(clazz.isArray()) return false; if(clazz.isPrimitive() || clazz.getName().startsWith("java.") || clazz.getName().startsWith("javax.")) { return true; } return false; } private static boolean isTransientProperty(Method readMethod,Method writeMethod) { if(isJPAClassAvaiable) { if(readMethod.isAnnotationPresent(Transient.class)) { return true; } } return false; } private static BeanInfo getBeanInfo(Class clazz) { try { return Introspector.getBeanInfo(clazz); } catch (IntrospectionException e) { throw new IllegalArgumentException("error: generate Table instance from Class,clazz:"+clazz,e); } } private static boolean isJPAClassAvaiable = false; static { try { Class.forName("javax.persistence.Table"); isJPAClassAvaiable = true; } catch (ClassNotFoundException e) { } } private static boolean isPrimaryKeyColumn(Method readMethod) { boolean isPrimaryKey = false; if(isJPAClassAvaiable) { if(readMethod.isAnnotationPresent(Id.class)) { isPrimaryKey = true; } } return isPrimaryKey; } private static String getColumnSqlName(PropertyDescriptor pd, Method readMethod) { String sqlName = null; if(isJPAClassAvaiable) { javax.persistence.Column annColumn = (javax.persistence.Column)readMethod.getAnnotation(javax.persistence.Column.class); if(annColumn != null) { sqlName = annColumn.name(); } } if(sqlName == null || sqlName.length() == 0) { sqlName = toUnderscoreName(pd.getName()); } return sqlName; } private static boolean getColumnInsertable(PropertyDescriptor pd, Method method) { boolean insertable = true; if(isJPAClassAvaiable) { javax.persistence.Column annColumn = (javax.persistence.Column)method.getAnnotation(javax.persistence.Column.class); if(annColumn != null) { insertable = annColumn.insertable(); } } return insertable; } private static boolean getColumnUpdatable(PropertyDescriptor pd, Method method) { boolean updatable = true; if(isJPAClassAvaiable) { javax.persistence.Column annColumn = (javax.persistence.Column)method.getAnnotation(javax.persistence.Column.class); if(annColumn != null) { updatable = annColumn.updatable(); } } return updatable; } private static boolean getColumnUnique(PropertyDescriptor pd, Method method) { boolean unique = false; if(isJPAClassAvaiable) { javax.persistence.Column annColumn = (javax.persistence.Column)method.getAnnotation(javax.persistence.Column.class); if(annColumn != null) { unique = annColumn.unique(); } } return unique; } private static String getTableName(Class clazz) { String tableName = toUnderscoreName(clazz.getSimpleName()); if(isJPAClassAvaiable) { javax.persistence.Table annTable = (javax.persistence.Table)clazz.getAnnotation(javax.persistence.Table.class); if(annTable != null) { tableName = annTable.name(); } } return tableName; } private static String toUnderscoreName(String name) { if(name == null) return null; String filteredName = name; if(filteredName.indexOf("_") >= 0 && filteredName.equals(filteredName.toUpperCase())) { filteredName = filteredName.toLowerCase(); } if(filteredName.indexOf("_") == -1 && filteredName.equals(filteredName.toUpperCase())) { filteredName = filteredName.toLowerCase(); } StringBuffer result = new StringBuffer(); if (filteredName != null && filteredName.length() > 0) { result.append(filteredName.substring(0, 1).toLowerCase()); for (int i = 1; i < filteredName.length(); i++) { String preChart = filteredName.substring(i - 1, i); String c = filteredName.substring(i, i + 1); if(c.equals("_")) { result.append("_"); continue; } if(preChart.equals("_")){ result.append(c.toLowerCase()); continue; } if(c.matches("\\d")) { result.append(c); }else if (c.equals(c.toUpperCase())) { result.append("_"); result.append(c.toLowerCase()); } else { result.append(c); } } } return result.toString(); } }