You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by aa...@apache.org on 2007/12/09 14:33:44 UTC

svn commit: r602669 - /cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/gen/

Author: aadamchik
Date: Sun Dec  9 05:33:43 2007
New Revision: 602669

URL: http://svn.apache.org/viewvc?rev=602669&view=rev
Log:
CAY-926 Refactoring class generator classes
(merged TemplateProcessorLogic into ClassGeneratorAction to avoid generation control logic being spread in multiple places)

Removed:
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/gen/TemplateProcessor.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/gen/TemplateProcessor1_1.java
Modified:
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/gen/ClassGenerationAction.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/gen/ClassGenerationAction1_1.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/gen/ClassGenerator.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/gen/ClientClassGenerationAction.java

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/gen/ClassGenerationAction.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/gen/ClassGenerationAction.java?rev=602669&r1=602668&r2=602669&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/gen/ClassGenerationAction.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/gen/ClassGenerationAction.java Sun Dec  9 05:33:43 2007
@@ -26,6 +26,9 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
 
 import org.apache.cayenne.CayenneDataObject;
 import org.apache.cayenne.CayenneRuntimeException;
@@ -33,7 +36,11 @@
 import org.apache.cayenne.map.ObjEntity;
 import org.apache.cayenne.tools.NamePatternMatcher;
 import org.apache.commons.logging.Log;
+import org.apache.velocity.Template;
 import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.VelocityEngine;
+import org.apache.velocity.runtime.RuntimeConstants;
+import org.apache.velocity.runtime.log.NullLogSystem;
 
 /**
  * @since 3.0
@@ -53,6 +60,7 @@
     protected DataMap dataMap;
     protected ClassGeneratorMode mode;
     protected VelocityContext context;
+    protected Map<String, Template> templateCache;
 
     protected Log logger;
     protected File destDir;
@@ -71,6 +79,8 @@
         this.timestamp = System.currentTimeMillis();
         this.usePkgPath = true;
         this.makePairs = true;
+        this.context = new VelocityContext();
+        this.templateCache = new HashMap<String, Template>(5);
     }
 
     protected String defaultSingleClassTemplate() {
@@ -97,14 +107,12 @@
             String superTemplate,
             String superPrefix) throws Exception {
 
-        TemplateProcessor mainGenSetup = new TemplateProcessor(classTemplate, context);
-        TemplateProcessor superGenSetup = new TemplateProcessor(superTemplate, context);
         StringUtils stringUtils = StringUtils.getInstance();
 
-        for (ObjEntity ent : entitiesForCurrentMode()) {
+        for (ObjEntity entity : entitiesForCurrentMode()) {
 
-            String fqnSubClass = ent.getClassName();
-            String fqnBaseClass = (ent.getSuperClassName() != null) ? ent
+            String fqnSubClass = entity.getClassName();
+            String fqnBaseClass = (entity.getSuperClassName() != null) ? entity
                     .getSuperClassName() : CayenneDataObject.class.getName();
 
             String subClassName = stringUtils.stripPackageName(fqnSubClass);
@@ -120,12 +128,11 @@
             String fqnSuperClass = superPackageName + "." + superClassName;
 
             Writer superOut = openWriter(superPackageName, superClassName);
-
             if (superOut != null) {
-                superGenSetup.generateClass(
+                generate(
                         superOut,
-                        dataMap,
-                        ent,
+                        superTemplate,
+                        entity,
                         fqnBaseClass,
                         fqnSuperClass,
                         fqnSubClass);
@@ -134,10 +141,10 @@
 
             Writer mainOut = openWriter(subPackageName, subClassName);
             if (mainOut != null) {
-                mainGenSetup.generateClass(
+                generate(
                         mainOut,
-                        dataMap,
-                        ent,
+                        classTemplate,
+                        entity,
                         fqnBaseClass,
                         fqnSuperClass,
                         fqnSubClass);
@@ -146,30 +153,16 @@
         }
     }
 
-    protected Collection<ObjEntity> entitiesForCurrentMode() {
-
-        // TODO: andrus, 12/2/2007 - should we setup a dummy entity for an empty map in
-        // DataMap mode?
-        if (mode != ClassGeneratorMode.entity && !entities.isEmpty()) {
-            return Collections.singleton(entities.iterator().next());
-        }
-        else {
-            return this.entities;
-        }
-    }
-
     /**
      * Runs class generation. Produces a single Java class for each ObjEntity in the map.
      */
     public void generateSingleClasses(String classTemplate, String superPrefix)
             throws Exception {
 
-        TemplateProcessor generator = new TemplateProcessor(classTemplate, context);
-
-        for (ObjEntity ent : entitiesForCurrentMode()) {
+        for (ObjEntity entity : entitiesForCurrentMode()) {
 
-            String fqnSubClass = ent.getClassName();
-            String fqnBaseClass = (null != ent.getSuperClassName()) ? ent
+            String fqnSubClass = entity.getClassName();
+            String fqnBaseClass = (null != entity.getSuperClassName()) ? entity
                     .getSuperClassName() : CayenneDataObject.class.getName();
 
             StringUtils stringUtils = StringUtils.getInstance();
@@ -184,18 +177,16 @@
             String fqnSuperClass = superPackageName + "." + superClassName;
 
             Writer out = openWriter(subPackageName, subClassName);
-            if (out == null) {
-                continue;
+            if (out != null) {
+                generate(
+                        out,
+                        classTemplate,
+                        entity,
+                        fqnBaseClass,
+                        fqnSuperClass,
+                        fqnSubClass);
+                out.close();
             }
-
-            generator.generateClass(
-                    out,
-                    dataMap,
-                    ent,
-                    fqnBaseClass,
-                    fqnSuperClass,
-                    fqnSubClass);
-            out.close();
         }
     }
 
@@ -205,13 +196,61 @@
     public void execute() throws Exception {
         validateAttributes();
 
-        if (makePairs) {
-            String t = getTemplateForPairs();
-            String st = getSupertemplateForPairs();
-            generateClassPairs(t, st, SUPERCLASS_PREFIX);
+        try {
+            if (makePairs) {
+                String t = getTemplateForPairs();
+                String st = getSupertemplateForPairs();
+                generateClassPairs(t, st, SUPERCLASS_PREFIX);
+            }
+            else {
+                generateSingleClasses(getTemplateForSingles(), SUPERCLASS_PREFIX);
+            }
+        }
+        finally {
+            // must reset engine at the end of class generator run to avoid memory
+            // leaks and stale templates
+            this.templateCache.clear();
+        }
+    }
+
+    protected Template getTemplate(String name) throws Exception {
+        // Velocity < 1.5 has some memory problems, so we will create a VelocityEngine
+        // every time, and store templates in an internal cache, to avoid uncontrolled
+        // memory leaks... Presumably 1.5 fixes it.
+
+        Template template = templateCache.get(name);
+
+        if (template == null) {
+
+            Properties props = new Properties();
+
+            // null logger that will prevent velocity.log from being generated
+            props.put(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS, NullLogSystem.class
+                    .getName());
+            props.put("resource.loader", "cayenne");
+            props.put("cayenne.resource.loader.class", ClassGeneratorResourceLoader.class
+                    .getName());
+            props.put("cayenne.resource.loader.cache", "false");
+
+            VelocityEngine velocityEngine = new VelocityEngine();
+            velocityEngine.init(props);
+
+            template = velocityEngine.getTemplate(name);
+            templateCache.put(name, template);
+        }
+
+        return template;
+    }
+
+    protected Collection<ObjEntity> entitiesForCurrentMode() {
+
+        // TODO: andrus, 12/2/2007 - should we setup a dummy entity for an empty map in
+        // DataMap mode?
+        if (mode != ClassGeneratorMode.entity && !entities.isEmpty()) {
+            return Collections.singleton(entities.iterator().next());
         }
         else {
-            generateSingleClasses(getTemplateForSingles(), SUPERCLASS_PREFIX);
+            return this.entities;
         }
     }
 
@@ -389,6 +428,30 @@
      */
     protected boolean isOld(File file) {
         return file.lastModified() <= timestamp;
+    }
+
+    /**
+     * Merges a template with prebuilt context, writing output to provided writer.
+     */
+    protected void generate(
+            Writer out,
+            String template,
+            ObjEntity entity,
+            String fqnBaseClass,
+            String fqnSuperClass,
+            String fqnSubClass) throws Exception {
+
+        context.put("objEntity", entity);
+        context.put("stringUtils", StringUtils.getInstance());
+        context.put("entityUtils", new EntityUtils(
+                dataMap,
+                entity,
+                fqnBaseClass,
+                fqnSuperClass,
+                fqnSubClass));
+        context.put("importUtils", new ImportUtils());
+
+        getTemplate(template).merge(context, out);
     }
 
     /**

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/gen/ClassGenerationAction1_1.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/gen/ClassGenerationAction1_1.java?rev=602669&r1=602668&r2=602669&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/gen/ClassGenerationAction1_1.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/gen/ClassGenerationAction1_1.java Sun Dec  9 05:33:43 2007
@@ -56,11 +56,8 @@
             String superTemplate,
             String superPrefix) throws Exception {
 
-        TemplateProcessor1_1 mainGenerator = new TemplateProcessor1_1(classTemplate);
-        TemplateProcessor1_1 superGenerator = new TemplateProcessor1_1(superTemplate);
-
-        ClassGenerationInfo mainGen = mainGenerator.getClassGenerationInfo();
-        ClassGenerationInfo superGen = superGenerator.getClassGenerationInfo();
+        ClassGenerationInfo mainGen = new ClassGenerationInfo();
+        ClassGenerationInfo superGen = new ClassGenerationInfo();
 
         // prefix is needed for both generators
         mainGen.setSuperPrefix(superPrefix);
@@ -75,7 +72,7 @@
                     + superGen.getClassName());
 
             if (superOut != null) {
-                superGenerator.generateClass(superOut, dataMap, entity, null, null, null);
+                generate(superOut, superTemplate, entity, null, null, null);
                 superOut.close();
             }
 
@@ -83,30 +80,28 @@
             initClassGenerator(mainGen, entity, false);
             Writer mainOut = openWriter(mainGen.getPackageName(), mainGen.getClassName());
             if (mainOut != null) {
-                mainGenerator.generateClass(mainOut, dataMap, entity, null, null, null);
+                generate(mainOut, classTemplate, entity, null, null, null);
                 mainOut.close();
             }
         }
+
+        context.remove("classGen");
     }
 
     @Override
     public void generateSingleClasses(String classTemplate, String superPrefix)
             throws Exception {
 
-        TemplateProcessor1_1 generator = new TemplateProcessor1_1(classTemplate);
+        ClassGenerationInfo mainGen = new ClassGenerationInfo();
 
         for (ObjEntity entity : entitiesForCurrentMode()) {
 
-            initClassGenerator(generator.getClassGenerationInfo(), entity, false);
-            Writer out = openWriter(
-                    generator.getClassGenerationInfo().getPackageName(),
-                    generator.getClassGenerationInfo().getClassName());
-            if (out == null) {
-                continue;
+            initClassGenerator(mainGen, entity, false);
+            Writer out = openWriter(mainGen.getPackageName(), mainGen.getClassName());
+            if (out != null) {
+                generate(out, classTemplate, entity, null, null, null);
+                out.close();
             }
-
-            generator.generateClass(out, dataMap, entity, null, null, null);
-            out.close();
         }
     }
 
@@ -155,5 +150,8 @@
             generatorInfo.setSuperClassName(CayenneDataObject.class.getName());
         }
         generatorInfo.setSuperPackageName(spkg);
+
+        generatorInfo.setObjEntity(entity);
+        context.put("classGen", generatorInfo);
     }
 }

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/gen/ClassGenerator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/gen/ClassGenerator.java?rev=602669&r1=602668&r2=602669&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/gen/ClassGenerator.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/gen/ClassGenerator.java Sun Dec  9 05:33:43 2007
@@ -41,7 +41,7 @@
  * "classGen".
  * 
  * @author Andrus Adamchik
- * @deprecated since 3.0 use {@link TemplateProcessor}.
+ * @deprecated since 3.0 template logic is merged into the code generation action.
  */
 public class ClassGenerator {
 

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/gen/ClientClassGenerationAction.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/gen/ClientClassGenerationAction.java?rev=602669&r1=602668&r2=602669&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/gen/ClientClassGenerationAction.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/gen/ClientClassGenerationAction.java Sun Dec  9 05:33:43 2007
@@ -61,9 +61,6 @@
             String superTemplate,
             String superPrefix) throws Exception {
 
-        TemplateProcessor mainGenSetup = new TemplateProcessor(classTemplate, context);
-        TemplateProcessor superGenSetup = new TemplateProcessor(superTemplate, context);
-
         for (ObjEntity entity : entitiesForCurrentMode()) {
 
             // use client name, and if not specified use regular class name
@@ -90,9 +87,9 @@
             Writer superOut = openWriter(superPackageName, superClassName);
 
             if (superOut != null) {
-                superGenSetup.generateClass(
+                generate(
                         superOut,
-                        dataMap,
+                        superTemplate,
                         entity,
                         fqnBaseClass,
                         fqnSuperClass,
@@ -102,9 +99,9 @@
 
             Writer mainOut = openWriter(subPackageName, subClassName);
             if (mainOut != null) {
-                mainGenSetup.generateClass(
+                generate(
                         mainOut,
-                        dataMap,
+                        classTemplate,
                         entity,
                         fqnBaseClass,
                         fqnSuperClass,