package com.intellij.flex.maven; import org.apache.maven.artifact.Artifact; import org.apache.maven.execution.MavenSession; import org.apache.maven.lifecycle.internal.LifecycleExecutionPlanCalculator; import org.apache.maven.model.Plugin; import org.apache.maven.plugin.*; import org.apache.maven.plugin.descriptor.MojoDescriptor; import org.apache.maven.project.MavenProject; import org.codehaus.plexus.classworlds.realm.ClassRealm; import org.codehaus.plexus.component.annotations.Component; import org.codehaus.plexus.component.annotations.Requirement; import java.io.File; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; import java.util.List; /** * @goal generate * @requiresDependencyResolution compile * @threadSafe * @phase compile * @aggregator */ @Component(role=IdeaConfigurationMojo.class) public class IdeaConfigurationMojo extends AbstractMojo { @Requirement private MavenPluginManager mavenPluginManager; /** * @parameter expression="${session}" * @required * @readonly */ @SuppressWarnings({"UnusedDeclaration"}) private MavenSession session; /** * @parameter expression="${mojoExecution}" * @required * @readonly */ @SuppressWarnings({"UnusedDeclaration"}) private MojoExecution mojoExecution; @Requirement private BuildPluginManager pluginManager; @Requirement private LifecycleExecutionPlanCalculator lifeCycleExecutionPlanCalculator; /** * @parameter expression="${generateShareable}" * @readonly */ @SuppressWarnings({"UnusedDeclaration"}) private boolean generateShareable; /** * @parameter expression="${generateNonShareable}" default-value="true" * @readonly */ @SuppressWarnings({"UnusedDeclaration"}) private boolean generateNonShareable; @Override public void execute() throws MojoExecutionException, MojoFailureException { List<String> configurators = new ArrayList<String>(2); if (generateNonShareable) { configurators.add("com.intellij.flex.maven.IdeaConfigurator"); } if (generateShareable) { configurators.add("com.intellij.flex.maven.ShareableFlexConfigGenerator"); } // for some unknown reasons (WTF?), project artifact is not equals is not the same instance as in dependentProject.getArtifacts(), // so, without this hack, we have two problems: // 1) if artifact located in local repo, but not in project dir, output file will be from local repo (but must be from project dir) // 2) if artifact located nor in local repo, nor in project dir, will be build failure due to "Unable to handle unresolved artifact" final HashMap<Artifact, MavenProject> ourProjects = new HashMap<Artifact, MavenProject>(session.getProjects().size()); final String rootProjectDirPath = session.getTopLevelProject().getBasedir().getPath(); for (MavenProject project : session.getProjects()) { final String packaging = project.getPackaging(); if (!(packaging.equals("swc") || packaging.equals("swf") || packaging.equals("air"))) { continue; } for (Artifact artifact : project.getArtifacts()) { final MavenProject reactorProject = ourProjects.get(artifact); if (reactorProject != null) { // case 2, see comment above if (!artifact.isResolved()) { artifact.setResolved(true); } // case 1, see comment above else if (artifact.getFile().getPath().startsWith(rootProjectDirPath)) { continue; } artifact.setFile(reactorProject.getArtifact().getFile()); } } ourProjects.put(project.getArtifact(), project); try { // requires for flexmojos session.setCurrentProject(project); generateForProject(project, configurators); } catch (Exception e) { throw new MojoExecutionException("Cannot generate flex config: " + e.getMessage(), e); } finally { session.setCurrentProject(session.getTopLevelProject()); } } } private void generateForProject(MavenProject project, List<String> configurators) throws Exception { MojoExecution flexmojosMojoExecution = null; MojoExecution flexmojosGeneratorMojoExecution = null; for (Plugin plugin : project.getBuildPlugins()) { if (plugin.getGroupId().equals("org.sonatype.flexmojos")) { if (flexmojosMojoExecution == null && plugin.getArtifactId().equals("flexmojos-maven-plugin")) { flexmojosMojoExecution = createMojoExecution(plugin, getCompileGoalName(project), project); } else if (flexmojosGeneratorMojoExecution == null && plugin.getArtifactId().equals("flexmojos-generator-mojo")) { flexmojosGeneratorMojoExecution = createMojoExecution(plugin, "generate", project); } if (flexmojosMojoExecution != null && flexmojosGeneratorMojoExecution != null) { break; } } } if (flexmojosMojoExecution == null) { return; } ClassRealm flexmojosPluginRealm = pluginManager.getPluginRealm(session, flexmojosMojoExecution.getMojoDescriptor().getPluginDescriptor()); final ClassLoader classLoader = getClass().getClassLoader(); flexmojosPluginRealm.addURL(new URL(session.getLocalRepository().getUrl() + "com/intellij/flex/maven/idea-configurator/1.5.4/idea-configurator-1.5.4.jar")); flexmojosPluginRealm.importFrom(classLoader, "com.intellij.flex.maven.FlexConfigGenerator"); flexmojosPluginRealm.importFrom(classLoader, "com.intellij.flex.maven.Utils"); Mojo mojo = null; try { mojo = mavenPluginManager.getConfiguredMojo(Mojo.class, session, flexmojosMojoExecution); for (String configuratorClassName : configurators) { Class configuratorClass = flexmojosPluginRealm.loadClass(configuratorClassName); FlexConfigGenerator configurator = (FlexConfigGenerator)configuratorClass.getConstructor(MavenSession.class, File.class).newInstance(session, null); configurator.preGenerate(project, Flexmojos.getClassifier(mojo)); if ("swc".equals(project.getPackaging())) { configurator.generate(mojo); } else { configurator.generate(mojo, Flexmojos.getSourceFileForSwf(mojo)); } configurator.postGenerate(project); } } finally { mavenPluginManager.releaseMojo(mojo, mojoExecution); } } private String getCompileGoalName(final MavenProject project) { return "swc".equals(project.getPackaging()) ? "compile-swc" : "compile-swf"; } private MojoExecution createMojoExecution(Plugin plugin, String goal, MavenProject project) throws Exception { MojoDescriptor mojoDescriptor = pluginManager.getMojoDescriptor(plugin, goal, project.getRemotePluginRepositories(), session.getRepositorySession()); MojoExecution mojoExecution = new MojoExecution(mojoDescriptor, "default-cli", MojoExecution.Source.CLI); lifeCycleExecutionPlanCalculator.setupMojoExecution(session, project, mojoExecution); return mojoExecution; } }