001 /**************************************************************************************
002 * Copyright (C) 2009 Progress Software, Inc. All rights reserved. *
003 * http://fusesource.com *
004 * ---------------------------------------------------------------------------------- *
005 * The software in this package is published under the terms of the AGPL license *
006 * a copy of which has been included with this distribution in the license.txt file. *
007 **************************************************************************************/
008 package org.fusesource.mvnplugins.avro;
009
010 import java.io.File;
011 import java.io.FileFilter;
012 import java.io.FileWriter;
013 import java.io.IOException;
014 import java.io.Writer;
015
016 import org.apache.avro.specific.SpecificCompiler;
017 import org.apache.maven.plugin.AbstractMojo;
018 import org.apache.maven.plugin.MojoExecutionException;
019 import org.apache.maven.project.MavenProject;
020
021 /**
022 * A Maven Mojo so that the Avro compiler can be used with maven.
023 *
024 * @goal compile
025 * @phase process-sources
026
027 * @author <a href="http://hiramchirino.com">Hiram Chirino</a>
028 */
029 public class AvroMojo extends AbstractMojo {
030
031 /**
032 * The maven project.
033 *
034 * @parameter expression="${project}"
035 * @required
036 * @readonly
037 */
038 protected MavenProject project;
039
040 /**
041 * The directory where the Avro files (<code>*.avpr</code> or <code>*.avsc</code>) are
042 * located.
043 *
044 * @parameter default-value="${basedir}/src/main/avro"
045 */
046 private File mainSourceDirectory;
047
048 /**
049 * The directory where the output files will be located.
050 *
051 * @parameter default-value="${project.build.directory}/generated-sources/avro"
052 */
053 private File mainOutputDirectory;
054
055 /**
056 * The directory where the Avro files (<code>*.avpr</code> or <code>*.avsc</code>) are
057 * located.
058 *
059 * @parameter default-value="${basedir}/src/test/avro"
060 */
061 private File testSourceDirectory;
062
063 /**
064 * The directory where the output files will be located.
065 *
066 * @parameter default-value="${project.build.directory}/test-generated-sources/avro"
067 */
068 private File testOutputDirectory;
069
070 public void execute() throws MojoExecutionException {
071
072 File[] mainFiles = null;
073 if ( mainSourceDirectory.exists() ) {
074 mainFiles = mainSourceDirectory.listFiles(new FileFilter() {
075 public boolean accept(File pathname) {
076 String name = pathname.getName();
077 return name.endsWith(".avsc") || name.endsWith(".avpr");
078 }
079 });
080 if (mainFiles==null || mainFiles.length==0) {
081 getLog().warn("No avro files found in directory: " + mainSourceDirectory.getPath());
082 } else {
083 processFiles(mainFiles, mainOutputDirectory);
084 this.project.addCompileSourceRoot(mainOutputDirectory.getAbsolutePath());
085 }
086 }
087
088 File[] testFiles = null;
089 if ( testSourceDirectory.exists() ) {
090 testFiles = testSourceDirectory.listFiles(new FileFilter() {
091 public boolean accept(File pathname) {
092 String name = pathname.getName();
093 return name.endsWith(".avsc") || name.endsWith(".avpr");
094 }
095 });
096 if (testFiles==null || testFiles.length==0) {
097 getLog().warn("No avro files found in directory: " + testSourceDirectory.getPath());
098 } else {
099 processFiles(testFiles, testOutputDirectory);
100 this.project.addTestCompileSourceRoot(testOutputDirectory.getAbsolutePath());
101 }
102 }
103 }
104
105
106 static private String uCamel(String name) {
107 boolean upNext=true;
108 StringBuilder sb = new StringBuilder();
109 for (int i = 0; i < name.length(); i++) {
110 char c = name.charAt(i);
111 if( Character.isJavaIdentifierPart(c) && Character.isLetterOrDigit(c)) {
112 if( upNext ) {
113 c = Character.toUpperCase(c);
114 upNext=false;
115 }
116 sb.append(c);
117 } else {
118 upNext=true;
119 }
120 }
121 return sb.toString();
122 }
123
124 private void processFiles(File[] mainFiles, File outputDir) throws MojoExecutionException {
125 for (File file : mainFiles) {
126 try {
127
128 getLog().info("Compiling: "+file.getPath());
129 SpecificCompiler compiler;
130 if( file.getName().endsWith(".avpr") ) {
131 compiler = SpecificCompiler.compileProtocol(file);
132 } else if( file.getName().endsWith(".avsc") ) {
133 compiler = SpecificCompiler.compileSchema(file);
134 } else {
135 throw new RuntimeException("Unhandled file type: "+file.getName());
136 }
137
138 String targetName = file.getName();
139 targetName = targetName.substring(0, targetName.indexOf('.'));
140 targetName = uCamel(targetName)+ ".java";
141
142 File target;
143
144 String namespace = compiler.getNamespace();
145 if (namespace == null || namespace.length() == 0) {
146 target = new File(outputDir, targetName);
147 } else {
148 target = new File(new File(outputDir, namespace.replace('.', File.separatorChar)), targetName);
149 }
150 target.getParentFile().mkdirs();
151
152 getLog().info(" writting: "+target.getPath());
153
154 Writer out = new FileWriter(target);
155 try {
156 out.write(compiler.getCode());
157 } finally {
158 out.close();
159 }
160
161 } catch (IOException e) {
162 throw new MojoExecutionException("Avro compile failed.", e);
163 }
164 }
165 }
166
167 }