001: // Copyright (c) 2003-2007, Jodd Team (jodd.sf.net). All Rights Reserved.
002:
003: package jodd.db.orm;
004:
005: import jodd.db.orm.meta.DbColumn;
006: import jodd.db.orm.meta.DbTable;
007: import jodd.introspector.DefaultIntrospector;
008:
009: import java.lang.reflect.Field;
010: import java.util.ArrayList;
011: import java.util.List;
012:
013: /**
014: * Holds all information about some entity type, such as table name and column names.
015: */
016: public class DbEntityDescriptor {
017:
018: private DbOrm dbOrm;
019:
020: public DbEntityDescriptor(Class type, DbOrm dbOrm) {
021: this .type = type;
022: this .dbOrm = dbOrm;
023: resolveTableName();
024: }
025:
026: /**
027: * Resolves table name from a type. If type is annotated, table name
028: * will be read from annotation value. If this value is empty or if
029: * type is not annotated, table name will be set to wildcard pattern '*'
030: * (to match all tables).
031: */
032: @SuppressWarnings({"unchecked"})
033: private void resolveTableName() {
034: if (tableName == null) {
035: DbTable dbTable = (DbTable) type
036: .getAnnotation(DbTable.class);
037: if (dbTable != null) {
038: isAnnotated = true;
039: tableName = dbTable.value().trim();
040: }
041: if ((tableName == null) || (tableName.length() == 0)) {
042: tableName = DbNameUtil.convertClassNameToTableName(
043: type, dbOrm.tablePrefix);
044: }
045: }
046:
047: }
048:
049: // ---------------------------------------------------------------- type and table
050:
051: private Class type;
052:
053: /**
054: * Returns entity type.
055: */
056: public Class getType() {
057: return type;
058: }
059:
060: private boolean isAnnotated;
061:
062: /**
063: * Returns <code>true</code> if type is annotated with {@link jodd.db.orm.meta.DbTable}.
064: */
065: public boolean isAnnotated() {
066: return isAnnotated;
067: }
068:
069: private String tableName;
070:
071: /**
072: * Returns table name to which the entity is mapped.
073: */
074: public String getTableName() {
075: return tableName;
076: }
077:
078: // ---------------------------------------------------------------- columns and fields
079:
080: private String[] columns;
081: private String[] properties;
082:
083: /**
084: * Returns the array of all columns mapped by entity type.
085: */
086: public String[] getColumns() {
087: if (columns == null) {
088: resolveColumnsAndProperties(type);
089: }
090: return columns;
091: }
092:
093: /**
094: * Returns the array of all properties that are mapped to columns in entity type.
095: */
096: public String[] getProperties() {
097: if (properties == null) {
098: resolveColumnsAndProperties(type);
099: }
100: return properties;
101: }
102:
103: /**
104: * Resolves list of all columns and properties.
105: */
106: private void resolveColumnsAndProperties(Class type) {
107: List<String> columnNames = new ArrayList<String>();
108: List<String> propertyNames = new ArrayList<String>();
109: Field[] fields = DefaultIntrospector.lookup(type).getAllFields(
110: true);
111: for (Field field : fields) {
112: String columnName = resolveColumnName(field);
113: if (columnName != null) {
114: columnNames.add(columnName);
115: propertyNames.add(field.getName());
116: }
117: }
118: if (columnNames.isEmpty()) {
119: throw new DbOrmException("Entity '" + type
120: + "' doesn't have any column mappings.");
121: }
122: columns = columnNames.toArray(new String[columnNames.size()]);
123: properties = propertyNames.toArray(new String[propertyNames
124: .size()]);
125: }
126:
127: /**
128: * Resolve column name from field. If field is annotated value will be read
129: * from annotation. If field is not annotated, then field will be ignored
130: * if entity is annotated. Otherwise, column name is generated from the field name.
131: */
132: private String resolveColumnName(Field field) {
133: DbColumn dbColumn = field.getAnnotation(DbColumn.class);
134: String columnName = null;
135: if (dbColumn != null) {
136: columnName = dbColumn.value().trim();
137: } else {
138: if (isAnnotated == true) {
139: return null;
140: }
141: }
142: if ((columnName == null) || (columnName.length() == 0)) {
143: columnName = DbNameUtil
144: .convertPropertyNameToColumnName(field.getName());
145: }
146: return columnName;
147: }
148:
149: /**
150: * Returns property name for specified column name.
151: */
152: public String getPropertyName(String columnName) {
153: if (columnName == null) {
154: return null;
155: }
156: if (columns == null) {
157: resolveColumnsAndProperties(type);
158: }
159: for (int i = 0; i < columns.length; i++) {
160: String name = columns[i];
161: if (name.equals(columnName) == true) {
162: return properties[i];
163: }
164: }
165: return null;
166: }
167:
168: /**
169: * Returns column name for specified property name..
170: */
171: public String getColumnName(String propertyName) {
172: if (propertyName == null) {
173: return null;
174: }
175: if (columns == null) {
176: resolveColumnsAndProperties(type);
177: }
178: for (int i = 0; i < properties.length; i++) {
179: String name = properties[i];
180: if (name.equals(propertyName) == true) {
181: return columns[i];
182: }
183: }
184: return null;
185: }
186:
187: }
|