You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@avro.apache.org by cu...@apache.org on 2012/02/08 23:13:51 UTC

svn commit: r1242140 - in /avro/trunk: ./ lang/java/avro/src/main/java/org/apache/avro/ lang/java/compiler/src/main/javacc/org/apache/avro/compiler/idl/ lang/java/compiler/src/test/idl/input/ lang/java/compiler/src/test/idl/output/ lang/java/compiler/s...

Author: cutting
Date: Wed Feb  8 22:13:50 2012
New Revision: 1242140

URL: http://svn.apache.org/viewvc?rev=1242140&view=rev
Log:
AVRO-971. Java: Permit IDL imports from classpath in Maven.  Contributed by Victor Chau.

Added:
    avro/trunk/lang/java/compiler/src/test/idl/putOnClassPath/
    avro/trunk/lang/java/compiler/src/test/idl/putOnClassPath/OnTheClasspath.avdl
    avro/trunk/lang/java/compiler/src/test/idl/putOnClassPath/OnTheClasspath.avpr
    avro/trunk/lang/java/compiler/src/test/idl/putOnClassPath/OnTheClasspath.avsc
Modified:
    avro/trunk/CHANGES.txt
    avro/trunk/lang/java/avro/src/main/java/org/apache/avro/Protocol.java
    avro/trunk/lang/java/compiler/src/main/javacc/org/apache/avro/compiler/idl/idl.jj
    avro/trunk/lang/java/compiler/src/test/idl/input/import.avdl
    avro/trunk/lang/java/compiler/src/test/idl/output/import.avpr
    avro/trunk/lang/java/compiler/src/test/java/org/apache/avro/compiler/idl/TestIdl.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

Modified: avro/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/avro/trunk/CHANGES.txt?rev=1242140&r1=1242139&r2=1242140&view=diff
==============================================================================
--- avro/trunk/CHANGES.txt (original)
+++ avro/trunk/CHANGES.txt Wed Feb  8 22:13:50 2012
@@ -67,6 +67,9 @@ Avro 1.6.2 (unreleased)
     AVRO-1012. Java: Improve avro-service-archetype: POM and IT
     changes. (Lars Francke via scottcarey)
 
+    AVRO-971. Java: Permit IDL imports from classpath in Maven.
+    (Victor Chau via cutting)
+
   BUG FIXES
 
     AVRO-962. Java: Fix Maven plugin to support string type override.

Modified: avro/trunk/lang/java/avro/src/main/java/org/apache/avro/Protocol.java
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/avro/src/main/java/org/apache/avro/Protocol.java?rev=1242140&r1=1242139&r2=1242140&view=diff
==============================================================================
--- avro/trunk/lang/java/avro/src/main/java/org/apache/avro/Protocol.java (original)
+++ avro/trunk/lang/java/avro/src/main/java/org/apache/avro/Protocol.java Wed Feb  8 22:13:50 2012
@@ -19,6 +19,7 @@ package org.apache.avro;
 
 import java.io.ByteArrayInputStream;
 import java.io.File;
+import java.io.InputStream;
 import java.io.StringWriter;
 import java.io.IOException;
 import java.security.MessageDigest;
@@ -390,6 +391,11 @@ public class Protocol {
     return parse(Schema.FACTORY.createJsonParser(file));
   }
 
