Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Issue #6 : Reconcile m2e-apt & excilys.ebi.m2e.apt

New complete refactoring to enable support for different annotation
processing strategies (I basically broke everything):
- New mode maven_execution corresponds to executing maven-processor-plugin
  as a build participant (code from
  https://github.com/excilys/m2e-extras/blob/40502d278f26a6beae07bcbed6ba7eed0a9226a6/com.excilys.ebi.m2e.apt/src/main/java/com/excilys/ebi/m2e/apt/internal/AptBuildParticipant.java)
- For some reason, executing maven-compiler-plugin with proc:only as part
  of a Build participant didn't pan out. That means the maven_execution
  mode is downgraded (or promoted?) to jdt_apt for  maven-compiler-plugin
- Generated source folders are automatically created in maven_execution
  mode (if annotation processing is detected) so the folders can be added
  to the project's classpath (no need to add some build-helper-maven-plugin
  configuration)

Signed-off-by: Fred Bricon <fbricon@gmail.com>
  • Loading branch information...
commit db6b635019f110f4edacf2f1bf671fe495d31104 1 parent afc5978
@fbricon fbricon authored
Showing with 1,349 additions and 522 deletions.
  1. +2 −2 org.jboss.tools.maven.apt.core/plugin.xml
  2. +274 −0 org.jboss.tools.maven.apt.core/src/org/jboss/tools/maven/apt/internal/AbstractAptConfiguratorDelegate.java
  3. +37 −318 org.jboss.tools.maven.apt.core/src/org/jboss/tools/maven/apt/internal/AbstractAptProjectConfigurator.java
  4. +2 −0  org.jboss.tools.maven.apt.core/src/org/jboss/tools/maven/apt/internal/AnnotationProcessorConfiguration.java
  5. +44 −0 org.jboss.tools.maven.apt.core/src/org/jboss/tools/maven/apt/internal/AptConfiguratorDelegate.java
  6. +10 −0 ...ss.tools.maven.apt.core/src/org/jboss/tools/maven/apt/internal/DefaultAnnotationProcessorConfiguration.java
  7. +0 −131 org.jboss.tools.maven.apt.core/src/org/jboss/tools/maven/apt/internal/MavenCompilerAptProjectConfigurator.java
  8. +0 −64 ...jboss.tools.maven.apt.core/src/org/jboss/tools/maven/apt/internal/MavenProcessorAptProjectConfigurator.java
  9. +55 −0 org.jboss.tools.maven.apt.core/src/org/jboss/tools/maven/apt/internal/NoOpDelegate.java
  10. +36 −0 ...ols.maven.apt.core/src/org/jboss/tools/maven/apt/internal/compiler/MavenCompilerAptProjectConfigurator.java
  11. +138 −0 ...oss.tools.maven.apt.core/src/org/jboss/tools/maven/apt/internal/compiler/MavenCompilerBuildParticipant.java
  12. +57 −0 ...ss.tools.maven.apt.core/src/org/jboss/tools/maven/apt/internal/compiler/MavenCompilerExecutionDelegate.java
  13. +107 −0 ...jboss.tools.maven.apt.core/src/org/jboss/tools/maven/apt/internal/compiler/MavenCompilerJdtAptDelegate.java
  14. +36 −0 ...s.maven.apt.core/src/org/jboss/tools/maven/apt/internal/processor/MavenProcessorAptProjectConfigurator.java
  15. +90 −0 ...s.tools.maven.apt.core/src/org/jboss/tools/maven/apt/internal/processor/MavenProcessorBuildParticipant.java
  16. +108 −0 ....tools.maven.apt.core/src/org/jboss/tools/maven/apt/internal/processor/MavenProcessorExecutionDelegate.java
  17. +95 −0 ...oss.tools.maven.apt.core/src/org/jboss/tools/maven/apt/internal/processor/MavenProcessorJdtAptDelegate.java
  18. +1 −1  ...s.tools.maven.apt.core/src/org/jboss/tools/maven/apt/internal/{ → utils}/AnnotationServiceLocator.java
  19. +1 −1  ...s.tools.maven.apt.core/src/org/jboss/tools/maven/apt/internal/{ → utils}/PluginDependencyResolver.java
  20. +210 −0 org.jboss.tools.maven.apt.core/src/org/jboss/tools/maven/apt/internal/utils/ProjectUtils.java
  21. +1 −1  org.jboss.tools.maven.apt.core/src/org/jboss/tools/maven/apt/preferences/AnnotationProcessingMode.java
  22. +7 −0 org.jboss.tools.maven.apt.tests/projects/p3/pom.xml
  23. +26 −1 org.jboss.tools.maven.apt.tests/src/org/jboss/tools/maven/apt/tests/M2eAptProjectconfiguratorTest.java
  24. +9 −3 ...jboss.tools.maven.apt.ui/src/org/jboss/tools/maven/apt/ui/preferences/AnnotationProcessingSettingsPage.java
  25. +2 −0  org.jboss.tools.maven.apt.ui/src/org/jboss/tools/maven/apt/ui/preferences/PreferenceMessages.java
  26. +1 −0  org.jboss.tools.maven.apt.ui/src/org/jboss/tools/maven/apt/ui/preferences/preferenceMessages.properties
