001/******************************************************************************* 002 * Copyright (c) 2017 Red Hat Inc 003 * All rights reserved. This program and the accompanying materials 004 * are made available under the terms of the Eclipse Public License v1.0 005 * which accompanies this distribution, and is available at 006 * http://www.eclipse.org/legal/epl-v10.html 007 * 008 * Contributors: 009 * Jens Reimann - initial API and implementation 010 *******************************************************************************/ 011package de.dentrassi.varlink.maven; 012 013import static java.nio.file.Files.walkFileTree; 014 015import java.io.File; 016import java.io.IOException; 017import java.nio.charset.Charset; 018import java.nio.file.FileVisitResult; 019import java.nio.file.Path; 020import java.nio.file.SimpleFileVisitor; 021import java.nio.file.attribute.BasicFileAttributes; 022import java.util.HashMap; 023import java.util.List; 024import java.util.Map; 025 026import org.apache.maven.plugin.AbstractMojo; 027import org.apache.maven.plugin.MojoExecutionException; 028import org.apache.maven.plugin.MojoFailureException; 029import org.apache.maven.plugins.annotations.Component; 030import org.apache.maven.plugins.annotations.LifecyclePhase; 031import org.apache.maven.plugins.annotations.Mojo; 032import org.apache.maven.plugins.annotations.Parameter; 033import org.apache.maven.project.MavenProject; 034import org.eclipse.emf.ecore.resource.Resource.Diagnostic; 035import org.sonatype.plexus.build.incremental.BuildContext; 036 037import de.dentrassi.varlink.generator.Generator; 038import de.dentrassi.varlink.generator.JdtGenerator; 039 040/** 041 * Generate Java bindings for a Varlink file 042 */ 043@Mojo(defaultPhase = LifecyclePhase.GENERATE_SOURCES, name = "generate", requiresProject = true) 044public class GenerateMojo extends AbstractMojo { 045 046 /** 047 * Allows to skip the generation 048 */ 049 @Parameter(property = "varlink.skip", required = false, defaultValue = "false") 050 private boolean skip; 051 052 public void setSkip(final boolean skip) { 053 this.skip = skip; 054 } 055 056 public boolean isSkip() { 057 return this.skip; 058 } 059 060 /** 061 * The character set to use for the generated resources 062 */ 063 @Parameter(property = "varlink.generator.charset", required = true, defaultValue = "${project.build.sourceEncoding}") 064 private String characterSet; 065 066 public void setCharacterSet(final String characterSet) { 067 this.characterSet = characterSet; 068 } 069 070 public String getCharacterSet() { 071 return this.characterSet; 072 } 073 074 /** 075 * The path to generate the sources to 076 */ 077 @Parameter(required = true, property = "varlink.targetPath", defaultValue = "${project.build.directory}/generated-sources/varlink") 078 private File targetPath; 079 080 public void setTargetPath(final File targetPath) { 081 this.targetPath = targetPath; 082 } 083 084 public File getTargetPath() { 085 return this.targetPath; 086 } 087 088 /** 089 * The path to load the sources from 090 */ 091 @Parameter(required = true, property = "varlink.sourcePath", defaultValue = "${basedir}/src/main/varlink") 092 private File sourcePath; 093 094 public void setSourcePath(final File sourcePath) { 095 this.sourcePath = sourcePath; 096 } 097 098 public File getSourcePath() { 099 return this.sourcePath; 100 } 101 102 @Parameter(property = "project", readonly = true, required = true) 103 protected MavenProject project; 104 105 public void setProject(final MavenProject project) { 106 this.project = project; 107 } 108 109 @Component 110 private BuildContext buildContext; 111 112 public void setBuildContext(final BuildContext buildContext) { 113 this.buildContext = buildContext; 114 } 115 116 @Override 117 public void execute() throws MojoExecutionException, MojoFailureException { 118 119 try { 120 121 // load interfaces 122 123 final Loader loader = new Loader(); 124 125 final Map<String, List<Diagnostic>> errors = new HashMap<>(); 126 127 walkFileTree( 128 this.sourcePath.toPath(), 129 new SimpleFileVisitor<Path>() { 130 @Override 131 public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs) 132 throws IOException { 133 134 final List<Diagnostic> localErrors = loader.loadFrom(file); 135 if (!localErrors.isEmpty()) { 136 errors.put(file.toString(), localErrors); 137 } 138 139 return FileVisitResult.CONTINUE; 140 } 141 }); 142 143 // process errors 144 145 if (!errors.isEmpty()) { 146 for (final Map.Entry<String, List<Diagnostic>> entry : errors.entrySet()) { 147 for (final Diagnostic diag : entry.getValue()) { 148 String location = diag.getLocation(); 149 if (location == null) { 150 location = entry.getKey(); 151 } 152 getLog().error(String.format("%s:%s:%s: %s", location, diag.getLine(), 153 diag.getColumn(), diag.getMessage())); 154 } 155 } 156 throw new MojoFailureException("Failed to validate models. See log for more information."); 157 } 158 159 // setup generator 160 161 final Generator.Options options = new Generator.Options(); 162 163 if (this.characterSet != null) { 164 options.setCharacterSet(Charset.forName(this.characterSet)); 165 } 166 if (this.targetPath != null) { 167 options.setTargetPath(this.targetPath.toPath()); 168 } 169 170 final Generator generator = new JdtGenerator(options); 171 172 // generate 173 174 generator.generateAll(loader); 175 176 // add sources 177 178 this.project.addCompileSourceRoot(this.targetPath.getAbsolutePath()); 179 this.buildContext.refresh(this.targetPath.getAbsoluteFile()); 180 181 } catch (final Exception e) { 182 throw new MojoExecutionException("Failed to generate", e); 183 } 184 185 } 186}