[prev in list] [next in list] [prev in thread] [next in thread] 

List:       avro-commits
Subject:    svn commit: r1415407 - in /avro/trunk: ./ lang/java/compiler/src/main/java/org/apache/avro/compiler/
From:       cutting () apache ! org
Date:       2012-11-29 22:07:58
Message-ID: 20121129220800.31EA5238890B () eris ! apache ! org
[Download RAW message or body]

Author: cutting
Date: Thu Nov 29 22:07:56 2012
New Revision: 1415407

URL: http://svn.apache.org/viewvc?rev=1415407&view=rev
Log:
AVRO-988, AVRO-1209: Add options to make fields in generated classes private and to \
make generated classes immutable, without setters.  Contributed by Jeff Kolesky.

Modified:
    avro/trunk/CHANGES.txt
    avro/trunk/lang/java/compiler/src/main/java/org/apache/avro/compiler/specific/SpecificCompiler.java
  avro/trunk/lang/java/compiler/src/main/velocity/org/apache/avro/compiler/specific/templates/java/classic/record.vm
  avro/trunk/lang/java/compiler/src/test/java/org/apache/avro/compiler/TestSpecificCompiler.java
  avro/trunk/lang/java/maven-plugin/src/main/java/org/apache/avro/mojo/AbstractAvroMojo.java
  avro/trunk/lang/java/maven-plugin/src/main/java/org/apache/avro/mojo/IDLProtocolMojo.java
  avro/trunk/lang/java/maven-plugin/src/main/java/org/apache/avro/mojo/ProtocolMojo.java
  avro/trunk/lang/java/maven-plugin/src/main/java/org/apache/avro/mojo/SchemaMojo.java


Modified: avro/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/avro/trunk/CHANGES.txt?rev=1415407&r1=1415406&r2=1415407&view=diff
 ==============================================================================
--- avro/trunk/CHANGES.txt (original)
+++ avro/trunk/CHANGES.txt Thu Nov 29 22:07:56 2012
@@ -26,6 +26,16 @@ Trunk (not yet released)
     annotation org.apache.avro.specific.AvroGenerated.
     (Sharmarke Aden via cutting)
 
+    AVRO-988. Java: Add option to make fields in generated classes
+    private, public, or public & deprecated.  This is specified with
+    the "fieldVisibility" option in Maven and is public_deprecated by
+    default for compatibility. (Jeff Kolesky via cutting)
+
+    AVRO-1209. Java: Add option to generate immutable classes, without
+    setter methods.  This is specified with the "createSetters"
+    boolean option in Maven and is true by default for compatibility.
+    (Jeff Kolesky via cutting)
+
   IMPROVEMENTS
 
     AVRO-1169. Java: Reduce memory footprint of resolver.

Modified: avro/trunk/lang/java/compiler/src/main/java/org/apache/avro/compiler/specific/SpecificCompiler.java
                
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/compiler/src/main/java/org/apac \
he/avro/compiler/specific/SpecificCompiler.java?rev=1415407&r1=1415406&r2=1415407&view=diff
 ==============================================================================
--- avro/trunk/lang/java/compiler/src/main/java/org/apache/avro/compiler/specific/SpecificCompiler.java \
                (original)
