diff --git a/.classpath b/.classpath new file mode 100644 index 00000000..0bb7ad5c --- /dev/null +++ b/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..eb5a316c --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +target diff --git a/.project b/.project new file mode 100644 index 00000000..5951c0ec --- /dev/null +++ b/.project @@ -0,0 +1,23 @@ + + + maven-protoc-plugin + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.maven.ide.eclipse.maven2Builder + + + + + + org.eclipse.jdt.core.javanature + org.maven.ide.eclipse.maven2Nature + + diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000..9e4e32bc --- /dev/null +++ b/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,6 @@ +#Sun Jun 19 09:26:49 BST 2011 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.source=1.5 diff --git a/.settings/org.maven.ide.eclipse.prefs b/.settings/org.maven.ide.eclipse.prefs new file mode 100644 index 00000000..8fbf289a --- /dev/null +++ b/.settings/org.maven.ide.eclipse.prefs @@ -0,0 +1,8 @@ +#Sun Jun 19 09:26:48 BST 2011 +activeProfiles= +eclipse.preferences.version=1 +fullBuildGoals=process-test-resources +resolveWorkspaceProjects=true +resourceFilterGoals=process-resources resources\:testResources +skipCompilerPlugin=true +version=1 diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 00000000..f825d4f4 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) 2002-2011 Marco Tedone, Jemos + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/README b/README index 8d93cc5b..85f61fb0 100644 --- a/README +++ b/README @@ -1,86 +1,95 @@ -********************************************** -*** Maven Protocol Buffers (protoc) Plugin *** -********************************************** - -A minimal configuration to invoke this plugin would be: - - - 4.0.0 - com.mycompany.example - example-protoc - jar - 1.0-SNAPSHOT - protoc-example - - - - - org.apache.maven.plugins - maven-compiler-plugin - - 1.5 - 1.5 - - - - com.google.protobuf.tools - maven-protoc-plugin - - /usr/local/bin/protoc - - - - - compile - testCompile - - - - - - - - - - com.google.protobuf - protobuf-java - 2.3.0 - - - - - -You must: -+ Use Java 1.5 or newer due to the usage of Generics -+ Either ensure the "protoc" executable is in your PATH or set the - parameter to the correct location. -+ Define the executions you want (you probably don't need the testCompile - unless you have custom protocol buffer objects in your tests. -+ Include the dependency on protobuf-java or your compile will fail. - - -Once this is all done add your *.protoc files to the directory: src/main/proto - -Everything should then build with a: mvn clean install - - - - -You may also need to add the following to your settings.xml to download the -plugin: - - - - dtrott - http://maven.davidtrott.com/repository - - - -Normally this plug-in executes the protoc compilation on every execution -this can be overriden by setting: - true - -If you build on NFS you may also need the following setting: - 10000 - +********************************************** +*** Maven Protocol Buffers (protoc) Plugin *** +********************************************** + +A minimal configuration to invoke this plugin would be: + + + 4.0.0 + com.mycompany.example + example-protoc + jar + 1.0-SNAPSHOT + protoc-example + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.5 + 1.5 + + + + uk.co.jemos.maven.plugins.protoc + maven-jemosProtoc-plugin + + /usr/local/bin/protoc + + + + + compile + testCompile + + + + + + + + + + com.google.protobuf + protobuf-java + 2.3.0 + + + + + +You must: ++ Use Java 1.5 or newer due to the usage of Generics ++ Either ensure the "protoc" executable is in your PATH or set the + parameter to the correct location. ++ Define the executions you want (you probably don't need the testCompile + unless you have custom protocol buffer objects in your tests. ++ Include the dependency on protobuf-java or your compile will fail. + +You should: ++ Add the following to your Maven settings.xml file to be able to execute the plugin as: + + $ mvn jemosProtoc:generatePojos + + + uk.co.jemos.maven.plugins + + + +Once this is all done add your *.protoc files to the directory: src/main/proto + +Everything should then build with a: mvn clean install + + + + +You may also need to add the following to your settings.xml to download the +plugin: + + + + dtrott + http://maven.davidtrott.com/repository + + + +Normally this plug-in executes the protoc compilation on every execution +this can be overriden by setting: + true + +If you build on NFS you may also need the following setting: + 10000 + diff --git a/pom.xml b/pom.xml index 530576dd..498136bb 100644 --- a/pom.xml +++ b/pom.xml @@ -1,81 +1,172 @@ - - 4.0.0 - - com.google.protobuf.tools - maven-protoc-plugin - maven-plugin - Maven Protoc Plugin - 0.1.11-SNAPSHOT - - - 2.0.6 - - - - scm:git:git://github.com/dtrott/maven-protoc-plugin.git - - - - http://maven.davidtrott.com/repository - - dtrott-public - David Trott's Public Repository - file:///repositories/maven.davidtrott.com/release - - - dtrott-public - David Trott's Public Snapshot Repository - file:///repositories/maven.davidtrott.com/snapshot - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - - 1.5 - 1.5 - - - - - - - org.apache.maven.wagon - wagon-ftp - 1.0-beta-6 - - - - - - - junit - junit - 4.5 - test - - - org.apache.maven - maven-plugin-api - 2.0.9 - - - com.google.collections - google-collections - 0.8 - - - org.codehaus.plexus - plexus-utils - 1.5.4 - - - org.apache.maven - maven-project - 2.0.9 - - - + + 4.0.0 + + + org.sonatype.oss + oss-parent + 7 + + + uk.co.jemos.maven.plugins + maven-jemosProtoc-plugin + 0.0.1.RELEASE + maven-plugin + + maven-jemosProtoc-plugin + http://www.jemos.eu/projects/protomak + + + + Maven JemosProtoc Plugin runs under the MIT license + LICENSE.txt + + + + + JIRA + http://www.jemos.eu/jira + + + + Jenkins + http://www.jemos.eu/jenkins + + + + + protomak - Google Groups + http://groups.google.com/group/protomak + http://groups.google.com/group/protomak + + + + + scm:git clone git://github.com/mtedone/maven-protoc-plugin.git + scm:git git://github.com/mtedone/maven-protoc-plugin.git + + + + + mtedone + Marco Tedone + marco.tedone@gmail.com + Jemos + http://www.jemos.eu/projects/protomak + + Project Lead + Team Member + + UTC + http://tedone.typepad.com/blog/ + + + + + + www.jemos.eu/maven-jemosProtoc-plugin + scp://tedonema@thor/home/tedonema/runtime/www/projects/jemos-maven-plugins/maven-jemosProtoc-plugin + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.3.2 + + 1.5 + 1.5 + + + + org.apache.maven.plugins + maven-plugin-plugin + 2.5.1 + + + org.apache.maven + maven-plugin-registry + 2.0.9 + + + + + org.apache.maven.plugins + maven-site-plugin + 3.0-beta-3 + + + org.apache.maven.plugins + maven-project-info-reports-plugin + 2.3.1 + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.1 + + + sign-artifacts + deploy + + sign + + + + + + org.apache.maven.plugins + maven-assembly-plugin + 2.2 + + + assembly-project + deploy + + single + + + + + ${project.build.directory}/site/downloads + + src/main/assembly/project.xml + src/main/assembly/bin.xml + + + + + + + + + + org.apache.maven.wagon + wagon-ftp + 1.0-beta-6 + + + + + + + junit + junit + 4.5 + test + + + commons-io + commons-io + 1.2 + + + org.apache.maven + maven-plugin-api + 2.0.9 + + + diff --git a/src/main/assembly/bin.xml b/src/main/assembly/bin.xml new file mode 100644 index 00000000..d4a28194 --- /dev/null +++ b/src/main/assembly/bin.xml @@ -0,0 +1,34 @@ + + bin + + tar.gz + tar.bz2 + zip + + + + ${project.basedir} + / + + README* + LICENSE* + NOTICE* + + + + ${project.build.directory} + / + + *.jar + + + **/*.log + ${project.basedir}/.settings/ + ${project.basedir}/.classpath + ${project.basedir}/.project + + + + \ No newline at end of file diff --git a/src/main/assembly/project.xml b/src/main/assembly/project.xml new file mode 100644 index 00000000..c200ed91 --- /dev/null +++ b/src/main/assembly/project.xml @@ -0,0 +1,24 @@ + + project + + tar.gz + tar.bz2 + zip + + + + ${project.basedir} + / + true + + **/*.log + **/${project.build.directory}/** + ${project.basedir}/.settings/ + ${project.basedir}/.classpath + ${project.basedir}/.project + + + + \ No newline at end of file diff --git a/src/main/java/com/google/protobuf/maven/AbstractProtocMojo.java b/src/main/java/com/google/protobuf/maven/AbstractProtocMojo.java deleted file mode 100644 index 38931024..00000000 --- a/src/main/java/com/google/protobuf/maven/AbstractProtocMojo.java +++ /dev/null @@ -1,355 +0,0 @@ -package com.google.protobuf.maven; - -import com.google.common.collect.ImmutableSet; -import org.apache.maven.artifact.Artifact; -import org.apache.maven.artifact.repository.ArtifactRepository; -import org.apache.maven.plugin.AbstractMojo; -import org.apache.maven.plugin.MojoExecutionException; -import org.apache.maven.plugin.MojoFailureException; -import org.apache.maven.project.MavenProject; -import org.apache.maven.project.MavenProjectHelper; -import org.codehaus.plexus.util.cli.CommandLineException; -import org.codehaus.plexus.util.io.RawInputStreamFacade; - -import java.io.File; -import java.io.FilenameFilter; -import java.io.IOException; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.List; -import java.util.Set; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; - -import static com.google.common.base.Join.join; -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; -import static com.google.common.collect.Sets.newHashSet; -import static java.lang.String.format; -import static java.util.Arrays.asList; -import static java.util.Collections.list; -import static org.codehaus.plexus.util.FileUtils.cleanDirectory; -import static org.codehaus.plexus.util.FileUtils.copyStreamToFile; -import static org.codehaus.plexus.util.FileUtils.getFiles; - -/** - * Abstract Mojo implementation. - *