View
4 org.jboss.tools.maven.apt.core/plugin.xml
@@ -11,14 +11,14 @@
<extension
point="org.eclipse.m2e.core.projectConfigurators">
<configurator
- class="org.jboss.tools.maven.apt.internal.MavenCompilerAptProjectConfigurator"
+ class="org.jboss.tools.maven.apt.internal.compiler.MavenCompilerAptProjectConfigurator"
id="org.jboss.tools.maven.apt.MavenCompilerAptProjectConfigurator"
name="%configurator.compiler.name"
secondaryTo="org.eclipse.m2e.jdt.javaConfigurator">
</configurator>
<configurator
- class="org.jboss.tools.maven.apt.internal.MavenProcessorAptProjectConfigurator"
+ class="org.jboss.tools.maven.apt.internal.processor.MavenProcessorAptProjectConfigurator"
id="org.jboss.tools.maven.apt.MavenProcessorAptProjectConfigurator"
name="%configurator.processor.name"
>
View
274 org.jboss.tools.maven.apt.core/src/org/jboss/tools/maven/apt/internal/AbstractAptConfiguratorDelegate.java
@@ -0,0 +1,274 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Red Hat, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Red Hat, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.jboss.tools.maven.apt.internal;
+
+import static org.jboss.tools.maven.apt.internal.utils.ProjectUtils.containsAptProcessors;
+import static org.jboss.tools.maven.apt.internal.utils.ProjectUtils.convertToProjectRelativePath;
+import static org.jboss.tools.maven.apt.internal.utils.ProjectUtils.filterToResolvedJars;
+import static org.jboss.tools.maven.apt.internal.utils.ProjectUtils.getProjectArtifacts;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jdt.apt.core.util.AptConfig;
+import org.eclipse.jdt.apt.core.util.IFactoryPath;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaCore;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.model.PluginExecution;
+import org.apache.maven.plugin.MojoExecution;
+import org.apache.maven.project.MavenProject;
+
+import org.eclipse.m2e.core.MavenPlugin;
+import org.eclipse.m2e.core.embedder.IMaven;
+import org.eclipse.m2e.core.project.IMavenProjectFacade;
+import org.eclipse.m2e.core.project.configurator.AbstractBuildParticipant;
+import org.eclipse.m2e.core.project.configurator.AbstractProjectConfigurator;
+import org.eclipse.m2e.jdt.IClasspathDescriptor;
+import org.eclipse.m2e.jdt.IClasspathEntryDescriptor;
+
+
+/**
+ * AbstractAptConfiguratorDelegate
+ *
+ * @author Fred Bricon
+ */
+public abstract class AbstractAptConfiguratorDelegate implements AptConfiguratorDelegate {
+
+ private static final String M2_REPO = "M2_REPO";
+
+ private static final Logger LOG = LoggerFactory.getLogger(AbstractAptConfiguratorDelegate.class);
+
+ protected IMavenProjectFacade mavenFacade ;
+
+ protected MavenSession mavenSession;
+
+ protected IMaven maven;
+
+ public AbstractAptConfiguratorDelegate() {
+ maven = MavenPlugin.getMaven();
+ }
+
+ public void setSession(MavenSession mavenSession) {
+ this.mavenSession = mavenSession;
+ }
+
+ public void setFacade(IMavenProjectFacade mavenProjectFacade) {
+ this.mavenFacade = mavenProjectFacade;
+ }
+
+ public boolean isIgnored(IProgressMonitor monitor) throws CoreException {
+ return false;
+ }
+
+ public AbstractBuildParticipant getMojoExecutionBuildParticipant(MojoExecution execution) {
+ return null;
+ }
+
+ /**
+ * Configures APT for the specified Maven project.
+ */
+ public void configureProject(IProgressMonitor monitor) throws CoreException {
+
+ IProject eclipseProject = mavenFacade.getProject();
+ // In case the Javaconfigurator was not called yet (eg. maven-processor-plugin being bound to process-sources,
+ // that project configurator runs first) We need to add the Java Nature before setting the APT config.
+ if(!eclipseProject .hasNature(JavaCore.NATURE_ID)) {
+ AbstractProjectConfigurator.addNature(eclipseProject, JavaCore.NATURE_ID, monitor);
+ }
+
+ AnnotationProcessorConfiguration configuration = getAnnotationProcessorConfiguration(monitor);
+
+ File generatedSourcesDirectory = configuration .getOutputDirectory();
+
+ // If this project has no valid generatedSourcesDirectory, we have nothing to do
+ if(generatedSourcesDirectory == null)
+ return;
+
+ IJavaProject javaProject = JavaCore.create(eclipseProject);
+
+ //The plugin dependencies are added first to the classpath
+ LinkedHashSet<File> resolvedJarArtifacts = new LinkedHashSet<File>(configuration.getDependencies());
+ // Get the project's dependencies
+ List<Artifact> artifacts = getProjectArtifacts(mavenFacade);
+ resolvedJarArtifacts.addAll(filterToResolvedJars(artifacts));
+
+ // Inspect the dependencies to see if any contain APT processors
+ boolean isAnnotationProcessingEnabled = configuration.isAnnotationProcessingEnabled()
+ && containsAptProcessors(resolvedJarArtifacts);
+
+ // Enable/Disable APT (depends on whether APT processors were found)
+ AptConfig.setEnabled(javaProject, isAnnotationProcessingEnabled);
+
+ //If no annotation processor is disabled, we can leave.
+ if (!isAnnotationProcessingEnabled) {
+ return;
+ }
+ LOG.debug("Enabling APT support on {}",eclipseProject.getName());
+ // Configure APT output path
+ File generatedSourcesRelativeDirectory = convertToProjectRelativePath(eclipseProject, generatedSourcesDirectory);
+ String generatedSourcesRelativeDirectoryPath = generatedSourcesRelativeDirectory.getPath();
+
+ AptConfig.setGenSrcDir(javaProject, generatedSourcesRelativeDirectoryPath);
+
+ /*
+ * Add all of the compile-scoped JAR artifacts to a new IFactoryPath (in
+ * addition to the workspace's default entries).
+ *
+ * Please note that--until JDT-APT supports project factory path entries
+ * (as opposed to just JARs)--this will be a bit wonky. Specifically, any
+ * project dependencies will be excluded, but their transitive JAR
+ * dependencies will be included.
+ *
+ * Also note: we add the artifacts in reverse order as
+ * IFactoryPath.addExternalJar(File) adds items to the top of the factory
+ * list.
+ */
+ List<File> resolvedJarArtifactsInReverseOrder = new ArrayList<File>(resolvedJarArtifacts);
+ Collections.reverse(resolvedJarArtifactsInReverseOrder);
+ IFactoryPath factoryPath = AptConfig.getDefaultFactoryPath(javaProject);
+
+ IPath m2RepoPath = JavaCore.getClasspathVariable(M2_REPO);
+
+ for(File resolvedJarArtifact : resolvedJarArtifactsInReverseOrder) {
+ IPath absolutePath = new Path(resolvedJarArtifact.getAbsolutePath());
+ //reference jars in a portable way
+ if (m2RepoPath != null && m2RepoPath.isPrefixOf(absolutePath)) {
+ IPath relativePath = absolutePath.removeFirstSegments(m2RepoPath.segmentCount()).makeRelative().setDevice(null);
+ IPath variablePath = new Path(M2_REPO).append(relativePath);
+ factoryPath.addVarJar(variablePath);
+ } else {
+ //fall back on using absolute references.
+ factoryPath.addExternalJar(resolvedJarArtifact);
+ }
+ }
+
+ Map<String, String> currentOptions = AptConfig.getProcessorOptions(javaProject);
+ Map<String, String> newOptions = configuration.getAnnotationProcessorOptions();
+ if (!currentOptions.equals(newOptions)) {
+ AptConfig.setProcessorOptions(newOptions, javaProject);
+ }
+
+ // Apply that IFactoryPath to the project
+ AptConfig.setFactoryPath(javaProject, factoryPath);
+ }
+
+
+
+ public void configureClasspath(IClasspathDescriptor classpath, IProgressMonitor monitor) throws CoreException {
+
+ AnnotationProcessorConfiguration configuration = getAnnotationProcessorConfiguration(monitor);
+
+ if (!configuration.isAnnotationProcessingEnabled()) {
+ return;
+ }
+
+ //Add generated source directory to classpath
+ File generatedSourcesDirectory = configuration.getOutputDirectory();
+ MavenProject mavenProject = mavenFacade.getMavenProject();
+ IProject eclipseProject = mavenFacade.getProject();
+
+ if(generatedSourcesDirectory != null && generatedSourcesDirectory.exists()) {
+ File outputFolder = new File(mavenProject.getBuild().getOutputDirectory());
+ addToClassPath(eclipseProject, generatedSourcesDirectory, outputFolder, classpath);
+ }
+
+ //Add generated test source directory to classpath
+ File generatedTestSourcesDirectory = configuration.getTestOutputDirectory();
+ if(generatedTestSourcesDirectory != null && generatedTestSourcesDirectory.exists()) {
+ File outputFolder = new File(mavenProject.getBuild().getTestOutputDirectory());
+ addToClassPath(eclipseProject, generatedTestSourcesDirectory, outputFolder, classpath);
+ }
+ }
+
+ protected abstract AnnotationProcessorConfiguration getAnnotationProcessorConfiguration(IProgressMonitor monitor) throws CoreException;
+
+
+ private void addToClassPath(IProject project, File sourceDirectory, File targetDirectory, IClasspathDescriptor classpath) {
+ // Get the generated annotation sources directory as an IFolder
+ File generatedSourcesRelativeDirectory = convertToProjectRelativePath(project, sourceDirectory);
+ String generatedSourcesRelativeDirectoryPath = generatedSourcesRelativeDirectory.getPath();
+ IFolder generatedSourcesFolder = project.getFolder(generatedSourcesRelativeDirectoryPath);
+
+ // Get the output folder to use as an IPath
+ File outputRelativeFile = convertToProjectRelativePath(project, targetDirectory);
+ IFolder outputFolder = project.getFolder(outputRelativeFile.getPath());
+ IPath outputPath = outputFolder.getFullPath();
+
+ // Create the includes & excludes specifiers
+ IPath[] includes = new IPath[] {};
+ IPath[] excludes = new IPath[] {};
+
+ // If the source folder is non-nested, add it
+ if(generatedSourcesFolder != null && generatedSourcesFolder.getProject().equals(project)) {
+ IClasspathEntryDescriptor enclosing = getEnclosingEntryDescriptor(classpath, generatedSourcesFolder.getFullPath());
+ if(enclosing == null || getEntryDescriptor(classpath, generatedSourcesFolder.getFullPath()) != null ) {
+ classpath.addSourceEntry(generatedSourcesFolder.getFullPath(), outputPath, includes, excludes, true);
+ }
+ } else {
+ if(generatedSourcesFolder != null) {
+ classpath.removeEntry(generatedSourcesFolder.getFullPath());
+ }
+ }
+
+ }
+
+ /**
+ * Returns the {@link IClasspathEntryDescriptor} in the specified {@link IClasspathDescriptor} that is a prefix of the
+ * specified {@link IPath}.
+ *
+ * @param classpath the {@link IClasspathDescriptor} to be searched for a matching {@link IClasspathEntryDescriptor}
+ * @param path the {@link IPath} to find a matching {@link IClasspathEntryDescriptor} for
+ * @return the {@link IClasspathEntryDescriptor} in the specified {@link IClasspathDescriptor} that is a prefix of the
+ * specified {@link IPath}
+ */
+ private static IClasspathEntryDescriptor getEnclosingEntryDescriptor(IClasspathDescriptor classpath, IPath path) {
+ for(IClasspathEntryDescriptor cped : classpath.getEntryDescriptors()) {
+ if(cped.getPath().isPrefixOf(path)) {
+ return cped;
+ }
+ }
+ return null;
+ }
+
+ private IClasspathEntryDescriptor getEntryDescriptor(IClasspathDescriptor classpath, IPath fullPath) {
+ for(IClasspathEntryDescriptor cped : classpath.getEntryDescriptors()) {
+ if(cped.getPath().equals(fullPath)) {
+ return cped;
+ }
+ }
+ return null;
+ }
+
+ protected <T> T getParameterValue(String parameter, Class<T> asType, MavenSession session, MojoExecution mojoExecution)
+ throws CoreException {
+ PluginExecution execution = new PluginExecution();
+ execution.setConfiguration(mojoExecution.getConfiguration());
+ return maven.getMojoParameterValue(parameter, asType, session, mojoExecution.getPlugin(), execution,
+ mojoExecution.getGoal());
+ }
+
+}
View
355 org.jboss.tools.maven.apt.core/src/org/jboss/tools/maven/apt/internal/AbstractAptProjectConfigurator.java
@@ -12,43 +12,24 @@
package org.jboss.tools.maven.apt.internal;
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
import org.jboss.tools.maven.apt.MavenJdtAptPlugin;
-import org.jboss.tools.maven.apt.internal.AnnotationServiceLocator.ServiceEntry;
import org.jboss.tools.maven.apt.preferences.AnnotationProcessingMode;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.jboss.tools.maven.apt.preferences.IPreferencesManager;
-import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.jdt.apt.core.util.AptConfig;
-import org.eclipse.jdt.apt.core.util.IFactoryPath;
-import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
-import org.apache.maven.artifact.Artifact;
-import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter;
import org.apache.maven.execution.MavenSession;
-import org.apache.maven.project.MavenProject;
+import org.apache.maven.plugin.MojoExecution;
+import org.eclipse.m2e.core.lifecyclemapping.model.IPluginExecutionMetadata;
import org.eclipse.m2e.core.project.IMavenProjectFacade;
+import org.eclipse.m2e.core.project.configurator.AbstractBuildParticipant;
import org.eclipse.m2e.core.project.configurator.AbstractProjectConfigurator;
import org.eclipse.m2e.core.project.configurator.ProjectConfigurationRequest;
import org.eclipse.m2e.jdt.IClasspathDescriptor;
-import org.eclipse.m2e.jdt.IClasspathEntryDescriptor;
import org.eclipse.m2e.jdt.IJavaProjectConfigurator;
@@ -79,14 +60,10 @@
* search path.
* </p>
*/
-abstract class AbstractAptProjectConfigurator extends AbstractProjectConfigurator implements IJavaProjectConfigurator {
+public abstract class AbstractAptProjectConfigurator extends AbstractProjectConfigurator implements IJavaProjectConfigurator {
+
+ protected abstract AptConfiguratorDelegate getDelegate(AnnotationProcessingMode mode);
- private static final String M2_REPO = "M2_REPO";
-
- private static final Logger LOG = LoggerFactory.getLogger(AbstractAptProjectConfigurator.class);
-
- protected abstract AnnotationProcessorConfiguration getAnnotationProcessorConfiguration(IMavenProjectFacade mavenProjectFacade, MavenSession mavenSession, IProgressMonitor monitor) throws CoreException;
-
/**
* {@inheritDoc}
*/
@@ -100,229 +77,20 @@ public void configure(ProjectConfigurationRequest request, IProgressMonitor moni
// Get the objects needed for APT configuration
IMavenProjectFacade mavenProjectFacade = request.getMavenProjectFacade();
+
IProject eclipseProject = mavenProjectFacade.getProject();
- if (AnnotationProcessingMode.jdt_apt
- != MavenJdtAptPlugin.getDefault().getPreferencesManager().getAnnotationProcessorMode(eclipseProject)) {
- return;
- }
+ AnnotationProcessingMode mode = getAnnotationProcessorMode(eclipseProject);
MavenSession mavenSession = request.getMavenSession();
-
- if (ignoreConfigurator(mavenProjectFacade, monitor)) {
- return;
- }
-
- AnnotationProcessorConfiguration configuration = getAnnotationProcessorConfiguration(mavenProjectFacade, mavenSession, monitor);
- // Configure APT
- configureAptForProject(eclipseProject, mavenProjectFacade, configuration, monitor);
- }
-
- protected boolean ignoreConfigurator(IMavenProjectFacade mavenProjectFacade, IProgressMonitor monitor) throws CoreException {
- return false;
- }
-
- /**
- * Configures APT for the specified Maven project.
- *
- * @param eclipseProject an {@link IProject} reference to the Eclipse project being configured
- * @param mavenProject {@link IMavenProjectFacade} reference to the Maven project being configured
- * @param monitor the {@link IProgressMonitor} to use
- * @param mavenProjectFacade
- * @throws CoreException Any {@link CoreException}s thrown will be passed through.
- */
- private void configureAptForProject(IProject eclipseProject, IMavenProjectFacade mavenProjectFacade, AnnotationProcessorConfiguration configuration, IProgressMonitor monitor) throws CoreException {
-
- // In case the Javaconfigurator was not called yet (eg. maven-processor-plugin being bound to process-sources,
- // that project configurator runs first) We need to add the Java Nature before setting the APT config.
- if(!eclipseProject.hasNature(JavaCore.NATURE_ID)) {
- addNature(eclipseProject, JavaCore.NATURE_ID, monitor);
- }
-
- File generatedSourcesDirectory = configuration.getOutputDirectory();
-
- // If this project has no valid generatedSourcesDirectory, we have nothing to do
- if(generatedSourcesDirectory == null)
- return;
-
- IJavaProject javaProject = JavaCore.create(eclipseProject);
- //The plugin dependencies are added first to the classpath
- LinkedHashSet<File> resolvedJarArtifacts = new LinkedHashSet<File>(configuration.getDependencies());
- // Get the project's dependencies
- List<Artifact> artifacts = getProjectArtifacts(mavenProjectFacade);
- resolvedJarArtifacts.addAll(filterToResolvedJars(artifacts));
+ AptConfiguratorDelegate configuratorDelegate = getDelegate(mode);
+ configuratorDelegate.setSession(mavenSession);
+ configuratorDelegate.setFacade(mavenProjectFacade);
- // Inspect the dependencies to see if any contain APT processors
- boolean isAnnotationProcessingEnabled = configuration.isAnnotationProcessingEnabled()
- && containsAptProcessors(resolvedJarArtifacts);
-
- // Enable/Disable APT (depends on whether APT processors were found)
- AptConfig.setEnabled(javaProject, isAnnotationProcessingEnabled);
-
- //If no annotation processor is disabled, we can leave.
- if (!isAnnotationProcessingEnabled) {
- return;
- }
- LOG.debug("Enabling APT support on {}",eclipseProject.getName());
- // Configure APT output path
- File generatedSourcesRelativeDirectory = convertToProjectRelativePath(eclipseProject, generatedSourcesDirectory);
- String generatedSourcesRelativeDirectoryPath = generatedSourcesRelativeDirectory.getPath();
-
- //createFolder(eclipseProject.getFolder(generatedSourcesRelativeDirectoryPath), monitor);
- AptConfig.setGenSrcDir(javaProject, generatedSourcesRelativeDirectoryPath);
-
- /*
- * Add all of the compile-scoped JAR artifacts to a new IFactoryPath (in
- * addition to the workspace's default entries).
- *
- * Please note that--until JDT-APT supports project factory path entries
- * (as opposed to just JARs)--this will be a bit wonky. Specifically, any
- * project dependencies will be excluded, but their transitive JAR
- * dependencies will be included.
- *
- * Also note: we add the artifacts in reverse order as
- * IFactoryPath.addExternalJar(File) adds items to the top of the factory
- * list.
- */
- List<File> resolvedJarArtifactsInReverseOrder = new ArrayList<File>(resolvedJarArtifacts);
- Collections.reverse(resolvedJarArtifactsInReverseOrder);
- IFactoryPath factoryPath = AptConfig.getDefaultFactoryPath(javaProject);
-
- IPath m2RepoPath = JavaCore.getClasspathVariable(M2_REPO);
-
- for(File resolvedJarArtifact : resolvedJarArtifactsInReverseOrder) {
- IPath absolutePath = new Path(resolvedJarArtifact.getAbsolutePath());
- //reference jars in a portable way
- if (m2RepoPath != null && m2RepoPath.isPrefixOf(absolutePath)) {
- IPath relativePath = absolutePath.removeFirstSegments(m2RepoPath.segmentCount()).makeRelative().setDevice(null);
- IPath variablePath = new Path(M2_REPO).append(relativePath);
- factoryPath.addVarJar(variablePath);
- } else {
- //fall back on using absolute references.
- factoryPath.addExternalJar(resolvedJarArtifact);
- }
- }
-
- Map<String, String> currentOptions = AptConfig.getProcessorOptions(javaProject);
- Map<String, String> newOptions = configuration.getAnnotationProcessorOptions();
- if (!currentOptions.equals(newOptions)) {
- AptConfig.setProcessorOptions(newOptions, javaProject);
- }
-
- // Apply that IFactoryPath to the project
- AptConfig.setFactoryPath(javaProject, factoryPath);
- }
-
-
- /**
- * @param mavenProjectFacade the {@link IMavenProjectFacade} to get the {@link Artifact}s for
- * @return an ordered {@link List} of the specified {@link IMavenProjectFacade}'s {@link Artifact}s
- */
- private static List<Artifact> getProjectArtifacts(IMavenProjectFacade mavenProjectFacade) {
- /*
- * This method essentially wraps org.apache.maven.project.MavenProject.getArtifacts(),
- * returning a List instead of a Set to indicate that ordering is maintained and important.
- * The set being "wrapped" is actually a LinkedHashSet, which does guarantee a consistent
- * insertion & iteration order.
- */
-
- Set<Artifact> unorderedArtifacts = mavenProjectFacade.getMavenProject().getArtifacts();
- List<Artifact> orderedArtifacts = new ArrayList<Artifact>(unorderedArtifacts.size());
- for(Artifact artifact : unorderedArtifacts)
- orderedArtifacts.add(artifact);
- return orderedArtifacts;
- }
-
-
- /**
- * <p>
- * Filters the specified {@link Artifact}s to those that match the following criteria:
- * </p>
- * <ul>
- * <li>{@link Artifact#isResolved()} is <code>true</code></li>
- * <li>{@link Artifact#getArtifactHandler().getExtension()} equals "jar"</li>
- * <li>{@link Artifact#getScope()} equals {@link Artifact#SCOPE_COMPILE}</li>
- * <li>{@link Artifact#getFile()} returns a {@link File} where {@link File#isFile()} is <code>true</code></li>
- * </ul>
- *
- * @param artifacts the {@link Set} of {@link Artifact}s to filter
- * @return the actual JAR {@link File}s available from the specified {@link Artifact}s
- */
- private static List<File> filterToResolvedJars(List<Artifact> artifacts) {
- List<File> resolvedJarArtifacts = new ArrayList<File>();
- ScopeArtifactFilter filter = new ScopeArtifactFilter(Artifact.SCOPE_COMPILE_PLUS_RUNTIME);
-
- for(Artifact artifact : artifacts) {
- // Ensure that this Artifact should be included
- if(!artifact.isResolved())
- continue;
- if(artifact.getArtifactHandler() == null
- || !"jar".equalsIgnoreCase(artifact.getArtifactHandler().getExtension()))
- continue;
- if(!filter.include(artifact))
- continue;
-
- // Ensure that the Artifact resolves to a File that we can use
- File artifactJarFile = artifact.getFile();
- if(!artifactJarFile.isFile())
- continue;
-
- resolvedJarArtifacts.add(artifactJarFile);
- }
-
- return resolvedJarArtifacts;
- }
-
- /**
- * Returns <code>true</code> if any of the specified JARs contain a Java 5 or Java 6 annotation processor,
- * <code>false</code> if none of them do.
- *
- * @param resolvedJarArtifacts the JAR {@link File}s to inspect for annotation processors
- * @return <code>true</code> if any of the specified JARs contain a Java 5 or Java 6 annotation processor,
- * <code>false</code> if none of them do
- */
- private static boolean containsAptProcessors(Collection<File> resolvedJarArtifacts) {
- // Read through all JARs, checking for any APT service entries
- try {
- for(File resolvedJarArtifact : resolvedJarArtifacts) {
- Set<ServiceEntry> aptServiceEntries = AnnotationServiceLocator.getAptServiceEntries(resolvedJarArtifact);
- if(!aptServiceEntries.isEmpty())
- return true;
- }
- } catch(IOException e) {
- MavenJdtAptPlugin.createErrorStatus(e, "Error while reading artifact JARs.");
- }
-
- // No service entries were found
- return false;
- }
-
- /**
- * Converts the specified relative or absolute {@link File} to a {@link File} that is relative to the base directory
- * of the specified {@link IProject}.
- *
- * @param project the {@link IProject} whose base directory the returned {@link File} should be relative to
- * @param fileToConvert the relative or absolute {@link File} to convert
- * @return a {@link File} that is relative to the base directory of the specified {@link IProject}
- */
- protected File convertToProjectRelativePath(IProject project, File fileToConvert) {
- // Get an absolute version of the specified file
- File absoluteFile = fileToConvert.getAbsoluteFile();
- String absoluteFilePath = absoluteFile.getAbsolutePath();
-
- // Get a File for the absolute path to the project's directory
- File projectBasedirFile = project.getLocation().toFile().getAbsoluteFile();
- String projectBasedirFilePath = projectBasedirFile.getAbsolutePath();
-
- // Compute the relative path
- if(absoluteFile.equals(projectBasedirFile)) {
- return new File(".");
- } else if(absoluteFilePath.startsWith(projectBasedirFilePath)) {
- String projectRelativePath = absoluteFilePath.substring(projectBasedirFilePath.length() + 1);
- return new File(projectRelativePath);
- } else {
- return absoluteFile;
+ // Configure APT
+ if (!configuratorDelegate.isIgnored(monitor)) {
+ configuratorDelegate.configureProject(monitor);
}
}
@@ -350,84 +118,35 @@ public void configureRawClasspath(ProjectConfigurationRequest request, IClasspat
*/
// Get the various project references we'll need
IProject eclipseProject = request.getProject();
- if (AnnotationProcessingMode.jdt_apt
- != MavenJdtAptPlugin.getDefault().getPreferencesManager().getAnnotationProcessorMode(eclipseProject)) {
+ if(!eclipseProject.hasNature(JavaCore.NATURE_ID))
return;
- }
-
- MavenProject mavenProject = request.getMavenProject();
- IMavenProjectFacade projectFacade = request.getMavenProjectFacade();
- MavenSession mavenSession = request.getMavenSession();
+ AptConfiguratorDelegate delegate = getDelegate(eclipseProject);
+ delegate.setFacade(request.getMavenProjectFacade());
+ delegate.setSession(request.getMavenSession());
// If this isn't a Java project, we have nothing to do
- if(!eclipseProject.hasNature(JavaCore.NATURE_ID))
- return;
- if (ignoreConfigurator(projectFacade, monitor)) {
- return;
- }
-
- //If APT is not enabled, nothing to do either
- IJavaProject javaProject = JavaCore.create(eclipseProject);
- if (!AptConfig.isEnabled(javaProject)) {
- return;
+ if (!delegate.isIgnored(monitor)) {
+ delegate.configureClasspath(classpath, monitor);
}
-
- AnnotationProcessorConfiguration configuration = getAnnotationProcessorConfiguration(projectFacade, mavenSession, monitor);
- if (!configuration.isAnnotationProcessingEnabled()) {
- return;
- }
-
- // If this project has no valid compiler plugin config, we have nothing to do
- File generatedSourcesDirectory = configuration.getOutputDirectory();
- if(generatedSourcesDirectory == null)
- return;
-
- // Get the generated annotation sources directory as an IFolder
- File generatedSourcesRelativeDirectory = convertToProjectRelativePath(eclipseProject, generatedSourcesDirectory);
- String generatedSourcesRelativeDirectoryPath = generatedSourcesRelativeDirectory.getPath();
- IFolder generatedSourcesFolder = eclipseProject.getFolder(generatedSourcesRelativeDirectoryPath);
- // Get the output folder to use as an IPath
- File outputFile = new File(mavenProject.getBuild().getOutputDirectory());
- File outputRelativeFile = convertToProjectRelativePath(eclipseProject, outputFile);
- IFolder outputFolder = eclipseProject.getFolder(outputRelativeFile.getPath());
- IPath outputPath = outputFolder.getFullPath();
-
- // Create the includes & excludes specifiers
- IPath[] includes = new IPath[] {};
- IPath[] excludes = new IPath[] {};
-
- // If the source folder exists and is non-nested, add it
- if(generatedSourcesFolder != null && generatedSourcesFolder.exists()
- && generatedSourcesFolder.getProject().equals(eclipseProject)) {
- IClasspathEntryDescriptor cped = getEnclosingEntryDescriptor(classpath, generatedSourcesFolder.getFullPath());
- if(cped == null) {
- classpath.addSourceEntry(generatedSourcesFolder.getFullPath(), outputPath, includes, excludes, false);
- }
- } else {
- if(generatedSourcesFolder != null) {
- classpath.removeEntry(generatedSourcesFolder.getFullPath());
- }
- }
}
-
- /**
- * Returns the {@link IClasspathEntryDescriptor} in the specified {@link IClasspathDescriptor} that is a prefix of the
- * specified {@link IPath}.
- *
- * @param classpath the {@link IClasspathDescriptor} to be searched for a matching {@link IClasspathEntryDescriptor}
- * @param path the {@link IPath} to find a matching {@link IClasspathEntryDescriptor} for
- * @return the {@link IClasspathEntryDescriptor} in the specified {@link IClasspathDescriptor} that is a prefix of the
- * specified {@link IPath}
- */
- private static IClasspathEntryDescriptor getEnclosingEntryDescriptor(IClasspathDescriptor classpath, IPath path) {
- for(IClasspathEntryDescriptor cped : classpath.getEntryDescriptors()) {
- if(cped.getPath().isPrefixOf(path)) {
- return cped;
- }
- }
- return null;
+
+ public AbstractBuildParticipant getBuildParticipant(IMavenProjectFacade projectFacade, MojoExecution execution,
+ IPluginExecutionMetadata executionMetadata) {
+
+ AptConfiguratorDelegate configuratorDelegate = getDelegate(projectFacade.getProject());
+
+ return configuratorDelegate.getMojoExecutionBuildParticipant(execution);
}
+ private AptConfiguratorDelegate getDelegate(IProject project) {
+ AnnotationProcessingMode mode = getAnnotationProcessorMode(project);
+ return getDelegate(mode);
+ }
+
+ protected AnnotationProcessingMode getAnnotationProcessorMode(IProject project) {
+ IPreferencesManager preferencesManager = MavenJdtAptPlugin.getDefault().getPreferencesManager();
+ return preferencesManager.getAnnotationProcessorMode(project);
+ }
}
View
2  org.jboss.tools.maven.apt.core/src/org/jboss/tools/maven/apt/internal/AnnotationProcessorConfiguration.java
@@ -26,6 +26,8 @@
File getOutputDirectory();
+ File getTestOutputDirectory();
+
List<String> getAnnotationProcessors();
}
View
44 org.jboss.tools.maven.apt.core/src/org/jboss/tools/maven/apt/internal/AptConfiguratorDelegate.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Red Hat, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Red Hat, Inc. - initial API and implementation
+ *******************************************************************************/
+
+package org.jboss.tools.maven.apt.internal;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.plugin.MojoExecution;
+
+import org.eclipse.m2e.core.project.IMavenProjectFacade;
+import org.eclipse.m2e.core.project.configurator.AbstractBuildParticipant;
+import org.eclipse.m2e.jdt.IClasspathDescriptor;
+
+/**
+ * AptConfiguratorDelegate
+ *
+ * @author Fred Bricon
+ */
+public interface AptConfiguratorDelegate {
+
+ void setSession(MavenSession mavenSession);
+
+ void setFacade(IMavenProjectFacade mavenProjectFacade);
+
+ void configureProject(IProgressMonitor monitor) throws CoreException;
+
+ void configureClasspath(IClasspathDescriptor classpath, IProgressMonitor monitor) throws CoreException;
+
+ boolean isIgnored(IProgressMonitor monitor) throws CoreException;
+
+ AbstractBuildParticipant getMojoExecutionBuildParticipant(MojoExecution execution);
+
+
+}
View
10 ...tools.maven.apt.core/src/org/jboss/tools/maven/apt/internal/DefaultAnnotationProcessorConfiguration.java
@@ -22,6 +22,8 @@
private File outputDirectory = null;
+ private File testOutputDirectory = null;
+
private Map<String, String> annotationProcessorOptions;
private List<String> annotationProcessors;
@@ -78,4 +80,12 @@ public void setAnnotationProcessors(List<String> annotationProcessors) {
this.annotationProcessors = annotationProcessors;
}
+ public File getTestOutputDirectory() {
+ return this.testOutputDirectory;
+ }
+
+ public void setTestOutputDirectory(File testOutputDirectory) {
+ this.testOutputDirectory = testOutputDirectory;
+ }
+
}
View
131 ...oss.tools.maven.apt.core/src/org/jboss/tools/maven/apt/internal/MavenCompilerAptProjectConfigurator.java
@@ -1,131 +0,0 @@
-/*************************************************************************************
- * Copyright (c) 2008-2012 Red Hat, Inc. and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * JBoss by Red Hat - Initial implementation.
- * Karl M. Davis (Knowledge Computing Corp.) - initial implementation
- ************************************************************************************/
-package org.jboss.tools.maven.apt.internal;
-
-import java.io.File;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-
-import org.apache.maven.execution.MavenSession;
-import org.apache.maven.plugin.MojoExecution;
-
-import org.eclipse.m2e.core.project.IMavenProjectFacade;
-
-public class MavenCompilerAptProjectConfigurator extends AbstractAptProjectConfigurator {
-
- /**
- * The <code>groupId</code> of the <a href="http://maven.apache.org/plugins/maven-compiler-plugin/">Maven Compiler
- * Plugin</a>.
- */
- private static final String COMPILER_PLUGIN_GROUP_ID = "org.apache.maven.plugins";
-
- /**
- * The <code>artifactId</code> of the <a href="http://maven.apache.org/plugins/maven-compiler-plugin/">Maven Compiler
- * Plugin</a>.
- */
- private static final String COMPILER_PLUGIN_ARTIFACT_ID = "maven-compiler-plugin";
-
- /**
- * The name of the <a href="http://maven.apache.org/plugins/maven-compiler-plugin/">Maven Compiler Plugin</a>'s
- * "compile" goal.
- */
- private static final String GOAL_COMPILE = "compile";
-
- @Override
- protected AnnotationProcessorConfiguration getAnnotationProcessorConfiguration(
- IMavenProjectFacade mavenProjectFacade, MavenSession mavenSession, IProgressMonitor monitor) throws CoreException {
-
- for(MojoExecution mojoExecution : mavenProjectFacade.getMojoExecutions(COMPILER_PLUGIN_GROUP_ID,
- COMPILER_PLUGIN_ARTIFACT_ID, monitor, GOAL_COMPILE)) {
- File generatedOutputDirectory = maven.getMojoParameterValue(mavenSession, mojoExecution, "generatedSourcesDirectory", File.class);
- String compilerArgument = maven.getMojoParameterValue(mavenSession, mojoExecution, "compilerArgument", String.class);
- Map<String, String> options = parseProcessorOptions(compilerArgument);
-
- boolean isAnnotationProcessingEnabled = compilerArgument == null || !compilerArgument.contains("-proc:none");
- if (isAnnotationProcessingEnabled ) {
- String proc = maven.getMojoParameterValue(mavenSession, mojoExecution, "proc", String.class);
- isAnnotationProcessingEnabled = !"none".equals(proc);
- }
-
- PluginDependencyResolver dependencyResolver = new PluginDependencyResolver();
- List<File> dependencies = dependencyResolver.getResolvedPluginDependencies(mavenSession,
- mavenProjectFacade.getMavenProject(),
- mojoExecution.getPlugin(),
- monitor);
-
-
-
- DefaultAnnotationProcessorConfiguration configuration = new DefaultAnnotationProcessorConfiguration();
- configuration.setOutputDirectory(generatedOutputDirectory);
- configuration.setAnnotationProcessingEnabled(isAnnotationProcessingEnabled);
- configuration.setDependencies(dependencies);
- configuration.setAnnotationProcessorOptions(options);
- return configuration;
- }
-
- return null;
- }
-
- @Override
- protected boolean ignoreConfigurator(IMavenProjectFacade mavenProjectFacade, IProgressMonitor monitor) throws CoreException {
- return !mavenProjectFacade.getMojoExecutions(MavenProcessorAptProjectConfigurator.PROCESSOR_PLUGIN_GROUP_ID,
- MavenProcessorAptProjectConfigurator.PROCESSOR_PLUGIN_ARTIFACT_ID,
- monitor,
- MavenProcessorAptProjectConfigurator.GOAL_PROCESS).isEmpty();
- }
-
- /**
- * @param compilerArgument
- * @return
- */
- private static Map<String, String> parseProcessorOptions(String compilerArgument) {
- if (compilerArgument == null) {
- return Collections.emptyMap();
- }
- Map<String, String> ret = new HashMap<String, String>();
-
- Pattern fullOptionPattern = Pattern.compile("-A([^ \\t\"']+)");
- Matcher matcher = fullOptionPattern.matcher(compilerArgument);
-
- int start = 0;
- while(matcher.find(start)) {
- String argument = matcher.group(1);
-
- final String key;
- final String value;
-
- int optionalEqualsIndex = argument.indexOf('=');
- if (optionalEqualsIndex != -1) {
- key = argument.substring(0, optionalEqualsIndex);
- value = argument.substring(optionalEqualsIndex + 1, argument.length());
- } else {
- key = argument;
- value = "";
- }
-
- ret.put(key, value);
-
- start = matcher.end();
- }
-
- return ret;
- }
-
-
-}
View
64 ...ss.tools.maven.apt.core/src/org/jboss/tools/maven/apt/internal/MavenProcessorAptProjectConfigurator.java
@@ -1,64 +0,0 @@
-/*************************************************************************************
- * Copyright (c) 2008-2012 Red Hat, Inc. and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Red Hat, Inc. - Initial implementation.
- ************************************************************************************/
-package org.jboss.tools.maven.apt.internal;
-
-import java.io.File;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.maven.execution.MavenSession;
-import org.apache.maven.plugin.MojoExecution;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.m2e.core.project.IMavenProjectFacade;
-
-public class MavenProcessorAptProjectConfigurator extends AbstractAptProjectConfigurator {
-
- static final String PROCESSOR_PLUGIN_GROUP_ID = "org.bsc.maven";
-
- static final String PROCESSOR_PLUGIN_ARTIFACT_ID = "maven-processor-plugin";
-
- static final String GOAL_PROCESS = "process";
-
- @Override
- protected AnnotationProcessorConfiguration getAnnotationProcessorConfiguration(
- IMavenProjectFacade mavenProjectFacade, MavenSession mavenSession, IProgressMonitor monitor) throws CoreException {
-
- for(MojoExecution mojoExecution : mavenProjectFacade.getMojoExecutions(PROCESSOR_PLUGIN_GROUP_ID,
- PROCESSOR_PLUGIN_ARTIFACT_ID,
- monitor,
- GOAL_PROCESS)) {
-
- File generatedOutputDirectory = maven.getMojoParameterValue(mavenSession, mojoExecution, "defaultOutputDirectory", File.class);
-
- PluginDependencyResolver dependencyResolver = new PluginDependencyResolver();
- List<File> dependencies = dependencyResolver.getResolvedPluginDependencies(mavenSession,
- mavenProjectFacade.getMavenProject(),
- mojoExecution.getPlugin(),
- monitor);
-
- Map<String, String> options = maven.getMojoParameterValue(mavenSession, mojoExecution, "optionMap", Map.class);
-
-
- DefaultAnnotationProcessorConfiguration configuration = new DefaultAnnotationProcessorConfiguration();
- configuration.setOutputDirectory(generatedOutputDirectory);
- configuration.setAnnotationProcessingEnabled(true);
- configuration.setDependencies(dependencies);
- configuration.setAnnotationProcessorOptions(options);
- return configuration;
- }
-
-
- return null;
- }
-
-
-}
View
55 org.jboss.tools.maven.apt.core/src/org/jboss/tools/maven/apt/internal/NoOpDelegate.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Red Hat, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Red Hat, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.jboss.tools.maven.apt.internal;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.plugin.MojoExecution;
+
+import org.eclipse.m2e.core.project.IMavenProjectFacade;
+import org.eclipse.m2e.core.project.configurator.AbstractBuildParticipant;
+import org.eclipse.m2e.jdt.IClasspathDescriptor;
+
+
+/**
+ * No Operation Configurator Delegate
+ *
+ * @author Fred Bricon
+ */
+public class NoOpDelegate implements AptConfiguratorDelegate {
+
+ public void configureProject(IProgressMonitor monitor) throws CoreException {
+ //No-Op
+ }
+
+ public void configureClasspath(IClasspathDescriptor classpath, IProgressMonitor monitor) throws CoreException {
+ //No-Op
+ }
+
+ public boolean isIgnored(IProgressMonitor monitor) throws CoreException {
+ return true;
+ }
+
+ public void setSession(MavenSession mavenSession) {
+ //No-Op
+ }
+
+ public void setFacade(IMavenProjectFacade mavenProjectFacade) {
+ //No-Op
+ }
+
+ public AbstractBuildParticipant getMojoExecutionBuildParticipant(MojoExecution execution) {
+ return null;
+ }
+
+}
View
36 ....maven.apt.core/src/org/jboss/tools/maven/apt/internal/compiler/MavenCompilerAptProjectConfigurator.java
@@ -0,0 +1,36 @@
+/*************************************************************************************
+ * Copyright (c) 2008-2012 Red Hat, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * JBoss by Red Hat - Initial implementation.
+ * Karl M. Davis (Knowledge Computing Corp.) - initial implementation
+ ************************************************************************************/
+package org.jboss.tools.maven.apt.internal.compiler;
+
+import org.jboss.tools.maven.apt.internal.AbstractAptProjectConfigurator;
+import org.jboss.tools.maven.apt.internal.AptConfiguratorDelegate;
+import org.jboss.tools.maven.apt.internal.NoOpDelegate;
+import org.jboss.tools.maven.apt.preferences.AnnotationProcessingMode;
+
+import org.eclipse.core.runtime.Assert;
+
+public class MavenCompilerAptProjectConfigurator extends AbstractAptProjectConfigurator {
+
+ protected AptConfiguratorDelegate getDelegate(AnnotationProcessingMode mode) {
+ Assert.isNotNull(mode, "AnnotationProcessingMode can not be null");
+ switch(mode) {
+ case jdt_apt:
+ return new MavenCompilerJdtAptDelegate();
+ case maven_execution:
+ return new MavenCompilerExecutionDelegate();
+ case disabled:
+ default:
+ }
+ return new NoOpDelegate();
+ }
+
+}
View
138 ....tools.maven.apt.core/src/org/jboss/tools/maven/apt/internal/compiler/MavenCompilerBuildParticipant.java
@@ -0,0 +1,138 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Excylis and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Excylis - initial API and implementation
+ * Red Hat, Inc.
+ *******************************************************************************/
+package org.jboss.tools.maven.apt.internal.compiler;
+
+import java.io.File;
+import java.util.Collections;
+import java.util.Set;
+
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+
+import org.codehaus.plexus.util.Scanner;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+
+import org.apache.maven.plugin.MojoExecution;
+
+import org.sonatype.plexus.build.incremental.BuildContext;
+
+import org.eclipse.m2e.core.MavenPlugin;
+import org.eclipse.m2e.core.embedder.IMaven;
+import org.eclipse.m2e.core.project.IMavenProjectFacade;
+import org.eclipse.m2e.core.project.configurator.MojoExecutionBuildParticipant;
+
+/**
+ * Executes maven-compiler-plugin:compile with -proc:only
+ *
+ * @author Fred Bricon
+ */
+public class MavenCompilerBuildParticipant extends MojoExecutionBuildParticipant {
+
+ private static final String PROC = "proc";
+
+ public MavenCompilerBuildParticipant(MojoExecution execution) {
+ super(execution, true);
+ }
+
+ @Override
+ public Set<IProject> build(int kind, IProgressMonitor monitor) throws Exception {
+ IMaven maven = MavenPlugin.getMaven();
+ BuildContext buildContext = getBuildContext();
+
+ MojoExecution mojoExecution = getMojoExecution();
+
+ monitor.setTaskName("Executing " +mojoExecution.getArtifactId()+ ":" +mojoExecution.getGoal());
+
+ //TODO check delta / scan source for *.java
+
+ String compilerArgument = maven.getMojoParameterValue(getSession(), mojoExecution, "compilerArgument", String.class);
+ boolean isAnnotationProcessingEnabled = compilerArgument == null || !compilerArgument.contains("-proc:none");
+ if (isAnnotationProcessingEnabled ) {
+ String proc = maven.getMojoParameterValue(getSession(), mojoExecution, PROC, String.class);
+ isAnnotationProcessingEnabled = !"none".equals(proc);
+ }
+ if (!isAnnotationProcessingEnabled) {
+ return Collections.emptySet();
+ }
+
+ IMavenProjectFacade mavenProjectFacade = getMavenProjectFacade();
+
+ if (!buildContext.hasDelta(mavenProjectFacade.getPomFile())) {
+
+ IPath[] sources = "compile".equals(mojoExecution.getGoal())?mavenProjectFacade.getCompileSourceLocations()
+ :mavenProjectFacade.getTestCompileSourceLocations();
+
+ boolean hasSourceChanged = false;
+ for (IPath relPathSource : sources) {
+ IFolder sourceFolder = mavenProjectFacade.getProject().getFolder(relPathSource);
+ File folder = new File(sourceFolder.getRawLocationURI());
+ Scanner ds = buildContext.newScanner(folder); // delta or full scanner
+ ds.scan();
+ String[] includedFiles = ds.getIncludedFiles();
+ if (includedFiles != null && includedFiles.length > 0) {
+ hasSourceChanged = true;
+ break;
+ }
+ }
+ if (!hasSourceChanged) {
+ return Collections.emptySet();
+ }
+ }
+
+
+
+ Xpp3Dom originalConfiguration = mojoExecution.getConfiguration();
+ Set<IProject> result = Collections.emptySet();
+ try {
+ Xpp3Dom newConfiguration = new Xpp3Dom(originalConfiguration);
+ setProcOnly(newConfiguration);
+ setVerbose(newConfiguration);
+ mojoExecution.setConfiguration(newConfiguration);
+ // execute mojo
+ System.err.println("execute " + mojoExecution.getArtifactId()+":"+ mojoExecution.getGoal() +" proc:only for "+mavenProjectFacade.getProject().getName());
+ result = super.build(kind, monitor);
+ } finally {
+ mojoExecution.setConfiguration(originalConfiguration);
+ }
+
+ // tell m2e builder to refresh generated files
+ File generated = maven.getMojoParameterValue(getSession(), getMojoExecution(), MavenCompilerJdtAptDelegate.OUTPUT_DIRECTORY_PARAMETER, File.class);
+ if (generated != null) {
+ buildContext.refresh(generated);
+ }
+
+ return result;
+ }
+
+ /**
+ * @param newConfiguration
+ */
+ private void setVerbose(Xpp3Dom configuration) {
+ Xpp3Dom verboseDom = configuration.getChild("verbose");
+ if(verboseDom == null) {
+ verboseDom = new Xpp3Dom("verbose");
+ configuration.addChild(verboseDom);
+ }
+ verboseDom.setValue("true");
+ }
+
+ private void setProcOnly(Xpp3Dom configuration) {
+ Xpp3Dom procDom = configuration.getChild(PROC);
+ if(procDom == null) {
+ procDom = new Xpp3Dom(PROC);
+ configuration.addChild(procDom);
+ }
+ procDom.setValue("only");
+ }
+}
View
57 ...tools.maven.apt.core/src/org/jboss/tools/maven/apt/internal/compiler/MavenCompilerExecutionDelegate.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Red Hat, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Red Hat, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.jboss.tools.maven.apt.internal.compiler;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+
+import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
+import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
+import org.apache.maven.artifact.versioning.VersionRange;
+import org.apache.maven.plugin.MojoExecution;
+
+import org.eclipse.m2e.core.project.configurator.AbstractBuildParticipant;
+
+/**
+ * MavenCompilerExecutionDelegate
+ *
+ * @author Fred Bricon
+ */
+public class MavenCompilerExecutionDelegate extends MavenCompilerJdtAptDelegate {
+
+ private static final VersionRange VALID_COMPILER_PLUGIN_RANGE;
+
+ static {
+ try {
+ VALID_COMPILER_PLUGIN_RANGE = VersionRange.createFromVersionSpec("[2.2,)");
+ } catch(InvalidVersionSpecificationException ex) {
+ throw new RuntimeException("Unable to create maven-compiler-plugin version range from [2.2,)", ex);
+ }
+ }
+
+ public void configureProject(IProgressMonitor monitor) throws CoreException {
+ //Disable JDT Apt
+ //ProjectUtils.disableApt(mavenFacade.getProject());
+ super.configureProject(monitor);//FIXME Fallback on JDt APT for now
+ }
+
+ /* (non-Javadoc)
+ * @see org.jboss.tools.maven.apt.internal.AbstractAptConfiguratorDelegate#getMojoExecutionBuildParticipant(org.apache.maven.plugin.MojoExecution)
+ */
+ public AbstractBuildParticipant getMojoExecutionBuildParticipant(MojoExecution execution) {
+ //<proc></proc> is not available for maven-compiler-plugin < 2.2
+ if(VALID_COMPILER_PLUGIN_RANGE.containsVersion(new DefaultArtifactVersion(execution.getVersion()))) {
+ // Disabled for now return new MavenCompilerBuildParticipant(execution);
+ }
+ return null;
+ }
+
+}
View
107 ...ss.tools.maven.apt.core/src/org/jboss/tools/maven/apt/internal/compiler/MavenCompilerJdtAptDelegate.java
@@ -0,0 +1,107 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Red Hat, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Red Hat, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.jboss.tools.maven.apt.internal.compiler;
+
+import static org.jboss.tools.maven.apt.internal.utils.ProjectUtils.parseProcessorOptions;
+
+import java.io.File;
+import java.util.List;
+import java.util.Map;
+
+import org.jboss.tools.maven.apt.internal.AbstractAptConfiguratorDelegate;
+import org.jboss.tools.maven.apt.internal.AnnotationProcessorConfiguration;
+import org.jboss.tools.maven.apt.internal.DefaultAnnotationProcessorConfiguration;
+import org.jboss.tools.maven.apt.internal.processor.MavenProcessorJdtAptDelegate;
+import org.jboss.tools.maven.apt.internal.utils.PluginDependencyResolver;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+
+import org.apache.maven.plugin.MojoExecution;
+
+/**
+ * MavenCompilerExecutionDelegate
+ *
+ * @author Fred Bricon
+ */
+public class MavenCompilerJdtAptDelegate extends AbstractAptConfiguratorDelegate {
+
+ /**
+ * The <code>groupId</code> of the <a href="http://maven.apache.org/plugins/maven-compiler-plugin/">Maven Compiler
+ * Plugin</a>.
+ */
+ private static final String COMPILER_PLUGIN_GROUP_ID = "org.apache.maven.plugins";
+
+ /**
+ * The <code>artifactId</code> of the <a href="http://maven.apache.org/plugins/maven-compiler-plugin/">Maven Compiler
+ * Plugin</a>.
+ */
+ private static final String COMPILER_PLUGIN_ARTIFACT_ID = "maven-compiler-plugin";
+
+ /**
+ * The name of the <a href="http://maven.apache.org/plugins/maven-compiler-plugin/">Maven Compiler Plugin</a>'s
+ * "compile" goal.
+ */
+ private static final String GOAL_COMPILE = "compile";
+
+
+ static final String OUTPUT_DIRECTORY_PARAMETER = "generatedSourcesDirectory";
+
+ /**
+ * Ignore this configurator if maven-processor-plugin is also active.
+ */
+ public boolean isIgnored(IProgressMonitor monitor) {
+ try {
+ return !mavenFacade.getMojoExecutions(MavenProcessorJdtAptDelegate.PROCESSOR_PLUGIN_GROUP_ID,
+ MavenProcessorJdtAptDelegate.PROCESSOR_PLUGIN_ARTIFACT_ID,
+ monitor,
+ MavenProcessorJdtAptDelegate.GOAL_PROCESS)
+ .isEmpty();
+ } catch(CoreException ex) {
+ //Ohoh!
+ ex.printStackTrace();
+ }
+ return true;
+ }
+
+ @Override
+ protected AnnotationProcessorConfiguration getAnnotationProcessorConfiguration(IProgressMonitor monitor) throws CoreException {
+
+ for(MojoExecution mojoExecution : mavenFacade.getMojoExecutions(COMPILER_PLUGIN_GROUP_ID,
+ COMPILER_PLUGIN_ARTIFACT_ID, monitor, GOAL_COMPILE)) {
+ File generatedOutputDirectory = maven.getMojoParameterValue(mavenSession, mojoExecution, OUTPUT_DIRECTORY_PARAMETER, File.class);
+ String compilerArgument = maven.getMojoParameterValue(mavenSession, mojoExecution, "compilerArgument", String.class);
+ Map<String, String> options = parseProcessorOptions(compilerArgument);
+
+ boolean isAnnotationProcessingEnabled = compilerArgument == null || !compilerArgument.contains("-proc:none");
+ if (isAnnotationProcessingEnabled ) {
+ String proc = maven.getMojoParameterValue(mavenSession, mojoExecution, "proc", String.class);
+ isAnnotationProcessingEnabled = !"none".equals(proc);
+ }
+
+ PluginDependencyResolver dependencyResolver = new PluginDependencyResolver();
+ List<File> dependencies = dependencyResolver.getResolvedPluginDependencies(mavenSession,
+ mavenFacade.getMavenProject(),
+ mojoExecution.getPlugin(),
+ monitor);
+
+ DefaultAnnotationProcessorConfiguration configuration = new DefaultAnnotationProcessorConfiguration();
+ configuration.setOutputDirectory(generatedOutputDirectory);
+ configuration.setAnnotationProcessingEnabled(isAnnotationProcessingEnabled);
+ configuration.setDependencies(dependencies);
+ configuration.setAnnotationProcessorOptions(options);
+ return configuration;
+ }
+
+ return null;
+ }
+
+}
View
36 ...aven.apt.core/src/org/jboss/tools/maven/apt/internal/processor/MavenProcessorAptProjectConfigurator.java
@@ -0,0 +1,36 @@
+/*************************************************************************************
+ * Copyright (c) 2008-2012 Red Hat, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Red Hat, Inc. - Initial implementation.
+ ************************************************************************************/
+package org.jboss.tools.maven.apt.internal.processor;
+
+import org.jboss.tools.maven.apt.internal.AbstractAptProjectConfigurator;
+import org.jboss.tools.maven.apt.internal.AptConfiguratorDelegate;
+import org.jboss.tools.maven.apt.internal.NoOpDelegate;
+import org.jboss.tools.maven.apt.preferences.AnnotationProcessingMode;
+
+import org.eclipse.core.runtime.Assert;
+
+public class MavenProcessorAptProjectConfigurator extends AbstractAptProjectConfigurator {
+
+ protected AptConfiguratorDelegate getDelegate(AnnotationProcessingMode mode) {
+ Assert.isNotNull(mode, "AnnotationProcessingMode can not be null");
+ switch(mode) {
+ case jdt_apt:
+ return new MavenProcessorJdtAptDelegate();
+ case maven_execution:
+ return new MavenProcessorExecutionDelegate();
+ case disabled:
+ default:
+ }
+ return new NoOpDelegate();
+ }
+
+
+}
View
90 ...ools.maven.apt.core/src/org/jboss/tools/maven/apt/internal/processor/MavenProcessorBuildParticipant.java
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Excylis and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Excylis - initial API and implementation
+ * Red Hat, Inc.
+ *******************************************************************************/
+package org.jboss.tools.maven.apt.internal.processor;
+
+import java.io.File;
+import java.util.Collections;
+import java.util.Set;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IProgressMonitor;
+
+import org.codehaus.plexus.util.Scanner;
+
+import org.apache.maven.plugin.MojoExecution;
+
+import org.sonatype.plexus.build.incremental.BuildContext;
+
+import org.eclipse.m2e.core.MavenPlugin;
+import org.eclipse.m2e.core.embedder.IMaven;
+import org.eclipse.m2e.core.project.configurator.MojoExecutionBuildParticipant;
+
+/**
+ * Executes maven-processor-plugin:process or process-test during incremental builds.
+ *
+ * @author Stéphane Landelle
+ * @author Fred Bricon
+ */
+public class MavenProcessorBuildParticipant extends MojoExecutionBuildParticipant {
+
+ public MavenProcessorBuildParticipant(MojoExecution execution) {
+ super(execution, true);
+ }
+
+ @Override
+ public Set<IProject> build(int kind, IProgressMonitor monitor) throws Exception {
+ IMaven maven = MavenPlugin.getMaven();
+ BuildContext buildContext = getBuildContext();
+
+ monitor.setTaskName("Executing " + getMojoExecution().getArtifactId()+ ":" +getMojoExecution().getGoal());
+
+ //Modifying the pom triggers a build, otherwise, check for java source modifications
+ if (!buildContext.hasDelta(getMavenProjectFacade().getPomFile())) {
+
+ // check if any of the java files changed
+ File source = maven.getMojoParameterValue(getSession(), getMojoExecution(), MavenProcessorExecutionDelegate.SOURCE_DIRECTORY_PARAMETER, File.class);
+ Scanner ds = buildContext.newScanner(source); // delta or full scanner
+ ds.scan();
+ String[] includedFiles = ds.getIncludedFiles();
+ if (includedFiles == null || includedFiles.length <= 0) {
+ return null;
+ }
+
+ if (getBuildContext().isIncremental()) {
+ boolean interestingFileChanged = false;
+ for (String f : includedFiles) {
+ if (f.endsWith(".java")) {
+ interestingFileChanged = true;
+ break;
+ }
+ }
+
+ if (!interestingFileChanged) {
+ return Collections.emptySet();
+ }
+ }
+ }
+ // execute mojo
+ Set<IProject> result = super.build(kind, monitor);
+
+ // tell m2e builder to refresh generated files
+ File generated = maven.getMojoParameterValue(getSession(), getMojoExecution(), MavenProcessorExecutionDelegate.OUTPUT_DIRECTORY_PARAMETER, File.class);
+ if (generated == null) {
+ generated = maven.getMojoParameterValue(getSession(), getMojoExecution(), MavenProcessorExecutionDelegate.DEFAULT_OUTPUT_DIRECTORY_PARAMETER, File.class);
+ }
+ if (generated != null) {
+ buildContext.refresh(generated);
+ }
+
+ return result;
+ }
+}
View
108 ...ols.maven.apt.core/src/org/jboss/tools/maven/apt/internal/processor/MavenProcessorExecutionDelegate.java
@@ -0,0 +1,108 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Red Hat, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Red Hat, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.jboss.tools.maven.apt.internal.processor;
+
+import static org.jboss.tools.maven.apt.internal.utils.ProjectUtils.containsAptProcessors;
+import static org.jboss.tools.maven.apt.internal.utils.ProjectUtils.filterToResolvedJars;
+import static org.jboss.tools.maven.apt.internal.utils.ProjectUtils.getProjectArtifacts;
+
+import java.io.File;
+import java.util.LinkedHashSet;
+import java.util.List;
+
+import org.jboss.tools.maven.apt.internal.AnnotationProcessorConfiguration;
+import org.jboss.tools.maven.apt.internal.DefaultAnnotationProcessorConfiguration;
+import org.jboss.tools.maven.apt.internal.utils.ProjectUtils;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.core.JavaCore;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.plugin.MojoExecution;
+
+import org.eclipse.m2e.core.project.configurator.AbstractBuildParticipant;
+import org.eclipse.m2e.core.project.configurator.AbstractProjectConfigurator;
+
+/**
+ * MavenProcessorExecutionDelegate
+ *
+ * @author Fred Bricon
+ */
+public class MavenProcessorExecutionDelegate extends MavenProcessorJdtAptDelegate {
+
+ private static final String GOAL_PROCESS_TEST = "process-test";
+
+ protected AnnotationProcessorConfiguration getAnnotationProcessorConfiguration(IProgressMonitor monitor)
+ throws CoreException {
+ AnnotationProcessorConfiguration configuration = super.getAnnotationProcessorConfiguration(monitor);
+ if (configuration instanceof DefaultAnnotationProcessorConfiguration) {
+ MojoExecution testMojoExecution = getProcessorPluginMojoExecution(mavenFacade, GOAL_PROCESS_TEST, monitor);
+ if (testMojoExecution != null) {
+ File generatedTestOutputDirectory = getParameterValue(OUTPUT_DIRECTORY_PARAMETER, File.class, mavenSession, testMojoExecution);
+ ((DefaultAnnotationProcessorConfiguration)configuration).setTestOutputDirectory(generatedTestOutputDirectory);
+ }
+ }
+ return configuration;
+ }
+
+ public void configureProject(IProgressMonitor monitor) throws CoreException {
+ //Disable JDT Apt
+ IProject eclipseProject = mavenFacade.getProject();
+
+ ProjectUtils.disableApt(eclipseProject);
+
+ // In case the Javaconfigurator was not called yet (eg. maven-processor-plugin being bound to process-sources,
+ // that project configurator runs first) We need to add the Java Nature before setting the APT config.
+ if(!eclipseProject .hasNature(JavaCore.NATURE_ID)) {
+ AbstractProjectConfigurator.addNature(eclipseProject, JavaCore.NATURE_ID, monitor);
+ }
+
+ AnnotationProcessorConfiguration configuration = getAnnotationProcessorConfiguration(monitor);
+
+ File generatedSourcesDirectory = configuration.getOutputDirectory();
+
+ // If this project has no valid generatedSourcesDirectory, we have nothing to do
+ if(generatedSourcesDirectory == null)
+ return;
+
+ //The plugin dependencies are added first to the classpath
+ LinkedHashSet<File> resolvedJarArtifacts = new LinkedHashSet<File>(configuration.getDependencies());
+ // Get the project's dependencies
+ List<Artifact> artifacts = getProjectArtifacts(mavenFacade);
+ resolvedJarArtifacts.addAll(filterToResolvedJars(artifacts));
+
+ // Inspect the dependencies to see if any contain APT processors
+ boolean isAnnotationProcessingEnabled = configuration.isAnnotationProcessingEnabled()
+ && containsAptProcessors(resolvedJarArtifacts);
+
+ if (isAnnotationProcessingEnabled) {
+ //Make sure the output folder exists so it can be added to the classpath
+ if (!generatedSourcesDirectory.exists()) {
+ generatedSourcesDirectory.mkdirs();
+ }
+
+ File generatedTestSourcesDirectory = configuration.getTestOutputDirectory();
+ System.err.println(generatedTestSourcesDirectory != null && !generatedTestSourcesDirectory.exists());
+ if (generatedTestSourcesDirectory != null && !generatedTestSourcesDirectory.exists()) {
+ generatedTestSourcesDirectory.mkdirs();
+ }
+ }
+
+ }
+
+ @Override
+ public AbstractBuildParticipant getMojoExecutionBuildParticipant(MojoExecution execution) {
+ return new MavenProcessorBuildParticipant(execution);
+ }
+
+}
View
95 ....tools.maven.apt.core/src/org/jboss/tools/maven/apt/internal/processor/MavenProcessorJdtAptDelegate.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Red Hat, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Red Hat, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.jboss.tools.maven.apt.internal.processor;
+
+import java.io.File;
+import java.util.List;
+import java.util.Map;
+
+import org.jboss.tools.maven.apt.internal.AbstractAptConfiguratorDelegate;
+import org.jboss.tools.maven.apt.internal.AnnotationProcessorConfiguration;
+import org.jboss.tools.maven.apt.internal.DefaultAnnotationProcessorConfiguration;
+import org.jboss.tools.maven.apt.internal.utils.PluginDependencyResolver;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.plugin.MojoExecution;
+
+import org.eclipse.m2e.core.project.IMavenProjectFacade;
+
+/**
+ * MavenProcessorJdtAptDelegate
+ *
+ * @author Fred Bricon
+ */
+public class MavenProcessorJdtAptDelegate extends AbstractAptConfiguratorDelegate {
+
+ public static final String PROCESSOR_PLUGIN_GROUP_ID = "org.bsc.maven";
+
+ public static final String PROCESSOR_PLUGIN_ARTIFACT_ID = "maven-processor-plugin";
+
+ public static final String GOAL_PROCESS = "process";
+
+ static final String SOURCE_DIRECTORY_PARAMETER = "sourceDirectory";
+
+ static final String OUTPUT_DIRECTORY_PARAMETER = "outputDirectory";
+
+ static final String DEFAULT_OUTPUT_DIRECTORY_PARAMETER = "defaultOutputDirectory";
+
+ protected AnnotationProcessorConfiguration getAnnotationProcessorConfiguration(IProgressMonitor monitor)
+ throws CoreException {
+
+ MojoExecution mojoExecution = getProcessorPluginMojoExecution(mavenFacade, GOAL_PROCESS, monitor);
+ if (mojoExecution == null) {
+ return null;
+ }
+ File generatedOutputDirectory = getParameterValue(OUTPUT_DIRECTORY_PARAMETER, File.class, mavenSession, mojoExecution);
+
+ PluginDependencyResolver dependencyResolver = new PluginDependencyResolver();
+ List<File> dependencies = dependencyResolver.getResolvedPluginDependencies(mavenSession,
+ mavenFacade.getMavenProject(),
+ mojoExecution.getPlugin(),
+ monitor);
+
+ Map<String, String> options = getParameterValue("optionMap", Map.class, mavenSession, mojoExecution);
+
+ DefaultAnnotationProcessorConfiguration configuration = new DefaultAnnotationProcessorConfiguration();
+ configuration.setOutputDirectory(generatedOutputDirectory);
+ configuration.setAnnotationProcessingEnabled(true);
+ configuration.setDependencies(dependencies);
+ configuration.setAnnotationProcessorOptions(options);
+
+ return configuration;
+ }
+
+ protected MojoExecution getProcessorPluginMojoExecution(IMavenProjectFacade mavenProjectFacade, String goal, IProgressMonitor monitor) throws CoreException {
+ for(MojoExecution mojoExecution : mavenProjectFacade.getMojoExecutions(PROCESSOR_PLUGIN_GROUP_ID,
+ PROCESSOR_PLUGIN_ARTIFACT_ID,
+ monitor,
+ goal)) {
+ return mojoExecution;
+ }
+ return null;
+ }
+
+
+ @Override
+ protected <T> T getParameterValue(String parameter, Class<T> asType, MavenSession session, MojoExecution mojoExecution) throws CoreException {
+ T result = super.getParameterValue(parameter, asType, session, mojoExecution);
+ if (OUTPUT_DIRECTORY_PARAMETER.equals(parameter) && result == null) {
+ return super.getParameterValue(DEFAULT_OUTPUT_DIRECTORY_PARAMETER, asType, session, mojoExecution);
+ }
+ return result;
+ }
+
+}
View
2  .../maven/apt/internal/AnnotationServiceLocator.java → .../apt/internal/utils/AnnotationServiceLocator.java
@@ -9,7 +9,7 @@
* Karl M. Davis (Knowledge Computing Corp.) - initial API and implementation
*******************************************************************************/
-package org.jboss.tools.maven.apt.internal;
+package org.jboss.tools.maven.apt.internal.utils;
import java.io.BufferedReader;
import java.io.File;
View
2  .../maven/apt/internal/PluginDependencyResolver.java → .../apt/internal/utils/PluginDependencyResolver.java
@@ -8,7 +8,7 @@
* Contributors:
* Red Hat, Inc. - Initial implementation.
************************************************************************************/
-package org.jboss.tools.maven.apt.internal;
+package org.jboss.tools.maven.apt.internal.utils;
import java.io.File;
import java.util.ArrayList;
View
210 org.jboss.tools.maven.apt.core/src/org/jboss/tools/maven/apt/internal/utils/ProjectUtils.java
@@ -0,0 +1,210 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Red Hat, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Red Hat, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.jboss.tools.maven.apt.internal.utils;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.jboss.tools.maven.apt.MavenJdtAptPlugin;
+import org.jboss.tools.maven.apt.internal.utils.AnnotationServiceLocator.ServiceEntry;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.jdt.apt.core.util.AptConfig;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaCore;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter;
+
+import org.eclipse.m2e.core.project.IMavenProjectFacade;
+
+/**
+ * ProjectUtils
+ *
+ * @author Fred Bricon
+ */
+public class ProjectUtils {
+
+ /**
+ * Parse a string to extract Annotation Processor options
+ */
+ public static Map<String, String> parseProcessorOptions(String compilerArgument) {
+ if (compilerArgument == null) {
+ return Collections.emptyMap();
+ }
+ Map<String, String> ret = new HashMap<String, String>();
+
+ Pattern fullOptionPattern = Pattern.compile("-A([^ \\t\"']+)");
+ Matcher matcher = fullOptionPattern.matcher(compilerArgument);
+
+ int start = 0;
+ while(matcher.find(start)) {
+ String argument = matcher.group(1);
+
+ final String key;
+ final String value;
+
+ int optionalEqualsIndex = argument.indexOf('=');
+ if (optionalEqualsIndex != -1) {
+ key = argument.substring(0, optionalEqualsIndex);
+ value = argument.substring(optionalEqualsIndex + 1, argument.length());
+ } else {
+ key = argument;
+ value = "";
+ }
+
+ ret.put(key, value);
+
+ start = matcher.end();
+ }
+
+ return ret;
+ }
+
+
+ /**
+ * Converts the specified relative or absolute {@link File} to a {@link File} that is relative to the base directory
+ * of the specified {@link IProject}.
+ *
+ * @param project the {@link IProject} whose base directory the returned {@link File} should be relative to
+ * @param fileToConvert the relative or absolute {@link File} to convert
+ * @return a {@link File} that is relative to the base directory of the specified {@link IProject}
+ */
+ public static File convertToProjectRelativePath(IProject project, File fileToConvert) {
+ // Get an absolute version of the specified file
+ File absoluteFile = fileToConvert.getAbsoluteFile();
+ String absoluteFilePath = absoluteFile.getAbsolutePath();
+
+ // Get a File for the absolute path to the project's directory
+ File projectBasedirFile = project.getLocation().toFile().getAbsoluteFile();
+ String projectBasedirFilePath = projectBasedirFile.getAbsolutePath();
+
+ // Compute the relative path
+ if(absoluteFile.equals(projectBasedirFile)) {
+ return new File(".");
+ } else if(absoluteFilePath.startsWith(projectBasedirFilePath)) {
+ String projectRelativePath = absoluteFilePath.substring(projectBasedirFilePath.length() + 1);
+ return new File(projectRelativePath);
+ } else {
+ return absoluteFile;
+ }
+ }
+
+ /**
+ * @param mavenProjectFacade the {@link IMavenProjectFacade} to get the {@link Artifact}s for
+ * @return an ordered {@link List} of the specified {@link IMavenProjectFacade}'s {@link Artifact}s
+ */
+ public static List<Artifact> getProjectArtifacts(IMavenProjectFacade mavenProjectFacade) {
+ /*
+ * This method essentially wraps org.apache.maven.project.MavenProject.getArtifacts(),
+ * returning a List instead of a Set to indicate that ordering is maintained and important.
+ * The set being "wrapped" is actually a LinkedHashSet, which does guarantee a consistent
+ * insertion & iteration order.
+ */
+
+ Set<Artifact> unorderedArtifacts = mavenProjectFacade.getMavenProject().getArtifacts();
+ List<Artifact> orderedArtifacts = new ArrayList<Artifact>(unorderedArtifacts.size());
+ for(Artifact artifact : unorderedArtifacts) {
+ orderedArtifacts.add(artifact);
+ }
+ return orderedArtifacts;
+ }
+
+
+ /**
+ * <p>
+ * Filters the specified {@link Artifact}s to those that match the following criteria:
+ * </p>
+ * <ul>
+ * <li>{@link Artifact#isResolved()} is <code>true</code></li>
+ * <li>{@link Artifact#getArtifactHandler().getExtension()} equals "jar"</li>
+ * <li>{@link Artifact#getScope()} equals {@link Artifact#SCOPE_COMPILE}</li>
+ * <li>{@link Artifact#getFile()} returns a {@link File} where {@link File#isFile()} is <code>true</code></li>
+ * </ul>
+ *
+ * @param artifacts the {@link Set} of {@link Artifact}s to filter
+ * @return the actual JAR {@link File}s available from the specified {@link Artifact}s
+ */
+ public static List<File> filterToResolvedJars(List<Artifact> artifacts) {
+ List<File> resolvedJarArtifacts = new ArrayList<File>();
+ ScopeArtifactFilter filter = new ScopeArtifactFilter(Artifact.SCOPE_COMPILE_PLUS_RUNTIME);
+
+ for(Artifact artifact : artifacts) {
+ // Ensure that this Artifact should be included
+ if(!artifact.isResolved())
+ continue;
+ if(artifact.getArtifactHandler() == null
+ || !"jar".equalsIgnoreCase(artifact.getArtifactHandler().getExtension()))
+ continue;
+ if(!filter.include(artifact))
+ continue;
+
+ // Ensure that the Artifact resolves to a File that we can use
+ File artifactJarFile = artifact.getFile();
+ if(!artifactJarFile.isFile())
+ continue;
+
+ resolvedJarArtifacts.add(artifactJarFile);
+ }
+
+ return resolvedJarArtifacts;
+ }
+
+ /**
+ * Returns <code>true</code> if any of the specified JARs contain a Java 5 or Java 6 annotation processor,
+ * <code>false</code> if none of them do.
+ *
+ * @param resolvedJarArtifacts the JAR {@link File}s to inspect for annotation processors
+ * @return <code>true</code> if any of the specified JARs contain a Java 5 or Java 6 annotation processor,
+ * <code>false</code> if none of them do
+ */
+ public static boolean containsAptProcessors(Collection<File> resolvedJarArtifacts) {
+ // Read through all JARs, checking for any APT service entries
+ try {
+ for(File resolvedJarArtifact : resolvedJarArtifacts) {
+ Set<ServiceEntry> aptServiceEntries = AnnotationServiceLocator.getAptServiceEntries(resolvedJarArtifact);
+ if(!aptServiceEntries.isEmpty())
+ return true;
+ }
+ } catch(IOException e) {
+ MavenJdtAptPlugin.createErrorStatus(e, "Error while reading artifact JARs.");
+ }
+
+ // No service entries were found
+ return false;
+ }
+
+
+ /**
+ * Disable JDT APT on this project
+ */
+ public static void disableApt(IProject project) {
+ if (project == null) {
+ return;
+ }
+
+ IJavaProject javaProject = JavaCore.create(project);
+ if (javaProject != null && AptConfig.isEnabled(javaProject)) {
+ AptConfig.setEnabled(javaProject , false);
+ }
+ }
+
+
+}
View
2  org.jboss.tools.maven.apt.core/src/org/jboss/tools/maven/apt/preferences/AnnotationProcessingMode.java
@@ -11,7 +11,7 @@
package org.jboss.tools.maven.apt.preferences;
public enum AnnotationProcessingMode {
- disabled, jdt_apt;
+ disabled, jdt_apt, maven_execution;
public static AnnotationProcessingMode getFromString(String val) {
for (AnnotationProcessingMode mode : values() ) {
View
7 org.jboss.tools.maven.apt.tests/projects/p3/pom.xml
@@ -27,6 +27,13 @@
</goals>
<phase>generate-sources</phase>
</execution>
+ <execution>
+ <id>process-test</id>
+ <goals>
+ <goal>process-test</goal>
+ </goals>
+ <phase>generate-test-sources</phase>
+ </execution>
</executions>
<configuration>
View
27 org.jboss.tools.maven.apt.tests/src/org/jboss/tools/maven/apt/tests/M2eAptProjectconfiguratorTest.java
@@ -155,6 +155,31 @@ public void testDisableAnnotationProcessingFromProject() throws Exception {
}
+
+ public void testPluginExecutionDelegation() throws Exception {
+ IPreferencesManager preferencesManager = MavenJdtAptPlugin.getDefault().getPreferencesManager();
+ try {
+ preferencesManager.setAnnotationProcessorMode(null, AnnotationProcessingMode.maven_execution);
+ IProject p = importProject("projects/p3/pom.xml");
+ waitForJobsToComplete();
+
+ p.build(IncrementalProjectBuilder.INCREMENTAL_BUILD, monitor);
+ waitForJobsToComplete();
+
+ IJavaProject javaProject = JavaCore.create(p);
+ assertFalse("JDT APT support was enabled", AptConfig.isEnabled(javaProject));
+
+ IFolder annotationsFolder = p.getFolder("target/generated-sources/apt");
+ assertTrue(annotationsFolder + " was not generated", annotationsFolder.exists());
+
+ IFolder testAnnotationsFolder = p.getFolder("target/generated-sources/apt-test");
+ assertTrue(testAnnotationsFolder + " was not generated", testAnnotationsFolder.exists());
+
+ } finally {
+ preferencesManager.setAnnotationProcessorMode(null, AnnotationProcessingMode.jdt_apt);
+ }
+ }
+
private void testDisabledAnnotationProcessing(String projectName) throws Exception {
IProject p = importProject("projects/"+projectName+"/pom.xml");
@@ -169,7 +194,7 @@ private void testAnnotationProcessorArguments(String projectName, Map<String, St
waitForJobsToComplete();
IJavaProject javaProject = JavaCore.create(p);
assertNotNull(javaProject);
- assertTrue(AptConfig.isEnabled(javaProject));
+ assertTrue("Annotation processing is disabled for "+projectName, AptConfig.isEnabled(javaProject));
Map<String, String> options = AptConfig.getProcessorOptions(javaProject);
for (Map.Entry<String, String> option : expectedOptions.entrySet()) {
assertEquals(option.getValue(), options.get(option.getKey()));
View
12 ...ss.tools.maven.apt.ui/src/org/jboss/tools/maven/apt/ui/preferences/AnnotationProcessingSettingsPage.java
@@ -34,9 +34,10 @@
private Button disableAptButton;
private Button useJdtAptButton;
+ private Button mavenExecutionButton;
private IPreferencesManager preferencesManager;
- AnnotationProcessingMode annotationProcessingMode;
+ AnnotationProcessingMode annotationProcessingMode;
public AnnotationProcessingSettingsPage() {
setPreferenceStore(MavenJdtAptUIPlugin.getDefault().getPreferenceStore());
@@ -75,9 +76,13 @@ private void createModeGroup(Composite composite) {
PreferenceMessages.AnnotationProcessingSettingsPage_Jdt_Apt_Mode_Label,
AnnotationProcessingMode.jdt_apt);
+ mavenExecutionButton = createRadioButton(modeGroup,
+ PreferenceMessages.AnnotationProcessingSettingsPage_Maven_Execution_Mode,
+ AnnotationProcessingMode.maven_execution);
+
disableAptButton = createRadioButton(modeGroup,
- PreferenceMessages.AnnotationProcessingSettingsPage_Disabled_Mode_Label,
- AnnotationProcessingMode.disabled);
+ PreferenceMessages.AnnotationProcessingSettingsPage_Disabled_Mode_Label,
+ AnnotationProcessingMode.disabled);
resetModeButtons();
}
@@ -135,5 +140,6 @@ protected void enableProjectSpecificSettings(boolean useProjectSpecificSettings)
private void resetModeButtons() {
useJdtAptButton.setSelection(annotationProcessingMode == AnnotationProcessingMode.jdt_apt);
disableAptButton.setSelection(annotationProcessingMode == AnnotationProcessingMode.disabled);
+ mavenExecutionButton.setSelection(annotationProcessingMode == AnnotationProcessingMode.maven_execution);
}
}
View
2  org.jboss.tools.maven.apt.ui/src/org/jboss/tools/maven/apt/ui/preferences/PreferenceMessages.java
@@ -21,6 +21,8 @@
public static String AnnotationProcessingSettingsPage_Disabled_Mode_Label;
public static String AnnotationProcessingSettingsPage_Jdt_Apt_Mode_Label;
+
+ public static String AnnotationProcessingSettingsPage_Maven_Execution_Mode;
public static String AnnotationProcessingSettingsPage_Select_Annotation_Processing_Mode;
static {
// initialize resource bundle
View
1  org.jboss.tools.maven.apt.ui/src/org/jboss/tools/maven/apt/ui/preferences/preferenceMessages.properties
@@ -3,4 +3,5 @@ AnnotationProcessingSettingsPage_Use_Workspace_Settings_Label =Configure Workspa
AnnotationProcessingSettingsPage_Title =Annotation Processing
AnnotationProcessingSettingsPage_Disabled_Mode_Label=Do not automatically configure/execute Annotation Processing from pom.xml
AnnotationProcessingSettingsPage_Jdt_Apt_Mode_Label=Automatically configure JDT APT (builds faster, but outcome may differ from Maven builds)
+AnnotationProcessingSettingsPage_Maven_Execution_Mode=Experimental : Delegate Annotation Processing to maven plugins (for maven-processor-plugin only)
AnnotationProcessingSettingsPage_Select_Annotation_Processing_Mode=Select Annotation Processing Mode
Please sign in to comment.
Something went wrong with that request. Please try again.