package net.ltgt.gwt.maven;

import org.apache.maven.artifact.Artifact;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.MavenProjectHelper;
import org.codehaus.plexus.archiver.UnArchiver;

import java.io.File;

public abstract class AbstractImportSourcesMojo extends AbstractMojo {

  @Component
  protected MavenProject project;

  @Component
  private MavenProjectHelper projectHelper;

  @Component(hint = "jar")
  private UnArchiver unArchiver;

  public AbstractImportSourcesMojo() {
    super();
  }

  @Override
  public void execute() throws MojoExecutionException, MojoFailureException {
    // Add the compile source roots as resources to the build
    for (String sourceRoot : getSourceRoots()) {
      projectHelper.addResource(project, sourceRoot, null, null);
    }
  
    // Now unpack the type=java-source dependencies and add them as resources
    unArchiver.setDestDirectory(getOutputDirectory());
  
    for (Artifact artifact : project.getDependencyArtifacts()) {
      if (!includeArtifact(artifact)) {
        continue;
      }
      if (!"java-source".equals(artifact.getArtifactHandler().getPackaging())) {
        if (getLog().isDebugEnabled()) {
          getLog().debug("Skipping non-java-source dependency: " + artifact.getId());
        }
        continue;
      }
      // Check copied from maven-dependency-plugin.
      // TODO: copy directory reursively, while dealing with http://jira.codehaus.org/browse/MNG-5214
      if (artifact.getFile().isDirectory()) {
        // usual case is a future jar packaging, but there are special cases: classifier and other packaging
        throw new MojoExecutionException(artifact.getId() + " has not been packaged yet. When used on reactor artifact, "
            + "import-sources should be executed after packaging.");
      }
      if (getLog().isInfoEnabled()) {
        getLog().info("Importing " + artifact.getId());
      }
      unArchiver.setSourceFile(artifact.getFile());
      // Defer outputDirectory creation so that it's only tentatively created if there are source JARs to unpack
      ensureOutputDirectory();
      unArchiver.extract();
    }
  }

  protected abstract Iterable<String> getSourceRoots();

  protected abstract File getOutputDirectory();

  protected abstract boolean includeArtifact(Artifact artifact);

  private void ensureOutputDirectory() throws MojoExecutionException {
    if (!getOutputDirectory().exists() && !getOutputDirectory().mkdirs()) {
      throw new MojoExecutionException("Cannot create output directory: " + getOutputDirectory().getAbsolutePath());
    }
    projectHelper.addResource(project, getOutputDirectory().getPath(), null, null);
  }
}
@@ -61,24 +61,64 @@
 t.Artifact;%0A
+import org.apache.maven.model.Resource;%0A
 import org.a
@@ -981,38 +981,24 @@
 ()) %7B%0A      
-projectHelper.
 addResource(
@@ -997,25 +997,16 @@
 esource(
-project, 
 sourceRo
@@ -1007,28 +1007,16 @@
 urceRoot
-, null, null
 );%0A    %7D
@@ -2375,16 +2375,672 @@
  %7D%0A  %7D%0A%0A
+  protected void addResource(String sourceRoot) %7B%0A    // TODO: cache a processed list of Resources in a ThreadLocal as an optimization?%0A    sourceRoot = ensureTrailingSlash(sourceRoot);%0A    for (Resource resource : project.getResources()) %7B%0A      String dir = ensureTrailingSlash(resource.getDirectory());%0A      if (dir.startsWith(sourceRoot) %7C%7C sourceRoot.startsWith(dir)) %7B%0A        getLog().warn(String.format(%0A            %22Conflicting path between source folder (to be added as resource: %25s) and resource (%25s); skipping.%22,%0A            sourceRoot, dir));%0A        return;%0A      %7D%0A    %7D%0A    projectHelper.addResource(project, sourceRoot, null, null);%0A  %7D%0A%0A
   protec
@@ -3199,24 +3199,179 @@
 artifact);%0A%0A
+  private String ensureTrailingSlash(String directory) %7B%0A    if (directory.endsWith(%22/%22)) %7B%0A      return directory;%0A    %7D%0A    return directory + %22/%22;%0A  %7D%0A%0A
   private vo

Check for path conflicts between user-added resources and compile source roots