- * This class is extended by {@link com.google.protobuf.maven.ProtocCompileMojo} and - * {@link com.google.protobuf.maven.ProtocTestCompileMojo} in order to override the specific configuration for - * compiling the main or test classes respectively. - * - * @author Gregory Kick - * @author David Trott - * @author Brice Figureau - */ -abstract class AbstractProtocMojo extends AbstractMojo { - - private static final String PROTO_FILE_SUFFIX = ".proto"; - - private static final String DEFAULT_INCLUDES = "**/*" + PROTO_FILE_SUFFIX; - - /** - * The current Maven project. - * - * @parameter default-value="${project}" - * @readonly - * @required - */ - protected MavenProject project; - - /** - * A helper used to add resources to the project. - * - * @component - * @required - */ - protected MavenProjectHelper projectHelper; - - /** - * This is the path to the {@code protoc} executable. By default it will search the {@code $PATH}. - * - * @parameter default-value="protoc" - * @required - */ - private String protocExecutable; - - /** - * @parameter - */ - private File[] additionalProtoPathElements = new File[]{}; - - /** - * Since {@code protoc} cannot access jars, proto files in dependencies are extracted to this location - * and deleted on exit. This directory is always cleaned during execution. - * - * @parameter expression="${project.build.directory}/protoc-dependencies" - * @required - */ - private File temporaryProtoFileDirectory; - - /** - * This is the path to the local maven {@code repository}. - * - * @parameter default-value="${localRepository}" - * @required - */ - private ArtifactRepository localRepository; - - /** - * Set this to {@code false} to disable hashing of dependent jar paths. - *

- * This plugin expands jars on the classpath looking for embedded .proto files. - * Normally these paths are hashed (MD5) to avoid issues with long file names on windows. - * However if this property is set to {@code false} longer paths will be used. - * - * @parameter default-value="true" - * @required - */ - private boolean hashDependentPaths; - - /** - * @parameter - */ - private Set includes = ImmutableSet.of(DEFAULT_INCLUDES); - - /** - * @parameter - */ - private Set excludes = ImmutableSet.of(); - - /** - * @parameter - */ - private long staleMillis = 0; - - /** - * @parameter - */ - private boolean checkStaleness = false; - - /** - * Executes the mojo. - */ - public void execute() throws MojoExecutionException, MojoFailureException { - checkParameters(); - final File protoSourceRoot = getProtoSourceRoot(); - if (protoSourceRoot.exists()) { - try { - ImmutableSet protoFiles = findProtoFilesInDirectory(protoSourceRoot); - final File outputDirectory = getOutputDirectory(); - ImmutableSet outputFiles = findGeneratedFilesInDirectory(getOutputDirectory()); - - if (protoFiles.isEmpty()) { - getLog().info("No proto files to compile."); - } else if (checkStaleness && ((lastModified(protoFiles) + staleMillis) < lastModified(outputFiles))) { - getLog().info("Skipping compilation because target directory newer than sources."); - attachFiles(); - } else { - ImmutableSet derivedProtoPathElements = - makeProtoPathFromJars(temporaryProtoFileDirectory, getDependencyArtifactFiles()); - outputDirectory.mkdirs(); - - // Quick fix to fix issues with two mvn installs in a row (ie no clean) - cleanDirectory(outputDirectory); - - Protoc protoc = new Protoc.Builder(protocExecutable, outputDirectory) - .addProtoPathElement(protoSourceRoot) - .addProtoPathElements(derivedProtoPathElements) - .addProtoPathElements(asList(additionalProtoPathElements)) - .addProtoFiles(protoFiles) - .build(); - final int exitStatus = protoc.compile(); - if (exitStatus != 0) { - getLog().error("protoc failed output: " + protoc.getOutput()); - getLog().error("protoc failed error: " + protoc.getError()); - throw new MojoFailureException( - "protoc did not exit cleanly. Review output for more information."); - } - attachFiles(); - } - } catch (IOException e) { - throw new MojoExecutionException("An IO error occured", e); - } catch (IllegalArgumentException e) { - throw new MojoFailureException("protoc failed to execute because: " + e.getMessage(), e); - } catch (CommandLineException e) { - throw new MojoExecutionException("An error occurred while invoking protoc.", e); - } - } else { - getLog().info(format("%s does not exist. Review the configuration or consider disabling the plugin.", - protoSourceRoot)); - } - } - - ImmutableSet findGeneratedFilesInDirectory(File directory) throws IOException { - if (directory == null || !directory.isDirectory()) - return ImmutableSet.of(); - - // TODO(gak): plexus-utils needs generics - @SuppressWarnings("unchecked") - List javaFilesInDirectory = getFiles(directory, "**/*.java", null); - return ImmutableSet.copyOf(javaFilesInDirectory); - } - - private long lastModified(ImmutableSet files) { - long result = 0; - for (File file : files) { - if (file.lastModified() > result) - result = file.lastModified(); - } - return result; - } - - private void checkParameters() { - checkNotNull(project, "project"); - checkNotNull(projectHelper, "projectHelper"); - checkNotNull(protocExecutable, "protocExecutable"); - final File protoSourceRoot = getProtoSourceRoot(); - checkNotNull(protoSourceRoot); - checkArgument(!protoSourceRoot.isFile(), "protoSourceRoot is a file, not a diretory"); - checkNotNull(temporaryProtoFileDirectory, "temporaryProtoFileDirectory"); - checkState(!temporaryProtoFileDirectory.isFile(), "temporaryProtoFileDirectory is a file, not a directory"); - final File outputDirectory = getOutputDirectory(); - checkNotNull(outputDirectory); - checkState(!outputDirectory.isFile(), "the outputDirectory is a file, not a directory"); - } - - protected abstract File getProtoSourceRoot(); - - protected abstract List getDependencyArtifacts(); - - protected abstract File getOutputDirectory(); - - protected abstract void attachFiles(); - - /** - * Gets the {@link File} for each dependency artifact. - * - * @return A set of all dependency artifacts. - */ - private ImmutableSet getDependencyArtifactFiles() { - Set dependencyArtifactFiles = newHashSet(); - for (Artifact artifact : getDependencyArtifacts()) { - dependencyArtifactFiles.add(artifact.getFile()); - } - return ImmutableSet.copyOf(dependencyArtifactFiles); - } - - /** - * @throws IOException - */ - ImmutableSet makeProtoPathFromJars(File temporaryProtoFileDirectory, Iterable classpathElementFiles) - throws IOException, MojoExecutionException { - checkNotNull(classpathElementFiles, "classpathElementFiles"); - // clean the temporary directory to ensure that stale files aren't used - if (temporaryProtoFileDirectory.exists()) { - cleanDirectory(temporaryProtoFileDirectory); - } - Set protoDirectories = newHashSet(); - for (File classpathElementFile : classpathElementFiles) { - // for some reason under IAM, we receive poms as dependent files - // I am excluding .xml rather than including .jar as there may be other extensions in use (sar, har, zip) - if (classpathElementFile.isFile() && classpathElementFile.canRead() && - !classpathElementFile.getName().endsWith(".xml")) { - - // create the jar file. the constructor validates. - JarFile classpathJar; - try { - classpathJar = new JarFile(classpathElementFile); - } catch (IOException e) { - throw new IllegalArgumentException(format( - "%s was not a readable artifact", classpathElementFile)); - } - for (JarEntry jarEntry : list(classpathJar.entries())) { - final String jarEntryName = jarEntry.getName(); - if (jarEntry.getName().endsWith(PROTO_FILE_SUFFIX)) { - final File uncompressedCopy = - new File(new File(temporaryProtoFileDirectory, - truncatePath(classpathJar.getName())), jarEntryName); - uncompressedCopy.getParentFile().mkdirs(); - copyStreamToFile(new RawInputStreamFacade(classpathJar - .getInputStream(jarEntry)), uncompressedCopy); - protoDirectories.add(uncompressedCopy.getParentFile()); - } - } - } else if (classpathElementFile.isDirectory()) { - File[] protoFiles = classpathElementFile.listFiles(new FilenameFilter() { - public boolean accept(File dir, String name) { - return name.endsWith(PROTO_FILE_SUFFIX); - } - }); - - if (protoFiles.length > 0) { - protoDirectories.add(classpathElementFile); - } - } - } - return ImmutableSet.copyOf(protoDirectories); - } - - ImmutableSet findProtoFilesInDirectory(File directory) throws IOException { - checkNotNull(directory); - checkArgument(directory.isDirectory(), "%s is not a directory", directory); - // TODO(gak): plexus-utils needs generics - @SuppressWarnings("unchecked") - List protoFilesInDirectory = getFiles(directory, join(",", includes), join(",", excludes)); - return ImmutableSet.copyOf(protoFilesInDirectory); - } - - ImmutableSet findProtoFilesInDirectories(Iterable directories) throws IOException { - checkNotNull(directories); - Set protoFiles = newHashSet(); - for (File directory : directories) { - protoFiles.addAll(findProtoFilesInDirectory(directory)); - } - return ImmutableSet.copyOf(protoFiles); - } - - /** - * Truncates the path of jar files so that they are relative to the local repository. - * - * @param jarPath the full path of a jar file. - * @return the truncated path relative to the local repository or root of the drive. - */ - String truncatePath(final String jarPath) throws MojoExecutionException { - - if (hashDependentPaths) { - try { - return toHexString(MessageDigest.getInstance("MD5").digest(jarPath.getBytes())); - } catch (NoSuchAlgorithmException e) { - throw new MojoExecutionException("Failed to expand dependent jar", e); - } - } - - String repository = localRepository.getBasedir().replace('\\', '/'); - if (!repository.endsWith("/")) { - repository += "/"; - } - - String path = jarPath.replace('\\', '/'); - int repositoryIndex = path.indexOf(repository); - if (repositoryIndex != -1) { - path = path.substring(repositoryIndex + repository.length()); - } - - // By now the path should be good, but do a final check to fix windows machines. - int colonIndex = path.indexOf(':'); - if (colonIndex != -1) { - // 2 = :\ in C:\ - path = path.substring(colonIndex + 2); - } - - return path; - } - - private static final char[] HEX_CHARS = "0123456789abcdef".toCharArray(); - - public static String toHexString(byte[] byteArray) { - final StringBuilder hexString = new StringBuilder(2 * byteArray.length); - for (final byte b : byteArray) { - hexString.append(HEX_CHARS[(b & 0xF0) >> 4]).append(HEX_CHARS[b & 0x0F]); - } - return hexString.toString(); - } -} diff --git a/src/main/java/com/google/protobuf/maven/Protoc.java b/src/main/java/com/google/protobuf/maven/Protoc.java deleted file mode 100644 index 7f66742d..00000000 --- a/src/main/java/com/google/protobuf/maven/Protoc.java +++ /dev/null @@ -1,216 +0,0 @@ -package com.google.protobuf.maven; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; -import org.codehaus.plexus.util.cli.CommandLineException; -import org.codehaus.plexus.util.cli.CommandLineUtils; -import org.codehaus.plexus.util.cli.Commandline; - -import java.io.File; -import java.util.List; -import java.util.Set; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; -import static com.google.common.collect.Lists.newLinkedList; -import static com.google.common.collect.Sets.newHashSet; - -/** - * This class represents an invokable configuration of the {@code protoc} - * compiler. The actual executable is invoked using the plexus - * {@link Commandline}. - *

- * This class currently only supports generating java source files. - * - * @author gak@google.com (Gregory Kick) - */ -final class Protoc { - private final String executable; - private final ImmutableSet protoPathElements; - private final ImmutableSet protoFiles; - private final File javaOutputDirectory; - private final CommandLineUtils.StringStreamConsumer output; - private final CommandLineUtils.StringStreamConsumer error; - - /** - * Constructs a new instance. This should only be used by the {@link Builder}. - * - * @param executable The path to the {@code protoc} executable. - * @param protoPath The directories in which to search for imports. - * @param protoFiles The proto source files to compile. - * @param javaOutputDirectory The directory into which the java source files - * will be generated. - */ - private Protoc(String executable, ImmutableSet protoPath, - ImmutableSet protoFiles, File javaOutputDirectory) { - this.executable = checkNotNull(executable, "executable"); - this.protoPathElements = checkNotNull(protoPath, "protoPath"); - this.protoFiles = checkNotNull(protoFiles, "protoFiles"); - this.javaOutputDirectory = checkNotNull(javaOutputDirectory, "javaOutputDirectory"); - this.error = new CommandLineUtils.StringStreamConsumer(); - this.output = new CommandLineUtils.StringStreamConsumer(); - } - - /** - * Invokes the {@code protoc} compiler using the configuration specified at - * construction. - * - * @return The exit status of {@code protoc}. - * @throws CommandLineException - */ - public int compile() throws CommandLineException { - Commandline cl = new Commandline(); - cl.setExecutable(executable); - cl.addArguments(buildProtocCommand().toArray(new String[]{})); - return CommandLineUtils.executeCommandLine(cl, null, output, error); - } - - /** - * Creates the command line arguments. - *

- * This method has been made visible for testing only. - * - * @return A list consisting of the executable followed by any arguments. - */ - ImmutableList buildProtocCommand() { - final List command = newLinkedList(); - // add the executable - for (File protoPathElement : protoPathElements) { - command.add("--proto_path=" + protoPathElement); - } - command.add("--java_out=" + javaOutputDirectory); - for (File protoFile : protoFiles) { - command.add(protoFile.toString()); - } - return ImmutableList.copyOf(command); - } - - /** - * @return the output - */ - public String getOutput() { - return output.getOutput(); - } - - /** - * @return the error - */ - public String getError() { - return error.getOutput(); - } - - /** - * This class builds {@link Protoc} instances. - * - * @author gak@google.com (Gregory Kick) - */ - static final class Builder { - private final String executable; - private final File javaOutputDirectory; - private Set protopathElements; - private Set protoFiles; - - /** - * Constructs a new builder. The two parameters are present as they are - * required for all {@link Protoc} instances. - * - * @param executable The path to the {@code protoc} executable. - * @param javaOutputDirectory The directory into which the java source files - * will be generated. - * @throws NullPointerException If either of the arguments are {@code null}. - * @throws IllegalArgumentException If the {@code javaOutputDirectory} is - * not a directory. - */ - public Builder(String executable, File javaOutputDirectory) { - this.executable = checkNotNull(executable, "executable"); - this.javaOutputDirectory = checkNotNull(javaOutputDirectory); - checkArgument(javaOutputDirectory.isDirectory()); - this.protoFiles = newHashSet(); - this.protopathElements = newHashSet(); - } - - /** - * Adds a proto file to be compiled. Proto files must be on the protopath - * and this method will fail if a proto file is added without first adding a - * parent directory to the protopath. - * - * @param protoFile - * @return The builder. - * @throws IllegalStateException If a proto file is added without first - * adding a parent directory to the protopath. - * @throws NullPointerException If {@code protoFile} is {@code null}. - */ - public Builder addProtoFile(File protoFile) { - checkNotNull(protoFile); - checkArgument(protoFile.isFile()); - checkArgument(protoFile.getName().endsWith(".proto")); - checkProtoFileIsInProtopath(protoFile); - protoFiles.add(protoFile); - return this; - } - - private void checkProtoFileIsInProtopath(File protoFile) { - assert protoFile.isFile(); - checkState(checkProtoFileIsInProtopathHelper(protoFile.getParentFile())); - } - - private boolean checkProtoFileIsInProtopathHelper(File directory) { - assert directory.isDirectory(); - if (protopathElements.contains(directory)) { - return true; - } else { - final File parentDirectory = directory.getParentFile(); - return (parentDirectory == null) ? false - : checkProtoFileIsInProtopathHelper(parentDirectory); - } - } - - /** - * @see #addProtoFile(File) - */ - public Builder addProtoFiles(Iterable protoFiles) { - for (File protoFile : protoFiles) { - addProtoFile(protoFile); - } - return this; - } - - /** - * Adds the {@code protopathElement} to the protopath. - * - * @param protopathElement A directory to be searched for imported protocol - * buffer definitions. - * @return The builder. - * @throws NullPointerException If {@code protopathElement} is {@code null}. - * @throws IllegalArgumentException If {@code protpathElement} is not a - * directory. - */ - public Builder addProtoPathElement(File protopathElement) { - checkNotNull(protopathElement); - checkArgument(protopathElement.isDirectory()); - protopathElements.add(protopathElement); - return this; - } - - /** - * @see #addProtoPathElement(File) - */ - public Builder addProtoPathElements(Iterable protopathElements) { - for (File protopathElement : protopathElements) { - addProtoPathElement(protopathElement); - } - return this; - } - - /** - * @return A configured {@link Protoc} instance. - * @throws IllegalStateException If no proto files have been added. - */ - public Protoc build() { - checkState(!protoFiles.isEmpty()); - return new Protoc(executable, ImmutableSet.copyOf(protopathElements), - ImmutableSet.copyOf(protoFiles), javaOutputDirectory); - } - } -} diff --git a/src/main/java/com/google/protobuf/maven/ProtocCompileMojo.java b/src/main/java/com/google/protobuf/maven/ProtocCompileMojo.java deleted file mode 100644 index a37ea5b9..00000000 --- a/src/main/java/com/google/protobuf/maven/ProtocCompileMojo.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.google.protobuf.maven; - -import com.google.common.collect.ImmutableList; -import org.apache.maven.artifact.Artifact; - -import java.io.File; -import java.util.List; - -/** - * This mojo executes the {@code protoc} compiler for generating java sources - * from protocol buffer definitions. It also searches dependency artifacts for - * proto files and includes them in the protopath so that they can be - * referenced. Finally, it adds the proto files to the project as resources so - * that they are included in the final artifact. - * - * @phase generate-sources - * @goal compile - * @requiresDependencyResolution compile - */ - -public final class ProtocCompileMojo extends AbstractProtocMojo { - - /** - * The source directories containing the sources to be compiled. - * - * @parameter default-value="${basedir}/src/main/proto" - * @required - */ - private File protoSourceRoot; - - /** - * This is the directory into which the {@code .java} will be created. - * - * @parameter default-value="${project.build.directory}/generated-sources/protoc" - * @required - */ - private File outputDirectory; - - @Override - protected List getDependencyArtifacts() { - // TODO(gak): maven-project needs generics - @SuppressWarnings("unchecked") - List compileArtifacts = project.getCompileArtifacts(); - return compileArtifacts; - } - - @Override - protected File getOutputDirectory() { - return outputDirectory; - } - - @Override - protected File getProtoSourceRoot() { - return protoSourceRoot; - } - - @Override - protected void attachFiles() { - project.addCompileSourceRoot(outputDirectory.getAbsolutePath()); - projectHelper.addResource(project, protoSourceRoot.getAbsolutePath(), - ImmutableList.of("**/*.proto"), ImmutableList.of()); - } -} diff --git a/src/main/java/com/google/protobuf/maven/ProtocTestCompileMojo.java b/src/main/java/com/google/protobuf/maven/ProtocTestCompileMojo.java deleted file mode 100644 index 3c1c523d..00000000 --- a/src/main/java/com/google/protobuf/maven/ProtocTestCompileMojo.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.google.protobuf.maven; - -import com.google.common.collect.ImmutableList; -import org.apache.maven.artifact.Artifact; - -import java.io.File; -import java.util.List; - -/** - * @phase generate-test-sources - * @goal testCompile - * @requiresDependencyResolution test - */ -public final class ProtocTestCompileMojo extends AbstractProtocMojo { - - /** - * The source directories containing the sources to be compiled. - * - * @parameter default-value="${basedir}/src/test/proto" - * @required - */ - private File protoTestSourceRoot; - - /** - * This is the directory into which the {@code .java} will be created. - * - * @parameter default-value="${project.build.directory}/generated-test-sources/protoc" - * @required - */ - private File outputDirectory; - - @Override - protected void attachFiles() { - project.addTestCompileSourceRoot(outputDirectory.getAbsolutePath()); - projectHelper.addTestResource(project, protoTestSourceRoot.getAbsolutePath(), - ImmutableList.of("**/*.proto"), ImmutableList.of()); - } - - @Override - protected List getDependencyArtifacts() { - // TODO(gak): maven-project needs generics - @SuppressWarnings("unchecked") - List testArtifacts = project.getTestArtifacts(); - return testArtifacts; - } - - @Override - protected File getOutputDirectory() { - return outputDirectory; - } - - @Override - protected File getProtoSourceRoot() { - return protoTestSourceRoot; - } - -} diff --git a/src/main/java/uk/co/jemos/maven/plugins/protoc/GeneratePojosMojo.java b/src/main/java/uk/co/jemos/maven/plugins/protoc/GeneratePojosMojo.java new file mode 100644 index 00000000..dc69e26c --- /dev/null +++ b/src/main/java/uk/co/jemos/maven/plugins/protoc/GeneratePojosMojo.java @@ -0,0 +1,118 @@ +package uk.co.jemos.maven.plugins.protoc; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FilenameFilter; +import java.io.IOException; +import java.io.InputStreamReader; + +import org.apache.commons.io.IOUtils; +import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.plugin.MojoExecutionException; + +import uk.co.jemos.maven.plugins.utils.JemosProtocPluginUtils; + +/** + * Goal which triggers the generation of proto files from an XSD file + * + * @goal generatePojos + * + * @phase process-sources + * + * @requiresDependencyResolution compile + */ +public class GeneratePojosMojo extends AbstractMojo { + + /** + * Location of the file. + * + * @parameter expression="${inputFolder}" + * @required + */ + private File inputFolder; + + /** + * The location where the generated files will be placed. + * + * @parameter expression="${outputFolder}" + * @required + */ + private File outputFolder; + + /** + * The full path to the protoc compiler executable + * + * @parameter expression="${protocExecutable}" + * + */ + private String protocExecutable; + + private final FilenameFilter PROTO_FILENAME_FILTER = new FilenameFilter() { + + public boolean accept(File dir, String name) { + + return name.endsWith(JemosProtocPluginUtils.PROTO_SUFFIX); + } + }; + + public void execute() throws MojoExecutionException { + + if (protocExecutable == null) { + protocExecutable = JemosProtocPluginUtils.PROTOC_EXECUTABLE; + } + + if (!outputFolder.exists() || !outputFolder.isDirectory()) { + getLog().info("Folder: " + outputFolder + " does not exist. Creating one..."); + outputFolder.mkdirs(); + getLog().info("Folder: " + outputFolder + " created."); + } + + String outputFolderPath = outputFolder.getAbsolutePath().replace('\\', '/'); + + String inputFolderPath = inputFolder.getAbsolutePath().replace('\\', '/'); + if (!inputFolderPath.endsWith("/")) { + inputFolderPath += "/"; + } + + StringBuilder buff = new StringBuilder(); + buff.append("Protoc executable: " + protocExecutable + "\n"); + buff.append("Input Folder: " + inputFolderPath + "\n"); + buff.append("Output folder: " + outputFolderPath + "\n"); + + getLog().info(buff.toString()); + + buff.setLength(0); + + buff.append(protocExecutable).append(" --proto_path=").append(inputFolderPath).append(" ") + .append(inputFolderPath).append("*.proto ").append("--java_out=") + .append(outputFolderPath); + + getLog().info("Will execute: " + buff.toString()); + + BufferedReader reader = null; + + try { + + Process p = Runtime.getRuntime().exec(buff.toString()); + p.waitFor(); + reader = new BufferedReader(new InputStreamReader(p.getInputStream())); + String line = null; + while ((line = reader.readLine()) != null) { + getLog().info(line); + } + + getLog().info("Command: " + buff.toString() + " executed successfully."); + + } catch (IOException e) { + throw new MojoExecutionException( + "An error occurred while executing the protoc command", e); + + } catch (InterruptedException e) { + throw new MojoExecutionException( + "An error occurred while executing the protoc command", e); + } finally { + IOUtils.closeQuietly(reader); + } + + } +} diff --git a/src/main/java/uk/co/jemos/maven/plugins/utils/JemosProtocPluginUtils.java b/src/main/java/uk/co/jemos/maven/plugins/utils/JemosProtocPluginUtils.java new file mode 100644 index 00000000..a05e5ab9 --- /dev/null +++ b/src/main/java/uk/co/jemos/maven/plugins/utils/JemosProtocPluginUtils.java @@ -0,0 +1,24 @@ +/** + * + */ +package uk.co.jemos.maven.plugins.utils; + + +/** + * @author mtedone + * + */ +public class JemosProtocPluginUtils { + + /** The proto extension */ + public static final String PROTO_SUFFIX = ".proto"; + + /** The name of the protoc compiler */ + public static final String PROTOC_EXECUTABLE = "protoc"; + + /** Non instantiable */ + private JemosProtocPluginUtils() { + + } + +} diff --git a/src/thrift.sed b/src/thrift.sed deleted file mode 100644 index 8895c0dd..00000000 --- a/src/thrift.sed +++ /dev/null @@ -1,7 +0,0 @@ -s/com.google.protobuf/org.apache.thrift/g -s/protobuf/thrift/g -s/Protoc/Thrift/g -s/Proto/Thrift/g -s/protoc/thrift/g -s/proto/thrift/g -s/PROTO/THRIFT/g