+  /** Read a protocol from a Json stream. */
+  public static Protocol parse(InputStream stream) throws IOException {
+    return parse(Schema.FACTORY.createJsonParser(stream));
+  }
+
   /** Read a protocol from a Json string. */
   public static Protocol parse(String string) {
     try {

Modified: avro/trunk/lang/java/compiler/src/main/javacc/org/apache/avro/compiler/idl/idl.jj
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/compiler/src/main/javacc/org/apache/avro/compiler/idl/idl.jj?rev=1242140&r1=1242139&r2=1242140&view=diff
==============================================================================
--- avro/trunk/lang/java/compiler/src/main/javacc/org/apache/avro/compiler/idl/idl.jj (original)
+++ avro/trunk/lang/java/compiler/src/main/javacc/org/apache/avro/compiler/idl/idl.jj Wed Feb  8 22:13:50 2012
@@ -88,6 +88,7 @@ public class Idl
   static JsonNodeFactory FACTORY = JsonNodeFactory.instance;
 
   File inputDir = new File(".");
+  ClassLoader resourceLoader = null;
   String namespace;
   Map<String,Schema> names = new LinkedHashMap<String,Schema>();
 
@@ -104,6 +105,11 @@ public class Idl
     this.inputDir = inputFile.getParentFile();
   }
 
+  public Idl(File inputFile, ClassLoader resourceLoader) throws IOException {
+    this(inputFile);
+    this.resourceLoader = resourceLoader;
+  }
+  
   private ParseException error(String message, Token token) {
     return new ParseException
       (message+", at line "+token.beginLine+", column "+token.beginColumn);
@@ -130,6 +136,24 @@ public class Idl
         throw error(key+" values must be textual: "+n, token);
     return values;
   }
+  
+  private InputStream findFile(String importFile) throws IOException {
+    InputStream stream = null;
+    //Load the file if it exist in the inputDir
+    File file = new File(this.inputDir, importFile);
+    if (file.exists()) {
+      stream = new FileInputStream(file);
+    }
+    else if (this.resourceLoader != null) {
+      //Otherwise look for it using the provided ClassLoader.
+      stream = this.resourceLoader.getResourceAsStream(importFile);
+    }
+
+    if (stream == null) {
+      throw new FileNotFoundException(importFile);
+    }
+    return stream;
+  }
 
 }
 
@@ -1139,7 +1163,12 @@ Protocol ImportIdl() : {
   <IDL> importFile = JsonString() ";"
     {
       try {
-        return new Idl(new File(inputDir, importFile)).CompilationUnit();
+        InputStream stream = findFile(importFile); 
+        try {
+          return new Idl(stream).CompilationUnit();
+        } finally {
+          stream.close();
+        }
       } catch (IOException e) {
         throw error("Error importing "+importFile+": "+e, token);
       }        
@@ -1154,7 +1183,12 @@ Protocol ImportProtocol() : {
     {
 
       try {
-        return Protocol.parse(new File(inputDir, importFile));
+        InputStream stream = findFile(importFile);
+        try {
+          return Protocol.parse(stream);
+        } finally {
+          stream.close();
+        }
       } catch (IOException e) {
         throw error("Error importing "+importFile+": "+e, token);
       }        
@@ -1170,9 +1204,14 @@ Schema ImportSchema() : {
       try {
         Parser parser = new Schema.Parser();
         parser.addTypes(names);                   // inherit names
-        Schema value = parser.parse(new File(inputDir, importFile));
-        names = parser.getTypes();                // update names
-        return value;
+        InputStream stream = findFile(importFile);
+        try {
+          Schema value = parser.parse(stream);
+          names = parser.getTypes();                // update names
+          return value;
+        } finally {
+          stream.close();
+        }
       } catch (IOException e) {
         throw error("Error importing "+importFile+": "+e, token);
       }        

Modified: avro/trunk/lang/java/compiler/src/test/idl/input/import.avdl
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/compiler/src/test/idl/input/import.avdl?rev=1242140&r1=1242139&r2=1242140&view=diff
==============================================================================
--- avro/trunk/lang/java/compiler/src/test/idl/input/import.avdl (original)
+++ avro/trunk/lang/java/compiler/src/test/idl/input/import.avdl Wed Feb  8 22:13:50 2012
@@ -19,6 +19,12 @@
 @namespace("org.foo")
 protocol Import {
   import idl "reservedwords.avdl";
+  
+  //Note that this import is resolve via the classpath, not relative path.
+  import idl "OnTheClasspath.avdl";
+  import protocol "OnTheClasspath.avpr";
+  import schema "OnTheClasspath.avsc";
+  
   import schema "foo.avsc";
   import protocol "bar.avpr";
   

Modified: avro/trunk/lang/java/compiler/src/test/idl/output/import.avpr
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/compiler/src/test/idl/output/import.avpr?rev=1242140&r1=1242139&r2=1242140&view=diff
==============================================================================
--- avro/trunk/lang/java/compiler/src/test/idl/output/import.avpr (original)
+++ avro/trunk/lang/java/compiler/src/test/idl/output/import.avpr Wed Feb  8 22:13:50 2012
@@ -4,6 +4,21 @@
   "doc" : "* Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.",
   "types" : [ {
     "type" : "record",
+    "name" : "FromAfar",
+    "namespace" : "org.on.the.classpath",
+    "fields" : [ ]
+  }, {
+    "type" : "record",
+    "name" : "VeryFar",
+    "namespace" : "org.on.the.classpath",
+    "fields" : [ ]
+  }, {
+    "type" : "record",
+    "name" : "FarAway",
+    "namespace" : "org.on.the.classpath",
+    "fields" : [ ]
+  }, {
+    "type" : "record",
     "name" : "Foo",
     "fields" : [ {
       "name" : "x",

Added: avro/trunk/lang/java/compiler/src/test/idl/putOnClassPath/OnTheClasspath.avdl
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/compiler/src/test/idl/putOnClassPath/OnTheClasspath.avdl?rev=1242140&view=auto
==============================================================================
--- avro/trunk/lang/java/compiler/src/test/idl/putOnClassPath/OnTheClasspath.avdl (added)
+++ avro/trunk/lang/java/compiler/src/test/idl/putOnClassPath/OnTheClasspath.avdl Wed Feb  8 22:13:50 2012
@@ -0,0 +1,5 @@
+@namespace("org.on.the.classpath")
+protocol OnTheClasspath {
+	record FromAfar {
+	}
+}
\ No newline at end of file

Added: avro/trunk/lang/java/compiler/src/test/idl/putOnClassPath/OnTheClasspath.avpr
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/compiler/src/test/idl/putOnClassPath/OnTheClasspath.avpr?rev=1242140&view=auto
==============================================================================
--- avro/trunk/lang/java/compiler/src/test/idl/putOnClassPath/OnTheClasspath.avpr (added)
+++ avro/trunk/lang/java/compiler/src/test/idl/putOnClassPath/OnTheClasspath.avpr Wed Feb  8 22:13:50 2012
@@ -0,0 +1,11 @@
+{
+  "protocol" : "OnTheClasspath",
+  "namespace" : "org.on.the.classpath",
+  "types" : [ {
+    "type" : "record",
+    "name" : "VeryFar",
+    "fields" : [ ]
+  } ],
+  "messages" : {
+  }
+}
\ No newline at end of file

Added: avro/trunk/lang/java/compiler/src/test/idl/putOnClassPath/OnTheClasspath.avsc
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/compiler/src/test/idl/putOnClassPath/OnTheClasspath.avsc?rev=1242140&view=auto
==============================================================================
--- avro/trunk/lang/java/compiler/src/test/idl/putOnClassPath/OnTheClasspath.avsc (added)
+++ avro/trunk/lang/java/compiler/src/test/idl/putOnClassPath/OnTheClasspath.avsc Wed Feb  8 22:13:50 2012
@@ -0,0 +1,6 @@
+{
+  "type" : "record",
+  "name" : "FarAway",
+  "namespace" : "org.on.the.classpath",
+  "fields" : [ ]
+}
\ No newline at end of file

Modified: avro/trunk/lang/java/compiler/src/test/java/org/apache/avro/compiler/idl/TestIdl.java
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/compiler/src/test/java/org/apache/avro/compiler/idl/TestIdl.java?rev=1242140&r1=1242139&r2=1242140&view=diff
==============================================================================
--- avro/trunk/lang/java/compiler/src/test/java/org/apache/avro/compiler/idl/TestIdl.java (original)
+++ avro/trunk/lang/java/compiler/src/test/java/org/apache/avro/compiler/idl/TestIdl.java Wed Feb  8 22:13:50 2012
@@ -30,6 +30,8 @@ import java.io.FileInputStream;
 import java.io.FileWriter;
 import java.io.IOException;
 import java.io.InputStreamReader;
+import java.net.URL;
+import java.net.URLClassLoader;
 
 import org.apache.avro.Protocol;
 
@@ -122,7 +124,18 @@ public class TestIdl {
     }
 
     private String generate() throws Exception {
-      Idl parser = new Idl(in);
+      ClassLoader cl = Thread.currentThread().getContextClassLoader();
+
+      // Calculate the absolute path to src/test/resources/putOnClassPath/
+      File file = new File(".");
+      String currentWorkPath = file.toURI().toURL().toString();
+      String newPath = currentWorkPath + "src" + File.separator + "test"
+        + File.separator + "idl" + File.separator
+        + "putOnClassPath" + File.separator;
+      URL[] newPathURL = new URL[]{new URL(newPath)}; 
+      URLClassLoader ucl = new URLClassLoader(newPathURL, cl);
+
+      Idl parser = new Idl(in, ucl);
       Protocol p = parser.CompilationUnit();
       return p.toString(true);
     }

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=1242140&r1=1242139&r2=1242140&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 Wed Feb  8 22:13:50 2012
@@ -96,7 +96,7 @@ public abstract class AbstractAvroMojo e
    * @readonly
    * @required
    */
-  private MavenProject project;
+  protected MavenProject project;
 
   @Override
   public void execute() throws MojoExecutionException {

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=1242140&r1=1242139&r2=1242140&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 Wed Feb  8 22:13:50 2012
@@ -20,6 +20,9 @@ package org.apache.avro.mojo;
 
 import java.io.File;
 import java.io.IOException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.List;
 
 import org.apache.avro.Protocol;
 import org.apache.avro.compiler.idl.Idl;
@@ -27,10 +30,13 @@ import org.apache.avro.compiler.idl.Pars
 import org.apache.avro.compiler.specific.SpecificCompiler;
 import org.apache.avro.generic.GenericData;
 
+import org.apache.maven.artifact.DependencyResolutionRequiredException;
+
 /**
  * Generate Java classes and interfaces from AvroIDL files (.avdl)
  * 
  * @goal idl-protocol
+ * @requiresDependencyResolution runtime
  * @phase generate-sources
  */
 public class IDLProtocolMojo extends AbstractAvroMojo {
@@ -54,8 +60,18 @@ public class IDLProtocolMojo extends Abs
 
   @Override
   protected void doCompile(String filename, File sourceDirectory, File outputDirectory) throws IOException {
-    Idl parser = new Idl(new File(sourceDirectory, filename));
     try {
+      @SuppressWarnings("rawtypes")
+      List runtimeClasspathElements = project.getRuntimeClasspathElements();
+      URL[] runtimeUrls = new URL[runtimeClasspathElements.size()];
+      for (int i = 0; i < runtimeClasspathElements.size(); i++) {
+        String element = (String) runtimeClasspathElements.get(i);
+        runtimeUrls[i] = new File(element).toURI().toURL();
+      }
+      URLClassLoader projPathLoader = new URLClassLoader
+        (runtimeUrls, Thread.currentThread().getContextClassLoader());
+
+      Idl parser = new Idl(new File(sourceDirectory, filename), projPathLoader);
       Protocol p = parser.CompilationUnit();
       String json = p.toString(true);
       Protocol protocol = Protocol.parse(json);
@@ -65,6 +81,8 @@ public class IDLProtocolMojo extends Abs
       compiler.compileToDestination(null, outputDirectory);
     } catch (ParseException e) {
       throw new IOException(e);
+    } catch (DependencyResolutionRequiredException drre) {
+      throw new IOException(drre);
     }
   }