pluginArtifacts;
+
+ /**
+ * Specify the directory where to place generated source files (same behaviour of -s option)
+ */
+ @Parameter
+ private File outputDirectory;
+
+ /**
+ *
+ * Classpath elements to supply as annotation processor path. If specified, the compiler will detect annotation
+ * processors only in those classpath elements. If omitted, the default classpath is used to detect annotation
+ * processors. The detection itself depends on the configuration of {@code processors}.
+ *
+ *
+ * Each classpath element is specified using their Maven coordinates (groupId, artifactId, version, classifier,
+ * type). Transitive dependencies are added automatically. Example:
+ *
+ *
+ *
+ * <configuration>
+ * <annotationProcessorPaths>
+ * <path>
+ * <groupId>org.sample</groupId>
+ * <artifactId>sample-annotation-processor</artifactId>
+ * <version>1.2.3</version>
+ * </path>
+ * <!-- ... more ... -->
+ * </annotationProcessorPaths>
+ * </configuration>
+ *
+ *
+ * @since 5.0
+ */
+ @Parameter
+ List annotationProcessorPaths;
+
+ /**
+ * Annotation Processor FQN (Full Qualified Name) - when processors are not specified, the default discovery mechanism will be used
+ */
+ @Parameter
+ private String[] processors;
+
+ /**
+ * Additional compiler arguments
+ */
+ @Parameter
+ private String compilerArguments;
+
+ /**
+ * Additional processor options (see javax.annotation.processing.ProcessingEnvironment#getOptions()
+ */
+ @Parameter(alias = "options")
+ private java.util.Map optionMap;
+
+ /**
+ * Controls whether or not the output directory is added to compilation
+ */
+ @Parameter
+ private Boolean addOutputDirectoryToCompilationSources;
+
+ /**
+ * Indicates whether the build will continue even if there are compilation errors; defaults to true.
+ */
+ @Parameter(defaultValue = "true", required = true, property = "annotation.failOnError")
+ private Boolean failOnError = true;
+
+ /**
+ * Indicates whether the compiler output should be visible, defaults to true.
+ */
+ @Parameter(defaultValue = "true", required = true, property = "annotation.outputDiagnostics")
+ private boolean outputDiagnostics = true;
+
+ /**
+ * System properties set before processor invocation.
+ */
+ @Parameter
+ private java.util.Map systemProperties;
+
+ /**
+ * includes pattern
+ */
+ @Parameter
+ private String[] includes;
+
+ /**
+ * excludes pattern
+ */
+ @Parameter
+ private String[] excludes;
+
+ /**
+ * additional source directories for the annotation processors.
+ */
+ @Parameter
+ private java.util.List additionalSourceDirectories;
+
+
+ /**
+ * if true add to the source directory of the annotation processor all compile source roots detected int the project
+ * This is useful when we plan to use build-helper-maven-plugin
+ *
+ * @since 2.1.1
+ */
+ @Parameter(defaultValue = "false")
+ private boolean addCompileSourceRoots = false;
+
+
+ /**
+ * append source artifacts to sources list
+ *
+ * @since 2.2.0
+ */
+ @Parameter(defaultValue = "false")
+ private boolean appendSourceArtifacts = false;
+
+ /**
+ * The character set used for decoding sources
+ *
+ * @since 2.2.1
+ */
+ @Parameter(property = "project.build.sourceEncoding")
+ private String encoding;
+
+ /**
+ * The entry point to Aether, i.e. the component doing all the work.
+ */
+ @Component
+ private RepositorySystem repoSystem;
+
+ /**
+ * The current repository/network configuration of Maven.
+ */
+ @Parameter(defaultValue = "${repositorySystemSession}", readonly = true)
+ protected RepositorySystemSession repoSession;
+
+ /**
+ * The project's remote repositories to use for the resolution of plugins and their dependencies.
+ */
+ @Parameter(defaultValue = "${project.remoteProjectRepositories}", readonly = true)
+ private List remoteRepos;
+
+ /**
+ * List of artifacts on which perform sources scanning
+ *
+ * Each artifact must be specified in the form grouId:artifactId.
+ * If you need to include all artifacts belonging a groupId, specify as artifactId the character '*'
+ *
+ *
+ * e.g.
+ *
+ *
+ * org.bsc.maven:maven-confluence-plugin
+ * org.bsc.maven:*
+ *
+ *
+ *
+ * @since 2.2.5
+ */
+ @Parameter()
+ private java.util.List processSourceArtifacts = Collections.emptyList();
+
+ /**
+ * Set this to true to skip annotation processing.
+ *
+ * @since 3.1.0
+ */
+ @Parameter(defaultValue = "false", property = "skipAnnotationProcessing")
+ protected boolean skip;
+
+ /**
+ * Allows running the compiler in a separate process.
+ * If false it uses the built in compiler, while if true it will use an executable.
+ *
+ * to set source and target use
+ *
+ * maven.processor.source
+ * maven.processor.target
+ *
+ *
+ * @since 3.3
+ */
+ @Parameter(defaultValue = "false", property = "fork")
+ protected boolean fork;
+
+ /**
+ * Set this to true to skip annotation processing when there are no changes in the source files
+ * compared to the generated files.
+ *
+ * @since 4.3
+ */
+ @Parameter(defaultValue = "false", property = "skipSourcesUnchangedAnnotationProcessing")
+ protected boolean skipSourcesUnchanged;
+
+ /**
+ * Maven Session
+ *
+ * @since 3.3
+ */
+ @Parameter(defaultValue = "${session}", readonly = true)
+ protected MavenSession session;
+
+ /**
+ * Plexus compiler manager.
+ *
+ * @since 3.3
+ */
+ @Component
+ protected CompilerManager compilerManager;
+
+ /**
+ * @since 3.3
+ */
+ @Component
+ private ToolchainManager toolchainManager;
- result.append(processors[i]);
+ /**
+ * for execution synchronization
+ */
+ private static final Lock syncExecutionLock = new ReentrantLock();
+
+
+ /**
+ * @return supported source directories
+ */
+ protected abstract java.util.Set getSourceDirectories(java.util.Set result);
- return result.toString();
+ /**
+ * @return output folder
+ */
+ protected abstract File getOutputClassDirectory();
+
+ /**
+ * @param project
+ * @param dir
+ */
+ protected abstract void addCompileSourceRoot(MavenProject project, String dir);
+
+ /**
+ * @return
+ */
+ public abstract File getDefaultOutputDirectory();
+
+ /**
+ * @return
+ */
+ private Charset getCharsetFromEncoding() {
+
+ return ofNullable(encoding).map(enc -> {
+ try {
+ return Charset.forName(encoding);
+ } catch (IllegalCharsetNameException ex1) {
+ getLog().warn(format("the given charset name [%s] is illegal!. default is used", encoding));
+ } catch (UnsupportedCharsetException ex2) {
+ getLog().warn(format("the given charset name [%s] is unsupported!. default is used", encoding));
+ }
+ return Charset.defaultCharset();
+ }).orElseGet(() -> Charset.defaultCharset());
+
+ }
+
+ private String buildProcessor() {
+ if (processors == null || processors.length == 0) {
+ return null;
}
- protected abstract java.util.Set getResourcesElements( java.util.Set result );
+ StringBuilder result = new StringBuilder();
- protected abstract java.util.Set getClasspathElements( java.util.Set result );
+ int i;
- protected abstract java.util.List getAllCompileSourceRoots();
+ for (i = 0; i < processors.length - 1; ++i) {
+ result.append(processors[i]).append(',');
+ }
- private String buildCompileSourcepath( Consumer onSuccess) {
-
- final java.util.List roots = getAllCompileSourceRoots();
+ result.append(processors[i]);
- if( roots == null || roots.isEmpty() ) {
- return null;
- }
-
- final String result = StringUtils.join(roots.iterator(), File.pathSeparator);
-
- onSuccess.accept( result );
-
- return result;
- }
-
- private String buildCompileClasspath()
- {
-
- final java.util.Set pathElements = new java.util.LinkedHashSet<>();
+ return result.toString();
+ }
- getResourcesElements(pathElements);
+ protected abstract java.util.Set getResourcesElements(java.util.Set result);
- getClasspathElements(pathElements);
+ protected abstract java.util.Set getClasspathElements(java.util.Set result);
- if( pluginArtifacts!=null ) {
+ protected abstract java.util.List getAllCompileSourceRoots();
- for( Artifact a : pluginArtifacts ) {
-
- if( "compile".equalsIgnoreCase(a.getScope()) || "runtime".equalsIgnoreCase(a.getScope()) ) {
-
- java.io.File f = a.getFile();
-
- if( f!=null ) pathElements.add( a.getFile().getAbsolutePath() );
+ private String buildCompileSourcepath(Consumer onSuccess) {
- }
-
- }
- }
+ final java.util.List roots = getAllCompileSourceRoots();
+
+ if (roots == null || roots.isEmpty()) {
+ return null;
+ }
+
+ final String result = StringUtils.join(roots.iterator(), File.pathSeparator);
+
+ onSuccess.accept(result);
+
+ return result;
+ }
+ private String buildCompileClasspath() {
+
+ final java.util.Set pathElements = new java.util.LinkedHashSet<>();
+
+ getResourcesElements(pathElements);
+
+ getClasspathElements(pathElements);
+
+ if (pluginArtifacts != null) {
+
+ for (Artifact a : pluginArtifacts) {
+
+ if ("compile".equalsIgnoreCase(a.getScope()) || "runtime".equalsIgnoreCase(a.getScope())) {
+
+ java.io.File f = a.getFile();
+
+ if (f != null) pathElements.add(a.getFile().getAbsolutePath());
- final StringBuilder result = new StringBuilder();
-
- for( String elem : pathElements ) {
- result.append(elem).append(File.pathSeparator);
}
- return result.toString();
+
+ }
}
- private String buildModulePath()
- {
- return getClasspathElements(new java.util.LinkedHashSet<>())
- .stream()
- .collect(joining( File.pathSeparator) );
+ final StringBuilder result = new StringBuilder();
+
+ for (String elem : pathElements) {
+ result.append(elem).append(File.pathSeparator);
}
+ return result.toString();
+ }
- /**
- *
- */
- public void execute() throws MojoExecutionException
+ private String buildModulePath() {
+
+ return getClasspathElements(new java.util.LinkedHashSet<>())
+ .stream()
+ .collect(joining(File.pathSeparator));
+ }
+
+ /**
+ *
+ */
+ @Override
+ public void execute() throws MojoExecutionException {
+ if (skip) {
+ getLog().info("skipped");
+ return;
+ }
+
+ if ("pom".equalsIgnoreCase(project.getPackaging())) // Issue 17
{
- if (skip)
- {
- getLog().info("skipped");
- return;
- }
+ return;
+ }
- if ("pom".equalsIgnoreCase(project.getPackaging())) // Issue 17
- {
- return;
- }
+ syncExecutionLock.lock();
+
+ try {
+ executeWithExceptionsHandled();
+ } catch (Exception e1) {
+ super.getLog().error("error on execute: use -X to have details ");
+ super.getLog().debug(e1);
+ if (failOnError) {
+ throw new MojoExecutionException("Error executing", e1);
+ }
+ } finally {
+ syncExecutionLock.unlock();
+ }
- syncExecutionLock.lock();
-
- try
- {
- executeWithExceptionsHandled();
- }
- catch (Exception e1)
- {
- super.getLog().error("error on execute: use -X to have details " );
- super.getLog().debug(e1);
- if (failOnError)
- {
- throw new MojoExecutionException("Error executing", e1);
- }
- }
- finally {
- syncExecutionLock.unlock();
+ }
+
+ /**
+ * TODO remove the part with ToolchainManager lookup once we depend on
+ * 3.0.9 (have it as prerequisite). Define as regular component field then.
+ *
+ * @param jdkToolchain
+ */
+ private Toolchain getToolchain(final Map jdkToolchain) {
+ Toolchain tc = null;
+
+ if (jdkToolchain != null && !jdkToolchain.isEmpty()) {
+ // Maven 3.3.1 has plugin execution scoped Toolchain Support
+ try {
+ final Method getToolchainsMethod =
+ toolchainManager.getClass().getMethod("getToolchains",
+ MavenSession.class,
+ String.class,
+ Map.class);
+
+ @SuppressWarnings("unchecked") final List tcs =
+ (List) getToolchainsMethod.invoke(toolchainManager,
+ session,
+ "jdk",
+ jdkToolchain);
+
+ if (tcs != null && tcs.size() > 0) {
+ tc = tcs.get(0);
}
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+ if (tc == null) {
+ tc = toolchainManager.getToolchainFromBuildContext("jdk", session);
}
- /**
- * TODO remove the part with ToolchainManager lookup once we depend on
- * 3.0.9 (have it as prerequisite). Define as regular component field then.
- *
- * @param jdkToolchain
- */
- private Toolchain getToolchain(final Map jdkToolchain)
- {
- Toolchain tc = null;
-
- if ( jdkToolchain != null && !jdkToolchain.isEmpty())
- {
- // Maven 3.3.1 has plugin execution scoped Toolchain Support
- try
- {
- final Method getToolchainsMethod =
- toolchainManager.getClass().getMethod( "getToolchains",
- MavenSession.class,
- String.class,
- Map.class );
-
- @SuppressWarnings( "unchecked" )
- final List tcs =
- (List) getToolchainsMethod.invoke( toolchainManager,
- session,
- "jdk",
- jdkToolchain );
-
- if ( tcs != null && tcs.size() > 0 )
- {
- tc = tcs.get( 0 );
- }
- }
- catch ( Exception e )
- {
- // ignore
- }
- }
-
- if ( tc == null )
- {
- tc = toolchainManager.getToolchainFromBuildContext( "jdk", session );
- }
-
- return tc;
+ return tc;
+ }
+
+ private List prepareOptions(JavaCompiler compiler) throws MojoExecutionException {
+
+ final List options = new ArrayList<>(10);
+
+ final String compileClassPath = buildCompileClasspath();
+
+ final String processor = buildProcessor();
+
+ options.add("-cp");
+ options.add(compileClassPath);
+
+ if (compiler.isSupportedOption("--module-path") == 1) {
+ options.add("--module-path");
+ options.add(buildModulePath());
}
- private List prepareOptions( JavaCompiler compiler ) {
+ buildCompileSourcepath(sourcepath -> {
+ options.add("-sourcepath");
+ options.add(sourcepath);
+ });
- final List options = new ArrayList<>(10);
+ options.add("-proc:only");
- final String compileClassPath = buildCompileClasspath();
+ this.buildProcessorPath().ifPresent(value -> {
+ options.add("-processorpath");
+ options.add(value);
+ });
- final String processor = buildProcessor();
+ addCompilerArguments(options);
- options.add("-cp");
- options.add(compileClassPath);
+ if (processor != null) {
+ options.add("-processor");
+ options.add(processor);
+ } else {
+ getLog().warn("No processors specified. Using default discovery mechanism.");
+ }
+ options.add("-d");
+ options.add(getOutputClassDirectory().getPath());
+
+ options.add("-s");
+ options.add(outputDirectory.getPath());
+
+ ofNullable(releaseVersion).ifPresent(release -> {
+ options.add("--release");
+ options.add(releaseVersion);
+ });
+
+ ofNullable(project.getProperties()).ifPresent(properties -> {
+
+ ofNullable(properties.getProperty("maven.compiler.source")).ifPresent(source -> {
+ options.add("-source");
+ options.add(source);
+ });
+ ofNullable(properties.getProperty("maven.compiler.target")).ifPresent(target -> {
+ options.add("-target");
+ options.add(target);
+ });
+ });
+
+ ofNullable(encoding).ifPresent(enc -> {
+ options.add("-encoding");
+ options.add(getCharsetFromEncoding().name());
+ });
+
+ if (getLog().isDebugEnabled()) {
+ for (String option : options) {
+ getLog().debug(format("javac option: %s", option));
+ }
+ }
- if( compiler.isSupportedOption("--module-path") == 1 ) {
- options.add("--module-path");
- options.add(buildModulePath());
- }
+ return options;
- buildCompileSourcepath( sourcepath -> {
- options.add("-sourcepath");
- options.add(sourcepath);
- });
+ }
- options.add("-proc:only");
+ private boolean isSourcesUnchanged(List allSources) throws IOException {
+ if (!areSourceFilesSameAsPreviousRun(allSources))
+ return false;
- addCompilerArguments(options);
+ long maxSourceDate = allSources.stream()
+ .map(JavaFileObject::getLastModified)
+ .max(Long::compare)
+ .orElse(Long.MIN_VALUE);
- if (processor != null) {
- options.add("-processor");
- options.add(processor);
- }
- else
- {
- getLog().warn("No processors specified. Using default discovery mechanism.");
- }
- options.add("-d");
- options.add(getOutputClassDirectory().getPath());
-
- options.add("-s");
- options.add(outputDirectory.getPath());
-
- ofNullable(releaseVersion).ifPresent( release -> {
- options.add("--release");
- options.add( releaseVersion );
- });
-
- ofNullable(project.getProperties()).ifPresent( properties -> {
-
- ofNullable(properties.getProperty( "maven.compiler.source" )).ifPresent( source -> {
- options.add("-source");
- options.add(source);
- });
- ofNullable(properties.getProperty( "maven.compiler.target" )) .ifPresent( target -> {
- options.add("-target");
- options.add(target);
- });
- });
-
- ofNullable(encoding).ifPresent( enc -> {
- options.add("-encoding");
- options.add( getCharsetFromEncoding().name() );
- });
-
- if( getLog().isDebugEnabled() ) {
- for (String option : options) {
- getLog().debug(format("javac option: %s", option));
- }
+ // use atomic long for effectively final wrapper around long variable
+ final AtomicLong maxOutputDate = new AtomicLong(Long.MIN_VALUE);
+
+ Files.walkFileTree(outputDirectory.toPath(), new SimpleFileVisitor() {
+ @Override
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
+ throws IOException {
+ if (Files.isRegularFile(file)) {
+ maxOutputDate.updateAndGet(t -> Math.max(t, file.toFile().lastModified()));
}
+ return FileVisitResult.CONTINUE;
+ }
+ });
- return options;
+ if (getLog().isDebugEnabled()) {
+ getLog().debug("max source file date: " + maxSourceDate + ", max output date: " + maxOutputDate
+ .get());
+ }
+ return maxSourceDate <= maxOutputDate.get();
+ }
+
+ /**
+ * Checks the list of {@code allSources} against the stored list of source files in a previous run.
+ *
+ * @param allSources
+ * @return {@code true} when the filenames of the previous run matches exactly with the current run.
+ * @throws IOException
+ */
+ private boolean areSourceFilesSameAsPreviousRun(List allSources) throws IOException {
+ Path sourceFileList = outputDirectory.toPath().resolve(".maven-processor-source-files.txt");
+ try {
+ if (!Files.exists(sourceFileList)) {
+ getLog().debug("File with previous sources " + sourceFileList + " not found, treating as first run");
+ return false;
+ }
+
+ Set previousSourceFiles = new HashSet<>(Files.readAllLines(sourceFileList));
+ Set currentSourceFiles = allSources.stream().map(JavaFileObject::getName).collect(Collectors.toSet());
+ if (getLog().isDebugEnabled()) {
+ final String removedSourceFiles = previousSourceFiles.stream()
+ .filter(f -> !currentSourceFiles.contains(f))
+ .collect(joining("\n"));
+ getLog().debug(format("removed source files:\n%s", removedSourceFiles));
+
+ final String newSourceFiles = currentSourceFiles.stream()
+ .filter(f -> !previousSourceFiles.contains(f))
+ .collect(joining("\n"));
+ getLog().debug(format("new source files:\n%s", newSourceFiles));
+ }
+ return previousSourceFiles.equals(currentSourceFiles);
+ } finally {
+ outputDirectory.mkdirs();
+ Files.write(sourceFileList, allSources.stream().map(JavaFileObject::getName).collect(Collectors.toSet()));
}
+ }
- private boolean isSourcesUnchanged( List allSources ) throws IOException {
- if (!areSourceFilesSameAsPreviousRun(allSources))
- return false;
+ private void executeWithExceptionsHandled() throws Exception {
+ if (outputDirectory == null) {
+ outputDirectory = getDefaultOutputDirectory();
+ }
- long maxSourceDate = allSources.stream()
- .map(JavaFileObject::getLastModified)
- .max(Long::compare)
- .orElse(Long.MIN_VALUE);
+ ensureOutputDirectoryExists();
+ addOutputToSourcesIfNeeded();
- // use atomic long for effectively final wrapper around long variable
- final AtomicLong maxOutputDate = new AtomicLong(Long.MIN_VALUE);
+ // new Debug(project).printDebugInfo();
- Files.walkFileTree(outputDirectory.toPath(), new SimpleFileVisitor() {
- @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
- throws IOException
- {
- if(Files.isRegularFile(file)) {
- maxOutputDate.updateAndGet(t -> Math.max(t, file.toFile().lastModified()));
- }
- return FileVisitResult.CONTINUE;
- }
- });
+ final String includesString = (includes == null || includes.length == 0) ? "**/*.java" : StringUtils.join(includes, ",");
+ final String excludesString = (excludes == null || excludes.length == 0) ? null : StringUtils.join(excludes, ",");
- if(getLog().isDebugEnabled())
- {
- getLog().debug("max source file date: " + maxSourceDate + ", max output date: " + maxOutputDate
- .get());
- }
+ java.util.Set sourceDirs = getSourceDirectories(new java.util.HashSet<>(5));
- return maxSourceDate <= maxOutputDate.get();
- }
-
- /**
- * Checks the list of {@code allSources} against the stored list of source files in a previous run.
- *
- * @param allSources
- * @return {@code true} when the filenames of the previous run matches exactly with the current run.
- * @throws IOException
- */
- private boolean areSourceFilesSameAsPreviousRun(List allSources) throws IOException {
- Path sourceFileList = outputDirectory.toPath().resolve(".maven-processor-source-files.txt");
- try {
- if (!Files.exists(sourceFileList)) {
- getLog().debug("File with previous sources " + sourceFileList + " not found, treating as first run");
- return false;
- }
-
- Set previousSourceFiles = new HashSet<>(Files.readAllLines(sourceFileList));
- Set currentSourceFiles = allSources.stream().map(JavaFileObject::getName).collect(Collectors.toSet());
- if (getLog().isDebugEnabled()) {
- final String removedSourceFiles = previousSourceFiles.stream()
- .filter(f -> !currentSourceFiles.contains(f))
- .collect(joining("\n"));
- getLog().debug(format("removed source files:\n%s", removedSourceFiles));
-
- final String newSourceFiles = currentSourceFiles.stream()
- .filter(f -> !previousSourceFiles.contains(f))
- .collect(joining("\n"));
- getLog().debug(format("new source files:\n%s", newSourceFiles));
- }
- return previousSourceFiles.equals(currentSourceFiles);
- } finally {
- outputDirectory.mkdirs();
- Files.write(sourceFileList, allSources.stream().map(JavaFileObject::getName).collect(Collectors.toSet()));
+ if (addCompileSourceRoots) {
+ final java.util.List sourceRoots = project.getCompileSourceRoots();
+ if (sourceRoots != null) {
+ for (String s : sourceRoots) {
+ sourceDirs.add(new File(s));
}
+ }
}
- private void executeWithExceptionsHandled() throws Exception
- {
- if (outputDirectory == null)
- {
- outputDirectory = getDefaultOutputDirectory();
- }
+ if (additionalSourceDirectories != null && !additionalSourceDirectories.isEmpty()) {
+ sourceDirs.addAll(additionalSourceDirectories);
+ }
- ensureOutputDirectoryExists();
- addOutputToSourcesIfNeeded();
+ if (sourceDirs == null) {
+ throw new IllegalStateException("getSourceDirectories is null!");
+ }
- // new Debug(project).printDebugInfo();
+ final List files = new java.util.ArrayList<>();
- final String includesString = ( includes==null || includes.length==0) ? "**/*.java" : StringUtils.join(includes, ",");
- final String excludesString = ( excludes==null || excludes.length==0) ? null : StringUtils.join(excludes, ",");
+ for (File sourceDir : sourceDirs) {
- java.util.Set sourceDirs = getSourceDirectories(new java.util.HashSet<>( 5 ));
-
- if( addCompileSourceRoots ) {
- final java.util.List sourceRoots = project.getCompileSourceRoots();
- if( sourceRoots != null ) {
- for( String s : sourceRoots ) {
- sourceDirs.add( new File(s) );
- }
- }
- }
+ if (sourceDir == null) {
+ getLog().warn("source directory is null! Processor task will be skipped!");
+ continue;
+ }
- if( additionalSourceDirectories != null && !additionalSourceDirectories.isEmpty() ) {
- sourceDirs.addAll( additionalSourceDirectories );
- }
+ getLog().debug(format("processing source directory [%s]", sourceDir.getPath()));
- if( sourceDirs == null ) {
- throw new IllegalStateException("getSourceDirectories is null!");
- }
+ if (!sourceDir.exists()) {
+ getLog().warn(format("source directory [%s] doesn't exist! Processor task will be skipped!", sourceDir.getPath()));
+ continue;
+ }
+ if (!sourceDir.isDirectory()) {
+ getLog().warn(format("source directory [%s] is invalid! Processor task will be skipped!", sourceDir.getPath()));
+ continue;
+ }
+
+ files.addAll(FileUtils.getFiles(sourceDir, includesString, excludesString));
+ }
- final List files = new java.util.ArrayList<>();
-
- for( File sourceDir : sourceDirs ) {
-
- if( sourceDir==null ) {
- getLog().warn( "source directory is null! Processor task will be skipped!" );
- continue;
- }
-
- getLog().debug( format( "processing source directory [%s]", sourceDir.getPath()) );
-
- if( !sourceDir.exists() ) {
- getLog().warn( format("source directory [%s] doesn't exist! Processor task will be skipped!", sourceDir.getPath()));
- continue;
- }
- if( !sourceDir.isDirectory() ) {
- getLog().warn( format("source directory [%s] is invalid! Processor task will be skipped!", sourceDir.getPath()));
- continue;
- }
-
- files.addAll( FileUtils.getFiles(sourceDir, includesString, excludesString) );
+ final DiagnosticListener dl = diagnostic -> {
+
+ if (!outputDiagnostics) {
+ return;
+ }
+
+ final Kind kind = diagnostic.getKind();
+
+ if (null != kind)
+ switch (kind) {
+ case ERROR:
+ getLog().error(format("diagnostic: %s", diagnostic));
+ break;
+ case MANDATORY_WARNING:
+ case WARNING:
+ getLog().warn(format("diagnostic: %s", diagnostic));
+ break;
+ case NOTE:
+ getLog().info(format("diagnostic: %s", diagnostic));
+ break;
+ case OTHER:
+ getLog().info(format("diagnostic: %s", diagnostic));
+ break;
+ default:
+ break;
}
- final DiagnosticListener dl = diagnostic -> {
-
- if (!outputDiagnostics) {
- return;
- }
-
- final Kind kind = diagnostic.getKind();
-
- if (null != kind)
- switch (kind) {
- case ERROR:
- getLog().error(format("diagnostic: %s", diagnostic));
- break;
- case MANDATORY_WARNING:
- case WARNING:
- getLog().warn(format("diagnostic: %s", diagnostic));
- break;
- case NOTE:
- getLog().info(format("diagnostic: %s", diagnostic));
- break;
- case OTHER:
- getLog().info(format("diagnostic: %s", diagnostic));
- break;
- default:
- break;
- }
-
- };
-
- if (systemProperties != null) {
- java.util.Set< Map.Entry> pSet = systemProperties.entrySet();
-
- for ( Map.Entry e : pSet ) {
- getLog().debug( format("set system property : [%s] = [%s]", e.getKey(), e.getValue() ));
- System.setProperty(e.getKey(), e.getValue());
- }
+ };
- }
+ if (systemProperties != null) {
+ java.util.Set> pSet = systemProperties.entrySet();
+ for (Map.Entry e : pSet) {
+ getLog().debug(format("set system property : [%s] = [%s]", e.getKey(), e.getValue()));
+ System.setProperty(e.getKey(), e.getValue());
+ }
- final java.util.Map jdkToolchain =
- java.util.Collections.emptyMap();
-
- final Toolchain tc = getToolchain(jdkToolchain);
-
- // If toolchain is set force fork compilation
- fork = ( tc != null );
-
- if( fork ) { getLog().debug( "PROCESSOR COMPILER FORKED!"); }
+ }
- //
- // add to allSource the files coming out from source archives
- //
- final java.util.List allSources = new java.util.ArrayList<>();
- final UnzipService unzip = UnzipService.newInstance( getLog() );
+ final java.util.Map jdkToolchain =
+ java.util.Collections.emptyMap();
- if( fork ) {
- processSourceArtifacts( artifact -> unzip.extractSourcesFromArtifactToTempDirectory( artifact, allSources,
- Paths.get( project.getBuild().getDirectory(), "extracted-sources" ) ));
- }
- else {
- processSourceArtifacts( artifact -> unzip.extractSourcesFromArtifact(artifact, allSources) );
- }
+ final Toolchain tc = getToolchain(jdkToolchain);
- //compileLock.lock();
-
- try {
-
- final JavaCompiler compiler = (fork) ?
- AnnotationProcessorCompiler.createOutProcess(
- tc,
- compilerManager,
- project,
- session ) :
- AnnotationProcessorCompiler.createInProcess();
-
-
- if( compiler==null ) {
- getLog().error("JVM is not suitable for processing annotation! ToolProvider.getSystemJavaCompiler() is null.");
- return;
- }
-
- final StandardJavaFileManager fileManager =
- compiler.getStandardFileManager(null,
- null,
- getCharsetFromEncoding());
-
- if( files!=null && !files.isEmpty() ) {
-
- for( JavaFileObject f : fileManager.getJavaFileObjectsFromFiles(files) ) {
- allSources.add(f);
- };
-
- }
-
- if( allSources.isEmpty() ) {
- getLog().warn( "no source file(s) detected! Processor task will be skipped");
- return;
- }
-
- if(skipSourcesUnchanged && isSourcesUnchanged(allSources)) {
- getLog().info( "no source file(s) change(s) detected! Processor task will be skipped");
- return;
- }
- final java.util.List options = prepareOptions( compiler );
-
- final CompilationTask task = compiler.getTask(
- new PrintWriter(System.out),
- fileManager,
- dl,
- options,
- null,
- allSources);
-
- /*
- * //Create a list to hold annotation processors LinkedList processors = new
- * LinkedList();
- *
- * //Add an annotation processor to the list processors.add(p);
- *
- * //Set the annotation processor to the compiler task task.setProcessors(processors);
- */
-
- // Perform the compilation task.
- if (!task.call()) {
- throw new Exception("error during compilation");
- }
- }
- finally {
- //compileLock.unlock();
- }
-
+ // If toolchain is set force fork compilation
+ fork = (tc != null);
+
+ if (fork) {
+ getLog().debug("PROCESSOR COMPILER FORKED!");
}
- private List scanSourceDirectorySources(File sourceDir) throws IOException {
- if( sourceDir==null ) {
- getLog().warn( "source directory cannot be read (null returned)! Processor task will be skipped");
- return null;
- }
- if( !sourceDir.exists() ) {
- getLog().warn( "source directory doesn't exist! Processor task will be skipped");
- return null;
- }
- if( !sourceDir.isDirectory() ) {
- getLog().warn( "source directory is invalid! Processor task will be skipped");
- return null;
- }
+ //
+ // add to allSource the files coming out from source archives
+ //
+ final java.util.List allSources = new java.util.ArrayList<>();
- final String includesString = ( includes==null || includes.length==0) ? "**/*.java" : StringUtils.join(includes, ",");
- final String excludesString = ( excludes==null || excludes.length==0) ? null : StringUtils.join(excludes, ",");
+ final UnzipService unzip = UnzipService.newInstance(getLog());
- final List files = FileUtils.getFiles(sourceDir, includesString, excludesString);
- return files;
+ if (fork) {
+ processSourceArtifacts(artifact -> unzip.extractSourcesFromArtifactToTempDirectory(artifact, allSources,
+ Paths.get(project.getBuild().getDirectory(), "extracted-sources")));
+ } else {
+ processSourceArtifacts(artifact -> unzip.extractSourcesFromArtifact(artifact, allSources));
}
- private void addCompilerArguments(List options) {
- if (!StringUtils.isEmpty(compilerArguments)) {
- for (String arg : compilerArguments.split(" ")) {
- if (!StringUtils.isEmpty(arg)) {
- arg = arg.trim();
- getLog().debug(format("Adding compiler arg: %s", arg));
- options.add(arg);
- }
- }
- }
- if( optionMap!=null && !optionMap.isEmpty() ) {
- for( java.util.Map.Entry e : optionMap.entrySet() ) {
-
- if( !StringUtils.isEmpty(e.getKey()) && e.getValue()!=null ) {
- String opt = format("-A%s=%s", e.getKey().trim(), e.getValue().toString().trim());
- options.add( opt );
- getLog().debug(format("Adding compiler arg: %s", opt));
- }
- }
-
+ //compileLock.lock();
+
+ try {
+
+ final JavaCompiler compiler = (fork) ?
+ AnnotationProcessorCompiler.createOutProcess(
+ tc,
+ compilerManager,
+ project,
+ session) :
+ AnnotationProcessorCompiler.createInProcess();
+
+
+ if (compiler == null) {
+ getLog().error("JVM is not suitable for processing annotation! ToolProvider.getSystemJavaCompiler() is null.");
+ return;
+ }
+
+ final StandardJavaFileManager fileManager =
+ compiler.getStandardFileManager(null,
+ null,
+ getCharsetFromEncoding());
+
+ if (files != null && !files.isEmpty()) {
+
+ for (JavaFileObject f : fileManager.getJavaFileObjectsFromFiles(files)) {
+ allSources.add(f);
}
+ ;
+
+ }
+
+ if (allSources.isEmpty()) {
+ getLog().warn("no source file(s) detected! Processor task will be skipped");
+ return;
+ }
+
+ if (skipSourcesUnchanged && isSourcesUnchanged(allSources)) {
+ getLog().info("no source file(s) change(s) detected! Processor task will be skipped");
+ return;
+ }
+ final java.util.List options = prepareOptions(compiler);
+
+ final CompilationTask task = compiler.getTask(
+ new PrintWriter(System.out),
+ fileManager,
+ dl,
+ options,
+ null,
+ allSources);
+
+ /*
+ * //Create a list to hold annotation processors LinkedList processors = new
+ * LinkedList();
+ *
+ * //Add an annotation processor to the list processors.add(p);
+ *
+ * //Set the annotation processor to the compiler task task.setProcessors(processors);
+ */
+
+ // Perform the compilation task.
+ if (!task.call()) {
+ throw new Exception("error during compilation");
+ }
+ } finally {
+ //compileLock.unlock();
}
- private void addOutputToSourcesIfNeeded()
- {
- final Boolean add = addOutputDirectoryToCompilationSources;
- if (add == null || add.booleanValue()) {
- getLog().debug(format("Source directory: %s added", outputDirectory));
- addCompileSourceRoot(project, outputDirectory.getAbsolutePath());
- }
+ }
+
+ private List scanSourceDirectorySources(File sourceDir) throws IOException {
+ if (sourceDir == null) {
+ getLog().warn("source directory cannot be read (null returned)! Processor task will be skipped");
+ return null;
+ }
+ if (!sourceDir.exists()) {
+ getLog().warn("source directory doesn't exist! Processor task will be skipped");
+ return null;
+ }
+ if (!sourceDir.isDirectory()) {
+ getLog().warn("source directory is invalid! Processor task will be skipped");
+ return null;
}
- private void ensureOutputDirectoryExists()
- {
- final File f = outputDirectory;
- if (!f.exists()) {
- f.mkdirs();
- }
- if( !getOutputClassDirectory().exists()) {
- getOutputClassDirectory().mkdirs();
+ final String includesString = (includes == null || includes.length == 0) ? "**/*.java" : StringUtils.join(includes, ",");
+ final String excludesString = (excludes == null || excludes.length == 0) ? null : StringUtils.join(excludes, ",");
+
+ final List files = FileUtils.getFiles(sourceDir, includesString, excludesString);
+ return files;
+ }
+
+ private void addCompilerArguments(List options) {
+ if (!StringUtils.isEmpty(compilerArguments)) {
+ for (String arg : compilerArguments.split(" ")) {
+ if (!StringUtils.isEmpty(arg)) {
+ arg = arg.trim();
+ getLog().debug(format("Adding compiler arg: %s", arg));
+ options.add(arg);
}
+ }
}
+ if (optionMap != null && !optionMap.isEmpty()) {
+ for (java.util.Map.Entry e : optionMap.entrySet()) {
- private boolean matchArtifact( Artifact dep/*, ArtifactFilter filter*/ ) {
-
- if(processSourceArtifacts == null || processSourceArtifacts.isEmpty()) {
- return false;
- }
-
- for( String a : processSourceArtifacts ) {
-
- if( a == null || a.isEmpty() ) continue;
-
- final String [] token = a.split(":");
-
- final boolean matchGroupId = dep.getGroupId().equals(token[0]);
-
- if( !matchGroupId ) continue;
-
- if( token.length == 1 ) return true;
-
- if( token[1].equals("*") ) return true;
-
- return dep.getArtifactId().equals(token[1]);
-
+ if (!StringUtils.isEmpty(e.getKey()) && e.getValue() != null) {
+ String opt = format("-A%s=%s", e.getKey().trim(), e.getValue().toString().trim());
+ options.add(opt);
+ getLog().debug(format("Adding compiler arg: %s", opt));
}
- return false;
+ }
+
}
-
- private Optional resolveSourceArtifact( Artifact dep ) throws ArtifactResolutionException {
-
- if( !matchArtifact(dep) ) {
- return empty();
- }
-
- final ArtifactTypeRegistry typeReg = repoSession.getArtifactTypeRegistry();
-
- final DefaultArtifact artifact =
- new DefaultArtifact( dep.getGroupId(),
- dep.getArtifactId(),
- SOURCE_CLASSIFIER,
- null,
- dep.getVersion(),
- typeReg.get(dep.getType()));
-
- final ArtifactRequest request = new ArtifactRequest();
- request.setArtifact( artifact );
- request.setRepositories(remoteRepos);
-
- getLog().debug( format("Resolving artifact %s from %s", artifact, remoteRepos ));
-
- final ArtifactResult result = repoSystem.resolveArtifact( repoSession, request );
-
- return ofNullable(RepositoryUtils.toArtifact(result.getArtifact()));
- }
-
- private void processSourceArtifacts( Consumer closure ) {
-
- for (Artifact dep : this.project.getDependencyArtifacts()) {
- if (dep.hasClassifier() && SOURCE_CLASSIFIER.equals(dep.getClassifier()) ) {
-
- if( appendSourceArtifacts ) {
- closure.accept(dep);
- }
- //getLog().debug("Append source artifact to classpath: " + dep.getGroupId() + ":" + dep.getArtifactId());
- //this.sourceArtifacts.add(dep.getFile());
- }
- else {
- try {
- resolveSourceArtifact(dep).ifPresent(closure::accept);
-
- } catch (ArtifactResolutionException ex) {
- getLog().warn( format(" sources for artifact [%s] not found!", dep.toString()));
- getLog().debug(ex);
-
- }
- }
+ }
+
+ private void addOutputToSourcesIfNeeded() {
+ final Boolean add = addOutputDirectoryToCompilationSources;
+ if (add == null || add.booleanValue()) {
+ getLog().debug(format("Source directory: %s added", outputDirectory));
+ addCompileSourceRoot(project, outputDirectory.getAbsolutePath());
+ }
+ }
+
+ private void ensureOutputDirectoryExists() {
+ final File f = outputDirectory;
+ if (!f.exists()) {
+ f.mkdirs();
+ }
+ if (!getOutputClassDirectory().exists()) {
+ getOutputClassDirectory().mkdirs();
+ }
+ }
+
+ private boolean matchArtifact(Artifact dep/*, ArtifactFilter filter*/) {
+
+ if (processSourceArtifacts == null || processSourceArtifacts.isEmpty()) {
+ return false;
+ }
+
+ for (String a : processSourceArtifacts) {
+
+ if (a == null || a.isEmpty()) continue;
+
+ final String[] token = a.split(":");
+
+ final boolean matchGroupId = dep.getGroupId().equals(token[0]);
+
+ if (!matchGroupId) continue;
+
+ if (token.length == 1) return true;
+
+ if (token[1].equals("*")) return true;
+
+ return dep.getArtifactId().equals(token[1]);
+
+ }
+ return false;
+ }
+
+ private Optional resolveSourceArtifact(Artifact dep) throws ArtifactResolutionException {
+
+ if (!matchArtifact(dep)) {
+ return empty();
+ }
+
+ final ArtifactTypeRegistry typeReg = repoSession.getArtifactTypeRegistry();
+
+ final DefaultArtifact artifact =
+ new DefaultArtifact(dep.getGroupId(),
+ dep.getArtifactId(),
+ SOURCE_CLASSIFIER,
+ null,
+ dep.getVersion(),
+ typeReg.get(dep.getType()));
+
+ final ArtifactRequest request = new ArtifactRequest();
+ request.setArtifact(artifact);
+ request.setRepositories(remoteRepos);
+
+ getLog().debug(format("Resolving artifact %s from %s", artifact, remoteRepos));
+
+ final ArtifactResult result = repoSystem.resolveArtifact(repoSession, request);
+
+ return ofNullable(RepositoryUtils.toArtifact(result.getArtifact()));
+ }
+
+ private void processSourceArtifacts(Consumer closure) {
+
+ final java.util.Set depArtifacts = this.project.getDependencyArtifacts();
+ if (depArtifacts != null) {
+
+ for (Artifact dep : depArtifacts) {
+
+ if (dep.hasClassifier() && SOURCE_CLASSIFIER.equals(dep.getClassifier())) {
+
+ if (appendSourceArtifacts) {
+ closure.accept(dep);
+ }
+ //getLog().debug("Append source artifact to classpath: " + dep.getGroupId() + ":" + dep.getArtifactId());
+ //this.sourceArtifacts.add(dep.getFile());
+ } else {
+ try {
+ resolveSourceArtifact(dep).ifPresent(closure::accept);
+
+ } catch (ArtifactResolutionException ex) {
+ getLog().warn(format(" sources for artifact [%s] not found!", dep.toString()));
+ getLog().debug(ex);
+
+ }
}
+ }
+ }
+ }
+
+ private Optional> resolveProcessorPathEntries() {
+ if (this.annotationProcessorPaths != null && !this.annotationProcessorPaths.isEmpty() ) {
+
+ try {
+
+ final List requiredDependencies =
+ this.annotationProcessorPaths.stream()
+ .map(dependency -> new DefaultArtifact(
+ dependency.getGroupId(),
+ dependency.getArtifactId(),
+ dependency.getClassifier(),
+ dependency.getType(),
+ dependency.getVersion()))
+ .distinct()
+ .map(artifact -> new Dependency(artifact, Artifact.SCOPE_RUNTIME))
+ .collect(Collectors.toList());
+
+ final Dependency root = requiredDependencies.get(0);
+
+ final CollectRequest collectRequest =
+ new CollectRequest(root, requiredDependencies, this.remoteRepos);
+
+ final DependencyRequest dependencyRequest =
+ new DependencyRequest(collectRequest, null);
+
+ final DependencyResult resolutionResult =
+ this.repoSystem.resolveDependencies(this.repoSession, dependencyRequest);
+
+ final List artifactPaths =
+ resolutionResult.getArtifactResults().stream()
+ .map(artifactResult -> artifactResult.getArtifact().getFile().getAbsolutePath())
+ .collect(Collectors.toList());
+
+ return Optional.of(artifactPaths);
+
+ } catch (Exception e) {
+
+ final String msg = format("Resolution of annotationProcessorPath dependencies failed: %s", e.getLocalizedMessage());
+ getLog().error(msg, e);
+ }
}
+ return empty();
+
+ }
+ /**
+ *
+ * @return
+ */
+ protected Optional buildProcessorPath() {
+ return this.resolveProcessorPathEntries()
+ .flatMap( artifactPaths ->
+ Optional.of(artifactPaths.stream().collect(Collectors.joining(File.separator))) );
+ }
}
diff --git a/processor/src/test/java/org/bsc/maven/plugin/processor/AnnotationProcessorMojoTest.java b/processor/src/test/java/org/bsc/maven/plugin/processor/AnnotationProcessorMojoTest.java
new file mode 100644
index 0000000..102c31e
--- /dev/null
+++ b/processor/src/test/java/org/bsc/maven/plugin/processor/AnnotationProcessorMojoTest.java
@@ -0,0 +1,227 @@
+package org.bsc.maven.plugin.processor;
+
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.plugin.Mojo;
+import org.apache.maven.plugin.MojoExecution;
+import org.apache.maven.plugin.testing.MojoRule;
+import org.apache.maven.plugin.testing.resources.TestResources;
+import org.apache.maven.project.MavenProject;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.metadata.Metadata;
+import org.eclipse.aether.repository.*;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.io.File;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Optional;
+
+import static java.lang.String.format;
+import static org.junit.Assert.*;
+
+public class AnnotationProcessorMojoTest {
+
+ //final Path localRepoDir = Paths.get( System.getProperty("user.home"), ".m2", "repository");
+ final Path localRepoDir = Paths.get( "src", "test", "resources", "localRepo");
+
+ @Rule
+ public MojoRule mojoRule = new MojoRule();
+
+ @Rule
+ public TestResources resources = new TestResources();
+
+ final Path outputPath = Paths.get("target", "classes");
+
+ /**
+ *
+ * @param baseDir
+ * @param goal
+ * @return
+ *
+ * @ref https://stackoverflow.com/a/42216471/521197
+ */
+ T lookupConfiguredMojo( Path baseDir, String goal ) throws Exception {
+
+ final Path localRepoDir = Paths.get( System.getProperty("user.home"), ".m2", "repository");
+
+ final MavenProject project = mojoRule.readMavenProject(baseDir.toFile());
+
+ // Generate session
+ final MavenSession session = mojoRule.newMavenSession(project);
+
+ // add localRepo - framework doesn't do this on its own
+ final org.apache.maven.artifact.repository.ArtifactRepository localRepo =
+ new org.apache.maven.artifact.repository.MavenArtifactRepository("local",
+ localRepoDir.toString(),
+ new org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout(),
+ new org.apache.maven.artifact.repository.ArtifactRepositoryPolicy( true,
+ org.apache.maven.artifact.repository.ArtifactRepositoryPolicy.UPDATE_POLICY_ALWAYS,
+ org.apache.maven.artifact.repository.ArtifactRepositoryPolicy.CHECKSUM_POLICY_IGNORE ),
+ new org.apache.maven.artifact.repository.ArtifactRepositoryPolicy( true,
+ org.apache.maven.artifact.repository.ArtifactRepositoryPolicy.UPDATE_POLICY_ALWAYS,
+ org.apache.maven.artifact.repository.ArtifactRepositoryPolicy.CHECKSUM_POLICY_IGNORE )
+
+ );
+
+ session.getRequest().setLocalRepository(localRepo);
+
+ // Generate Execution and Mojo for testing
+ final MojoExecution execution = mojoRule.newMojoExecution("process");
+
+ return (T)mojoRule.lookupConfiguredMojo(session, execution);
+
+ }
+
+ Path artifactPath( String artifact ) {
+ return Paths.get( localRepoDir.toString(), artifact);
+ }
+
+ /**
+ *
+ */
+ class TestLocalRepositoryManager implements org.eclipse.aether.repository.LocalRepositoryManager {
+
+ final org.eclipse.aether.repository.LocalRepository localRepo;
+
+
+ public TestLocalRepositoryManager() {
+ localRepo = new org.eclipse.aether.repository.LocalRepository(localRepoDir.toString());
+ }
+
+ @Override
+ public LocalRepository getRepository() {
+ return localRepo;
+ }
+
+ @Override
+ public String getPathForLocalArtifact(Artifact artifact) {
+ return localRepoDir.toString();
+ }
+
+ @Override
+ public String getPathForRemoteArtifact(Artifact artifact, RemoteRepository remoteRepository, String s) {
+ throw new UnsupportedOperationException( format("getPathForRemoteArtifact(%s)", artifact));
+ }
+
+ @Override
+ public String getPathForLocalMetadata(Metadata metadata) {
+ throw new UnsupportedOperationException( format("getPathForLocalMetadata(%s)", metadata));
+ }
+
+ @Override
+ public String getPathForRemoteMetadata(Metadata metadata, RemoteRepository remoteRepository, String s) {
+ throw new UnsupportedOperationException( format("getPathForRemoteMetadata(%s)", metadata));
+ }
+
+ @Override
+ public LocalArtifactResult find(RepositorySystemSession repositorySystemSession, LocalArtifactRequest localArtifactRequest) {
+
+ final Artifact artifact = localArtifactRequest.getArtifact();
+
+ final LocalArtifactResult result = new LocalArtifactResult(localArtifactRequest);
+ result.setAvailable(true);
+
+ if( "jar".equals(artifact.getExtension()) ) {
+
+ final File file = artifactPath(
+ format("%s-%s.%s", artifact.getArtifactId(), artifact.getVersion(), artifact.getExtension()))
+ .toFile();
+
+ assertTrue(file.exists());
+
+ result.setFile(file);
+ }
+
+ return result;
+ }
+
+ @Override
+ public LocalMetadataResult find(RepositorySystemSession repositorySystemSession, LocalMetadataRequest localMetadataRequest) {
+ throw new UnsupportedOperationException(format("find(RepositorySystemSession,LocalMetadataRequest:%s)", localMetadataRequest));
+ }
+
+ @Override
+ public void add(RepositorySystemSession repositorySystemSession, LocalArtifactRegistration localArtifactRegistration) {
+ throw new UnsupportedOperationException(format("add(RepositorySystemSession,LocalArtifactRegistration%s)",localArtifactRegistration));
+ }
+
+ @Override
+ public void add(RepositorySystemSession repositorySystemSession, LocalMetadataRegistration localMetadataRegistration) {
+ throw new UnsupportedOperationException(format("add(RepositorySystemSession,LocalMetadataRegistration:%s)", localMetadataRegistration));
+ }
+ }
+
+ /**
+ *
+ * @param baseDir
+ * @param goal
+ * @return
+ *
+ * @ref https://stackoverflow.com/a/42216471/521197
+ */
+ MainAnnotationProcessorMojo lookupConfiguredMojoUsingAether( Path baseDir, String goal ) throws Exception {
+
+ final MavenProject project = mojoRule.readMavenProject(baseDir.toFile());
+
+ // Generate session
+ final MavenSession session = mojoRule.newMavenSession(project);
+
+ // Generate Execution and Mojo for testing
+ final MojoExecution execution = mojoRule.newMojoExecution(goal);
+
+ final MainAnnotationProcessorMojo mojo =
+ (MainAnnotationProcessorMojo) mojoRule.lookupConfiguredMojo(session, execution);
+
+ org.eclipse.aether.DefaultRepositorySystemSession repoSession =
+ (org.eclipse.aether.DefaultRepositorySystemSession)mojo.repoSession;
+
+ org.eclipse.aether.repository.LocalRepositoryManager localRepoManager =
+ repoSession.getLocalRepositoryManager();
+
+ if( localRepoManager == null ) {
+
+ repoSession.setLocalRepositoryManager( new TestLocalRepositoryManager() );
+ }
+
+ return mojo;
+
+ }
+
+ @Test
+ public void testPR45() throws Exception {
+ final File pom = Paths.get(outputPath.toString(), "pr45", "pom.xml").toFile();
+
+ assertNotNull(pom);
+
+ final Path baseDir = Paths.get(outputPath.toString(), "pr45");
+
+ assertNotNull(baseDir);
+ assertTrue( baseDir.toFile().exists() );
+ assertTrue( baseDir.toFile().isDirectory() );
+
+ final MainAnnotationProcessorMojo myMojo = lookupConfiguredMojoUsingAether(baseDir, "process");
+
+ myMojo.execute();
+
+ assertNotNull( myMojo.annotationProcessorPaths );
+ assertEquals( 1, myMojo.annotationProcessorPaths.size() );
+
+ final Dependency coord = myMojo.annotationProcessorPaths.get(0);
+
+ assertNotNull( coord );
+ assertEquals( "org.mapstruct", coord.getGroupId() );
+ assertEquals( "mapstruct-processor", coord.getArtifactId() );
+ assertEquals( "1.4.2.Final", coord.getVersion() );
+
+
+ final Optional processorPath = myMojo.buildProcessorPath();
+
+ assertTrue( processorPath.isPresent() );
+ assertEquals( artifactPath( "mapstruct-processor-1.4.2.Final.jar").toAbsolutePath().toString(), processorPath.get() );
+
+ }
+}
diff --git a/processor/src/test/resources/localRepo/mapstruct-processor-1.4.2.Final.jar b/processor/src/test/resources/localRepo/mapstruct-processor-1.4.2.Final.jar
new file mode 100644
index 0000000..dbcef7f
Binary files /dev/null and b/processor/src/test/resources/localRepo/mapstruct-processor-1.4.2.Final.jar differ
diff --git a/processor/src/test/resources/pr45/pom.xml b/processor/src/test/resources/pr45/pom.xml
new file mode 100644
index 0000000..c419978
--- /dev/null
+++ b/processor/src/test/resources/pr45/pom.xml
@@ -0,0 +1,31 @@
+
+
+ 4.0.0
+
+ org.bsc.maven
+ maven-processor-plugin-test
+ ${project.version}
+ jar
+ Test Processor Plugin
+
+
+
+
+ org.bsc.maven
+ maven-processor-plugin
+ ${project.version}
+
+
+
+ org.mapstruct
+ mapstruct-processor
+ 1.4.2.Final
+
+
+
+
+
+
+
+
\ No newline at end of file