From b884f89e8039f1186ce6d5c63560b491bce843a0 Mon Sep 17 00:00:00 2001 From: Michael Bayne Date: Wed, 15 Aug 2007 02:39:42 +0000 Subject: [PATCH] If a persistent record is abstract, do not generate ColumnExp() constants for it; if it extends another record, generate ColumnExp() constants for persistent fields inherited from its parents. --- .../jdbc/depot/tools/GenRecordTask.java | 97 ++++++++++++------- .../jdbc/depot/tools/record_column.tmpl | 3 + .../jdbc/depot/tools/record_name.tmpl | 4 - 3 files changed, 64 insertions(+), 40 deletions(-) create mode 100644 src/java/com/samskivert/jdbc/depot/tools/record_column.tmpl diff --git a/src/java/com/samskivert/jdbc/depot/tools/GenRecordTask.java b/src/java/com/samskivert/jdbc/depot/tools/GenRecordTask.java index c9cf38b..f51c033 100644 --- a/src/java/com/samskivert/jdbc/depot/tools/GenRecordTask.java +++ b/src/java/com/samskivert/jdbc/depot/tools/GenRecordTask.java @@ -34,7 +34,9 @@ import java.lang.reflect.Modifier; import java.lang.reflect.Type; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -137,23 +139,24 @@ public class GenRecordTask extends Task } } - /** Processes a resolved distributed object class instance. */ - protected void processRecord (File source, Class oclass) + /** Processes a resolved persistent record class instance. */ + protected void processRecord (File source, Class rclass) { // make sure we extend persistent record - if (!_prclass.isAssignableFrom(oclass)) { - // System.err.println("Skipping " + oclass.getName() + "..."); + if (!_prclass.isAssignableFrom(rclass)) { + // System.err.println("Skipping " + rclass.getName() + "..."); return; } + boolean isAbstract = Modifier.isAbstract(rclass.getModifiers()); // determine our primary key fields for getKey() generation (if we're not an abstract) List kflist = new ArrayList(); - if (!Modifier.isAbstract(oclass.getModifiers())) { + if (!isAbstract) { // determine which fields make up our primary key; we'd just use Class.getFields() but // that returns things in a random order whereas ClassUtil returns fields in // declaration order starting from the top-most class and going down the line FIELD_LOOP: - for (Field field : ClassUtil.getFields(oclass)) { + for (Field field : ClassUtil.getFields(rclass)) { // iterate becase getAnnotation() fails if we're dealing with multiple classloaders for (Annotation a : field.getAnnotations()) { if (Id.class.getName().equals(a.annotationType().getName())) { @@ -166,12 +169,16 @@ public class GenRecordTask extends Task // determine which fields we need to generate constants for List flist = new ArrayList(); - for (Field field : oclass.getDeclaredFields()) { - int mods = field.getModifiers(); - if (!Modifier.isPublic(mods) || Modifier.isStatic(mods) || Modifier.isTransient(mods)) { - continue; + for (Field field : rclass.getFields()) { + if (isPersistentField(field)) { + flist.add(field); + } + } + Set declared = new HashSet(); + for (Field field : rclass.getDeclaredFields()) { + if (isPersistentField(field)) { + declared.add(field); } - flist.add(field); } // slurp our source file into newline separated strings @@ -247,7 +254,7 @@ public class GenRecordTask extends Task } // get the unqualified class name - String rname = oclass.getName(); + String rname = rclass.getName(); rname = rname.substring(rname.lastIndexOf(".")+1); // generate our fields section @@ -263,19 +270,18 @@ public class GenRecordTask extends Task ctx.put("capfield", StringUtil.unStudlyName(fname).toUpperCase()); // now generate our bits - StringWriter fwriter = new StringWriter(); - try { - _velocity.mergeTemplate(NAME_TMPL, "UTF-8", ctx, fwriter); - } catch (Exception e) { - System.err.println("Failed processing template"); - e.printStackTrace(System.err); + if (declared.contains(f)) { + if (fsection.length() > 0) { + fsection.append("\n"); + } + fsection.append(mergeTemplate(NAME_TMPL, ctx)); } - - // and append them as appropriate to the string buffers - if (ii > 0) { - fsection.append("\n"); + if (!isAbstract) { + if (fsection.length() > 0) { + fsection.append("\n"); + } + fsection.append(mergeTemplate(COL_TMPL, ctx)); } - fsection.append(fwriter.toString()); } // generate our methods section @@ -306,17 +312,8 @@ public class GenRecordTask extends Task ctx.put("argNameList", argNameList.toString()); ctx.put("fieldNameList", fieldNameList.toString()); - // now generate our bits - StringWriter mwriter = new StringWriter(); - try { - _velocity.mergeTemplate(KEY_TMPL, "UTF-8", ctx, mwriter); - } catch (Exception e) { - System.err.println("Failed processing template"); - e.printStackTrace(System.err); - } - - // and append them as appropriate to the string buffers - msection.append(mwriter.toString()); + // generate our bits and append them as appropriate to the string buffers + msection.append(mergeTemplate(KEY_TMPL, ctx)); } // now bolt everything back together into a class declaration @@ -364,8 +361,20 @@ public class GenRecordTask extends Task } } - /** Safely gets the indexth line, returning the empty string if we exceed the - * length of the array. */ + /** + * Returns true if the supplied field is part of a persistent record (is a public, non-static, + * non-transient field). + */ + protected boolean isPersistentField (Field field) + { + int mods = field.getModifiers(); + return Modifier.isPublic(mods) && !Modifier.isStatic(mods) && !Modifier.isTransient(mods); + } + + /** + * Safely gets the indexth line, returning the empty string if we exceed the + * length of the array. + */ protected String get (String[] lines, int index) { return (index < lines.length) ? lines[index] : ""; @@ -390,6 +399,19 @@ public class GenRecordTask extends Task bout.newLine(); } + /** Helper function for generating our boilerplate code. */ + protected String mergeTemplate (String tmpl, VelocityContext ctx) + { + StringWriter writer = new StringWriter(); + try { + _velocity.mergeTemplate(tmpl, "UTF-8", ctx, writer); + } catch (Exception e) { + System.err.println("Failed processing template [tmpl=" + tmpl + "]"); + e.printStackTrace(System.err); + } + return writer.toString(); + } + /** * Reads in the supplied source file and locates the package and class or interface name and * returns a fully qualified class name. @@ -443,6 +465,9 @@ public class GenRecordTask extends Task /** Specifies the path to the name code template. */ protected static final String NAME_TMPL = "com/samskivert/jdbc/depot/tools/record_name.tmpl"; + /** Specifies the path to the column code template. */ + protected static final String COL_TMPL = "com/samskivert/jdbc/depot/tools/record_column.tmpl"; + /** Specifies the path to the key code template. */ protected static final String KEY_TMPL = "com/samskivert/jdbc/depot/tools/record_key.tmpl"; diff --git a/src/java/com/samskivert/jdbc/depot/tools/record_column.tmpl b/src/java/com/samskivert/jdbc/depot/tools/record_column.tmpl new file mode 100644 index 0000000..82e236f --- /dev/null +++ b/src/java/com/samskivert/jdbc/depot/tools/record_column.tmpl @@ -0,0 +1,3 @@ + /** The qualified column identifier for the {@link #$field} field. */ + public static final ColumnExp ${capfield}_C = + new ColumnExp(${record}.class, $capfield); diff --git a/src/java/com/samskivert/jdbc/depot/tools/record_name.tmpl b/src/java/com/samskivert/jdbc/depot/tools/record_name.tmpl index 2738ba4..e212ce6 100644 --- a/src/java/com/samskivert/jdbc/depot/tools/record_name.tmpl +++ b/src/java/com/samskivert/jdbc/depot/tools/record_name.tmpl @@ -1,6 +1,2 @@ /** The column identifier for the {@link #$field} field. */ public static final String $capfield = "$field"; - - /** The qualified column identifier for the {@link #$field} field. */ - public static final ColumnExp ${capfield}_C = - new ColumnExp(${record}.class, $capfield);