+++ avro/trunk/lang/java/compiler/src/main/java/org/apache/avro/compiler/specific/SpecificCompiler.java \
Thu Nov 29 22:07:56 2012 @@ -54,10 +54,16 @@ import org.slf4j.LoggerFactory;
  * Java reserved keywords are mangled to preserve compilation.
  */
 public class SpecificCompiler {
+  public static enum FieldVisibility {
+    PUBLIC, PUBLIC_DEPRECATED, PRIVATE
+  }
+
   private final Set<Schema> queue = new HashSet<Schema>();
   private Protocol protocol;
   private VelocityEngine velocityEngine;
   private String templateDir;
+  private FieldVisibility fieldVisibility = FieldVisibility.PUBLIC_DEPRECATED;
+  private boolean createSetters = true;
 
   /* List of Java reserved words from
    * http://java.sun.com/docs/books/jls/third_edition/html/lexical.html. */
@@ -125,6 +131,46 @@ public class SpecificCompiler {
     this.templateDir = templateDir;
   }
 
+  /**
+   * @return true if the record fields should be marked as deprecated
+   */
+  public boolean deprecatedFields() {
+    return (this.fieldVisibility == FieldVisibility.PUBLIC_DEPRECATED);
+  }
+
+  /**
+   * @return true if the record fields should be public
+   */
+  public boolean publicFields() {
+    return (this.fieldVisibility == FieldVisibility.PUBLIC ||
+            this.fieldVisibility == FieldVisibility.PUBLIC_DEPRECATED);
+  }
+
+  /**
+   * @return true if the record fields should be private
+   */
+  public boolean privateFields() {
+    return (this.fieldVisibility == FieldVisibility.PRIVATE);
+  }
+
+  /**
+   * Sets the field visibility option.
+   */
+  public void setFieldVisibility(FieldVisibility fieldVisibility) {
+    this.fieldVisibility = fieldVisibility;
+  }
+
+  public boolean isCreateSetters() {
+      return this.createSetters;
+  }
+
+  /**
+   * Set to false to not create setter methods for the fields of the record.
+   */
+  public void setCreateSetters(boolean createSetters) {
+    this.createSetters = createSetters;
+  }
+
   private static String logChuteName = null;
 
   private void initializeVelocity() {

Modified: avro/trunk/lang/java/compiler/src/main/velocity/org/apache/avro/compiler/specific/templates/java/classic/record.vm
                
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/compiler/src/main/velocity/org/ \
apache/avro/compiler/specific/templates/java/classic/record.vm?rev=1415407&r1=1415406&r2=1415407&view=diff
 ==============================================================================
--- avro/trunk/lang/java/compiler/src/main/velocity/org/apache/avro/compiler/specific/templates/java/classic/record.vm \
                (original)
+++ avro/trunk/lang/java/compiler/src/main/velocity/org/apache/avro/compiler/specific/templates/java/classic/record.vm \
Thu Nov 29 22:07:56 2012 @@ -35,7 +35,7 @@ public class ${this.mangle($schema.getNa
 #foreach ($annotation in $this.javaAnnotations($field))
   @$annotation
 #end
-  @Deprecated public ${this.javaUnbox($field.schema())} ${this.mangle($field.name(), \
$schema.isError())}; +  #if (${this.deprecatedFields()})@Deprecated#end #if \
(${this.publicFields()})public#elseif (${this.privateFields()})private#end \
${this.javaUnbox($field.schema())} ${this.mangle($field.name(), $schema.isError())};  \
#end  #if ($schema.isError())
 
@@ -108,6 +108,7 @@ public class ${this.mangle($schema.getNa
     return ${this.mangle($field.name(), $schema.isError())};
   }
 
+#if ($this.createSetters)
   /**
    * Sets the value of the '${this.mangle($field.name(), $schema.isError())}' field.
 #if ($field.doc())   * $field.doc()#end
@@ -116,6 +117,7 @@ public class ${this.mangle($schema.getNa
   public void ${this.generateSetMethod($schema, \
$field)}(${this.javaType($field.schema())} value) {  \
this.${this.mangle($field.name(), $schema.isError())} = value;  }
+#end
 
 #end
   /** Creates a new ${this.mangle($schema.getName())} RecordBuilder */

Modified: avro/trunk/lang/java/compiler/src/test/java/org/apache/avro/compiler/TestSpecificCompiler.java
                
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/compiler/src/test/java/org/apac \
he/avro/compiler/TestSpecificCompiler.java?rev=1415407&r1=1415406&r2=1415407&view=diff
 ==============================================================================
--- avro/trunk/lang/java/compiler/src/test/java/org/apache/avro/compiler/TestSpecificCompiler.java \
                (original)
+++ avro/trunk/lang/java/compiler/src/test/java/org/apache/avro/compiler/TestSpecificCompiler.java \
Thu Nov 29 22:07:56 2012 @@ -17,9 +17,13 @@
  */
 package org.apache.avro.compiler;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
+import java.io.BufferedReader;
 import java.io.File;
+import java.io.FileReader;
 import java.io.IOException;
 import java.net.URISyntaxException;
 
@@ -27,25 +31,145 @@ import org.apache.avro.AvroTestUtil;
 import org.apache.avro.Schema;
 import org.apache.avro.compiler.specific.SpecificCompiler;
 import org.apache.avro.generic.GenericData.StringType;
+import org.junit.After;
+import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
 
 @RunWith(JUnit4.class)
 public class TestSpecificCompiler {
+  private final String schemaSrcPath = "src/test/resources/simple_record.avsc";
+  private final String velocityTemplateDir =
+      "src/main/velocity/org/apache/avro/compiler/specific/templates/java/classic/";
+  private File src;
+  private File outputDir;
+  private File outputFile;
 
-  @Test
-  public void testCanReadTemplateFilesOnTheFilesystem() throws IOException, \
                URISyntaxException{
-    String schemaSrcPath = "src/test/resources/simple_record.avsc";
-    String velocityTemplateDir = \
                "src/main/velocity/org/apache/avro/compiler/specific/templates/java/classic/";
                
-    File src = new File(schemaSrcPath);
+  @Before
+  public void setUp() {
+    this.src = new File(this.schemaSrcPath);
+    this.outputDir = AvroTestUtil.tempDirectory(getClass(), "specific-output");
+    this.outputFile = new File(this.outputDir, "SimpleRecord.java");
+  }
+
+  @After
+  public void tearDow() {
+    if (this.outputFile != null) {
+      this.outputFile.delete();
+    }
+  }
+
+  private SpecificCompiler createCompiler() throws IOException {
     Schema.Parser parser = new Schema.Parser();
-    Schema schema = parser.parse(src);
+    Schema schema = parser.parse(this.src);
     SpecificCompiler compiler = new SpecificCompiler(schema);
-    compiler.setTemplateDir(velocityTemplateDir);
+    compiler.setTemplateDir(this.velocityTemplateDir);
     compiler.setStringType(StringType.CharSequence);
-    File outputDir = AvroTestUtil.tempDirectory(getClass(), "specific-output");
-    compiler.compileToDestination(src, outputDir);
-    assertTrue(new File(outputDir, "SimpleRecord.java").exists());
+    return compiler;
+  }
+
+  @Test
+  public void testCanReadTemplateFilesOnTheFilesystem() throws IOException, \
URISyntaxException{ +    SpecificCompiler compiler = createCompiler();
+    compiler.compileToDestination(this.src, this.outputDir);
+    assertTrue(this.outputFile.exists());
+  }
+
+  @Test
+  public void testPublicFieldVisibility() throws IOException {
+    SpecificCompiler compiler = createCompiler();
+    compiler.setFieldVisibility(SpecificCompiler.FieldVisibility.PUBLIC);
+    assertFalse(compiler.deprecatedFields());
+    assertTrue(compiler.publicFields());
+    assertFalse(compiler.privateFields());
+    compiler.compileToDestination(this.src, this.outputDir);
+    assertTrue(this.outputFile.exists());
+    BufferedReader reader = new BufferedReader(new FileReader(this.outputFile));
+    String line = null;
+    while ((line = reader.readLine()) != null) {
+      // No line, once trimmed, should start with a deprecated field declaration
+      // nor a private field declaration.  Since the nested builder uses private
+      // fields, we cannot do the second check.
+      line = line.trim();
+      assertFalse("Line started with a deprecated field declaration: " + line,
+        line.startsWith("@Deprecated public int value"));
+    }
+  }
+
+  @Test
+  public void testPublicDeprecatedFieldVisibility() throws IOException {
+    SpecificCompiler compiler = createCompiler();
+    assertTrue(compiler.deprecatedFields());
+    assertTrue(compiler.publicFields());
+    assertFalse(compiler.privateFields());
+    compiler.compileToDestination(this.src, this.outputDir);
+    assertTrue(this.outputFile.exists());
+    BufferedReader reader = new BufferedReader(new FileReader(this.outputFile));
+    String line = null;
+    while ((line = reader.readLine()) != null) {
+      // No line, once trimmed, should start with a public field declaration
+      line = line.trim();
+      assertFalse("Line started with a public field declaration: " + line,
+        line.startsWith("public int value"));
+    }
+  }
+
+  @Test
+  public void testPrivateFieldVisibility() throws IOException {
+    SpecificCompiler compiler = createCompiler();
+    compiler.setFieldVisibility(SpecificCompiler.FieldVisibility.PRIVATE);
+    assertFalse(compiler.deprecatedFields());
+    assertFalse(compiler.publicFields());
+    assertTrue(compiler.privateFields());
+    compiler.compileToDestination(this.src, this.outputDir);
+    assertTrue(this.outputFile.exists());
+    BufferedReader reader = new BufferedReader(new FileReader(this.outputFile));
+    String line = null;
+    while ((line = reader.readLine()) != null) {
+      // No line, once trimmed, should start with a public field declaration
+      // or with a deprecated public field declaration
+      line = line.trim();
+      assertFalse("Line started with a public field declaration: " + line,
+        line.startsWith("public int value"));
+      assertFalse("Line started with a deprecated field declaration: " + line,
+        line.startsWith("@Deprecated public int value"));
+    }
+  }
+
+  @Test
+  public void testSettersCreatedByDefault() throws IOException {
+    SpecificCompiler compiler = createCompiler();
+    assertTrue(compiler.isCreateSetters());
+    compiler.compileToDestination(this.src, this.outputDir);
+    assertTrue(this.outputFile.exists());
+    BufferedReader reader = new BufferedReader(new FileReader(this.outputFile));
+    int foundSetters = 0;
+    String line = null;
+    while ((line = reader.readLine()) != null) {
+      // We should find the setter in the main class
+      line = line.trim();
+      if (line.startsWith("public void setValue(")) {
+        foundSetters++;
+      }
+    }
+    assertEquals("Found the wrong number of setters", 1, foundSetters);
+  }
+
+  @Test
+  public void testSettersNotCreatedWhenOptionTurnedOff() throws IOException {
+    SpecificCompiler compiler = createCompiler();
+    compiler.setCreateSetters(false);
+    assertFalse(compiler.isCreateSetters());
+    compiler.compileToDestination(this.src, this.outputDir);
+    assertTrue(this.outputFile.exists());
+    BufferedReader reader = new BufferedReader(new FileReader(this.outputFile));
+    String line = null;
+    while ((line = reader.readLine()) != null) {
+      // No setter should be found
+      line = line.trim();
+      assertFalse("No line should include the setter: " + line,
+        line.startsWith("public void setValue("));
+    }
   }
 }

Modified: avro/trunk/lang/java/maven-plugin/src/main/java/org/apache/avro/mojo/AbstractAvroMojo.java
                
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/maven-plugin/src/main/java/org/ \
apache/avro/mojo/AbstractAvroMojo.java?rev=1415407&r1=1415406&r2=1415407&view=diff \
                ==============================================================================
                
--- avro/trunk/lang/java/maven-plugin/src/main/java/org/apache/avro/mojo/AbstractAvroMojo.java \
                (original)
+++ avro/trunk/lang/java/maven-plugin/src/main/java/org/apache/avro/mojo/AbstractAvroMojo.java \
Thu Nov 29 22:07:56 2012 @@ -22,6 +22,8 @@ import java.io.File;
 import java.io.IOException;
 import java.util.Arrays;
 
+import org.apache.avro.compiler.specific.SpecificCompiler;
+
 import org.apache.maven.plugin.AbstractMojo;
 import org.apache.maven.plugin.MojoExecutionException;
 import org.apache.maven.project.MavenProject;
@@ -57,6 +59,15 @@ public abstract class AbstractAvroMojo e
   private File testOutputDirectory;
 
   /**
+   * The field visibility indicator for the fields of the generated class, as
+   * string values of SpecificCompiler.FieldVisibility.  The text is case
+   * insensitive.
+   *
+   * @parameter default-value="PUBLIC_DEPRECATED"
+   */
+  private String fieldVisibility;
+
+  /**
    * A list of files or directories that should be compiled first thus making
    * them importable by subsequently compiled schemas. Note that imported files
    * should not reference each other.
@@ -99,6 +110,14 @@ public abstract class AbstractAvroMojo e
   protected String templateDirectory = \
"/org/apache/avro/compiler/specific/templates/java/classic/";  
   /**
+   * Determines whether or not to create setters for the fields of the record.
+   * The default is to create setters.
+   *
+   * @parameter default-value="true"
+   */
+  protected boolean createSetters;
+
+  /**
    * The current Maven project.
    * 
    * @parameter default-value="${project}"
@@ -197,6 +216,15 @@ public abstract class AbstractAvroMojo e
     }
   }
 
+  protected SpecificCompiler.FieldVisibility getFieldVisibility() {
+    try {
+      String upper = String.valueOf(this.fieldVisibility).trim().toUpperCase();
+      return SpecificCompiler.FieldVisibility.valueOf(upper);
+    } catch (IllegalArgumentException e) {
+      return SpecificCompiler.FieldVisibility.PUBLIC_DEPRECATED;
+    }
+  }
+
   protected abstract void doCompile(String filename, File sourceDirectory, File \
outputDirectory) throws IOException;  
   protected abstract String[] getIncludes();

Modified: avro/trunk/lang/java/maven-plugin/src/main/java/org/apache/avro/mojo/IDLProtocolMojo.java
                
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/maven-plugin/src/main/java/org/ \
apache/avro/mojo/IDLProtocolMojo.java?rev=1415407&r1=1415406&r2=1415407&view=diff \
                ==============================================================================
                
--- avro/trunk/lang/java/maven-plugin/src/main/java/org/apache/avro/mojo/IDLProtocolMojo.java \
                (original)
+++ avro/trunk/lang/java/maven-plugin/src/main/java/org/apache/avro/mojo/IDLProtocolMojo.java \
Thu Nov 29 22:07:56 2012 @@ -85,6 +85,8 @@ public class IDLProtocolMojo extends Abs
       SpecificCompiler compiler = new SpecificCompiler(protocol);
       compiler.setStringType(GenericData.StringType.valueOf(stringType));
       compiler.setTemplateDir(templateDirectory);
+      compiler.setFieldVisibility(getFieldVisibility());
+      compiler.setCreateSetters(createSetters);
       compiler.compileToDestination(null, outputDirectory);
     } catch (ParseException e) {
       throw new IOException(e);

Modified: avro/trunk/lang/java/maven-plugin/src/main/java/org/apache/avro/mojo/ProtocolMojo.java
                
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/maven-plugin/src/main/java/org/apache/avro/mojo/ProtocolMojo.java?rev=1415407&r1=1415406&r2=1415407&view=diff
 ==============================================================================
--- avro/trunk/lang/java/maven-plugin/src/main/java/org/apache/avro/mojo/ProtocolMojo.java \
                (original)
+++ avro/trunk/lang/java/maven-plugin/src/main/java/org/apache/avro/mojo/ProtocolMojo.java \
Thu Nov 29 22:07:56 2012 @@ -58,6 +58,8 @@ public class ProtocolMojo extends Abstra
     SpecificCompiler compiler = new SpecificCompiler(protocol);
     compiler.setTemplateDir(templateDirectory);
     compiler.setStringType(StringType.valueOf(stringType));
+    compiler.setFieldVisibility(getFieldVisibility());
+    compiler.setCreateSetters(createSetters);
     compiler.compileToDestination(src, outputDirectory);
   }
 

Modified: avro/trunk/lang/java/maven-plugin/src/main/java/org/apache/avro/mojo/SchemaMojo.java
                
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/maven-plugin/src/main/java/org/apache/avro/mojo/SchemaMojo.java?rev=1415407&r1=1415406&r2=1415407&view=diff
 ==============================================================================
--- avro/trunk/lang/java/maven-plugin/src/main/java/org/apache/avro/mojo/SchemaMojo.java \
                (original)
+++ avro/trunk/lang/java/maven-plugin/src/main/java/org/apache/avro/mojo/SchemaMojo.java \
Thu Nov 29 22:07:56 2012 @@ -75,6 +75,8 @@ public class SchemaMojo extends Abstract
     SpecificCompiler compiler = new SpecificCompiler(schema);
     compiler.setTemplateDir(templateDirectory);
     compiler.setStringType(StringType.valueOf(stringType));
+    compiler.setFieldVisibility(getFieldVisibility());
+    compiler.setCreateSetters(createSetters);
     compiler.compileToDestination(src, outputDirectory);
   }
 


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic