// Not concerned too much about reflective annotation access in this // method, since this only runs once per model class... static EntityMapping build(Class<? extends Entity> clz) { EntityMapping mapping = new EntityMapping(); mapping.mMappedClass = clz; Table table = clz.getAnnotation(Table.class); if (table != null) { mapping.mTableName = table.name(); } else { mapping.mTableName = MATCH_DOTDOLLAR.matcher(clz.getName()).replaceAll(""); } ArrayList<String> seenFields = new ArrayList<String>(); for (Field f : clz.getFields()) { // Blithely ignore this field if we've already seen one with same name - // Java field hiding allows this to happen and if it does, without this // we'd be adding the same column name twice. // // We might as well also ignore it here if it's inverse, since we'll // never want to access it via the mapping. Column colAnn = f.getAnnotation(Column.class); boolean inverse = colAnn != null && colAnn.inverse(); if (!seenFields.contains(f.getName()) && !inverse) { Column col = f.getAnnotation(Column.class); String name; if (col != null) { // empty is default, means we should use field name... if ("".equals(name = col.name())) { name = f.getName(); } if (col.primaryKey()) { mapping.mPrimaryKey = f; mapping.mPrimaryKeyColumnName = name; } } else { name = f.getName(); } // Try to default primary key if we don't have one yet... if (mapping.mPrimaryKey == null) { if ("_id".equals(name) || "id".equals(name)) { mapping.mPrimaryKey = f; mapping.mPrimaryKeyColumnName = name; } } mapping.mFields.add(f); mapping.mColumnNames.add(name); seenFields.add(f.getName()); } } if (mapping.mPrimaryKey == null) { // Error at this point - we must have a primary key! Log.e(TAG, "No primary key specified or determined for " + clz); throw new ORMDroidException( "No primary key was specified, and a default could not be determined for " + clz); } return mapping; }