package org.beanfuse.persist.hibernate; import java.io.Serializable; import org.beanfuse.lang.StringUtil; import org.hibernate.AssertionFailure; import org.hibernate.cfg.DefaultNamingStrategy; import org.hibernate.cfg.NamingStrategy; import org.hibernate.util.StringHelper; import org.jvnet.inflector.Pluralizer; import org.jvnet.inflector.lang.en.NounPluralizer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * An improved naming strategy that prefers embedded underscores to mixed case * names * * @see DefaultNamingStrategy the default strategy * @author chaostone */ public class RailsNamingStrategy implements NamingStrategy, Serializable { protected static Logger logger = LoggerFactory.getLogger(RailsNamingStrategy.class); /** * 是否对表名进行复数化 */ private boolean pluralizeTableName = true; private Pluralizer pluralizer = new NounPluralizer(); /** * 当前表的前缀 */ private String tablePrefix; /** * A convenient singleton instance */ public static final NamingStrategy INSTANCE = new RailsNamingStrategy(); public static String unqualify(String qualifiedName) { int loc = qualifiedName.lastIndexOf('.'); return (loc < 0) ? qualifiedName : qualifiedName.substring(loc + 1); } /** * Return the unqualified class name, mixed case converted to underscores */ public String classToTableName(String className) { String tableName = null; if (pluralizeTableName) { tableName = pluralizer.pluralize(addUnderscores(unqualify(className))); } else { tableName = addUnderscores(unqualify(className)); } tablePrefix = TableNameByModuleStrategy.getPrefix(className); if (null != tablePrefix) { tableName = tablePrefix + tableName; } if (tableName.length() > 30) { logger.warn("{}'s length has greate more then 30, database will not be supported!", tableName); } return tableName; } /** * Return the full property path with underscore seperators, mixed case * converted to underscores */ public String propertyToColumnName(String propertyName) { return addUnderscores(unqualify(propertyName)); } /** * Convert mixed case to underscores */ public String tableName(String tableName) { String newName = addUnderscores(tableName); if (null != tablePrefix) { if (!newName.startsWith(tablePrefix)) { newName = tablePrefix + newName; } } return newName; } /** * Convert mixed case to underscores */ public String columnName(String columnName) { return addUnderscores(columnName); } protected static String addUnderscores(String name) { return StringUtil.unCamel(name.replace('.', '_'), '_'); } public String collectionTableName(String ownerEntity, String ownerEntityTable, String associatedEntity, String associatedEntityTable, String propertyName) { return tableName(ownerEntityTable + '_') + propertyToColumnName(propertyName); } /** * Return the argument */ public String joinKeyColumnName(String joinedColumn, String joinedTable) { return columnName(joinedColumn); } /** * Return the property name or propertyTableName */ public String foreignKeyColumnName(String propertyName, String propertyEntityName, String propertyTableName, String referencedColumnName) { String header = null == propertyName ? propertyTableName : unqualify(propertyName); if (header == null) { throw new AssertionFailure("NamingStrategy not properly filled"); } return columnName(header) + "_" + referencedColumnName; } /** * Return the column name or the unqualified property name */ public String logicalColumnName(String columnName, String propertyName) { return StringHelper.isNotEmpty(columnName) ? columnName : propertyToColumnName(propertyName); } /** * Returns either the table name if explicit or if there is an associated * table, the concatenation of owner entity table and associated table * otherwise the concatenation of owner entity table and the unqualified * property name */ public String logicalCollectionTableName(String tableName, String ownerEntityTable, String associatedEntityTable, String propertyName) { if (tableName == null) { // use of a stringbuilder to workaround a JDK bug return new StringBuilder(ownerEntityTable).append("_") .append( associatedEntityTable == null ? unqualify(propertyName) : associatedEntityTable).toString(); } else { return tableName; } } /** * Return the column name if explicit or the concatenation of the property * name and the referenced column */ public String logicalCollectionColumnName(String columnName, String propertyName, String referencedColumn) { return StringHelper.isNotEmpty(columnName) ? columnName : unqualify(propertyName) + "_" + referencedColumn; } public Pluralizer getPluralizer() { return pluralizer; } public void setPluralizer(Pluralizer pluralizer) { this.pluralizer = pluralizer; } public boolean isPluralizeTableName() { return pluralizeTableName; } public void setPluralizeTableName(boolean pluralizeTableName) { this.pluralizeTableName = pluralizeTableName; } }