All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.codehaus.mojo.javascript.Configurer Maven / Gradle / Ivy

Go to download

An extension that provides lifecycle binding, dependency, plugin and resource configuration suitable to most JS projects.

The newest version!
package org.codehaus.mojo.javascript;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.maven.AbstractMavenLifecycleParticipant;
import org.apache.maven.MavenExecutionException;
import org.apache.maven.artifact.handler.ArtifactHandler;
import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.model.Build;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.Plugin;
import org.apache.maven.model.PluginExecution;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.MavenProjectHelper;
import org.codehaus.plexus.util.xml.Xpp3Dom;

/**
 * Configures plugins required by the javascript-maven-plugin plugin and adds them to the current project.
 * 
 * @author Ben Jones
 * @author Christopher Hunt
 */
public class Configurer
    extends AbstractMavenLifecycleParticipant
{
    /** Injected html resource folder. */
    private String htmlResourceDir;

    /** Injected html file patterns to exclude given that the js import plugin takes care of copying these. */
    private String htmlResourceExcludes;

    /** Injected html test resource folder. */
    private String htmlTestResourceDir;

    /** Injected html test file patterns to exclude given that the js import plugin takes care of copying these. */
    private String htmlTestResourceExcludes;

    /** Injected js resource folder. */
    private String jsResourceDir;

    /** Injected js file patterns to exclude given that the js import plugin takes care of copying these. */
    private String jsResourceExcludes;

    /** Injected js test resource folder. */
    private String jsTestResourceDir;

    /** Injected js test file patterns to exclude given that the js import plugin takes care of copying these. */
    private String jsTestResourceExcludes;

    /** Injected jetty-maven-plugin */
    private Plugin jettyPlugin;

    /** Injected jetty 'context path' configuration variable */
    private String jettyContextPath;

    /** Injected jetty 'resource bases' configuration variables */
    private List jettyResourceBases;

    /** Injected maven-compiler-plugin */
    private Plugin mavenCompilerPlugin;

    /** Injected maven-surefire-plugin */
    private Plugin mavenSurefirePlugin;

    /** Injected maven-surefire-plugin */
    private Plugin mavenAssemblyPlugin;

    /** Injected maven-site-plugin */
    private Plugin mavenSitePlugin;

    /** Injected maven site 'exclude modules' configuration variable */
    private String mavenSiteExcludeModules;

    /** Injected maven site plugin 'jstools group' configuration variable */
    private String mavenSiteJstoolsGroup;

    /** Injected maven site plugin 'jstools artifact' configuration variable */
    private String mavenSiteJstoolsArtifact;

    /** Injected maven site plugin 'jstools version' configuration variable */
    private String mavenSiteJstoolsVersion;

    /** Injected jstools 'jsDir' configuration variables */
    private String mavenSiteJstoolsReportsJsDir;

    /** Injected jstools 'reports' configuration variables */
    private List mavenSiteJstoolsReports;

    /** Injected Almond dependency for AMD builds */
    private Dependency almondDependency;

    /** Injected QUnit dependency for testing */
    private Dependency qunitDependency;

    /** Injected test runner for testing */
    private Dependency jstestrunnerJUnitDependency;

    /** Injected utility for configuring maven projects */
    private MavenProjectHelper projectHelper;

    /** Injected handler for js artifacts */
    private ArtifactHandler jsArtifactHandler;

    /** Injected manager of artifact handlers */
    private ArtifactHandlerManager artifactHandlerManager;

    @Override
    /** {@inheritDoc} */
    public void afterProjectsRead( MavenSession session )
        throws MavenExecutionException
    {
        // Ensure our artifact handler is registered.
        Map handlers = new HashMap( 1 );
        handlers.put( "js", jsArtifactHandler );
        artifactHandlerManager.addHandlers( handlers );

        // For multi-module builds, we need to iterate through all projects and only apply
        // our custom configuration to projects which are using this extension
        List projects = session.getProjects();
        for ( MavenProject project : projects )
        {
            if ( project.getExtensionArtifactMap().containsKey( "org.codehaus.mojo:javascript-maven-plugin" ) )
            {
                // Create a set of plugins for easy existance tests.
                List plugins = project.getBuildPlugins();
                Set projectSpecifiedPlugins = buildSpecifiedPlugins( project );

                // For each plugin we want to associate with the current project, check if it exists in the project's
                // the user has defined (not maven itself). If it has not been supplied by the user then remove it
                // (because Maven may have put it there) and configure it.
                if ( !projectSpecifiedPlugins.contains( jettyPlugin ) )
                {
                    plugins.remove( jettyPlugin );
                    configureJetty( project );
                }
                if ( !projectSpecifiedPlugins.contains( mavenCompilerPlugin ) )
                {
                    plugins.remove( mavenCompilerPlugin );
                    configureMavenCompiler( project );
                }
                if ( !projectSpecifiedPlugins.contains( mavenSurefirePlugin ) )
                {
                    plugins.remove( mavenSurefirePlugin );
                    configureMavenSurefire( project );
                }
                if ( !projectSpecifiedPlugins.contains( mavenSitePlugin ) )
                {
                    plugins.remove( mavenSitePlugin );
                    configureMavenSite( project );
                }

                // Add our required resources.
                addResources( project );

                // Add dependencies that js projects will need always.
                addDependencies( project );

                // Add artifact/attachments if there is no assembly plugin.
                if ( !projectSpecifiedPlugins.contains( mavenAssemblyPlugin ) )
                {
                    addArtifacts( project );
                }

            }
        }

        // Perform anything "normal".
        super.afterProjectsRead( session );
    }

    /**
     * Build a plugin list of those only relating to our project or parent projects i.e. not those introduced by Maven
     * itself.
     * 
     * @param project the project to work with.
     * @return the list of plugins excluding those defined by Maven.
     */
    protected Set buildSpecifiedPlugins( MavenProject project )
    {
        Set plugins = new HashSet( project.getBuildPlugins().size() );
        MavenProject currentProject = project;
        while ( currentProject != null )
        {
            Build build = currentProject.getOriginalModel().getBuild();
            if ( build != null )
            {
                plugins.addAll( build.getPlugins() );
            }
            currentProject = currentProject.getParent();
        }
        return plugins;
    }

    /**
     * Configure the maven-site-plugin with the configuration parameters injected into this class from components.xml
     * and add the plugin to the current project.
     */
    private void configureMavenSite( MavenProject project )
    {
        // Construct the Xpp3Dom structure for configuration
        Xpp3Dom configuration = new Xpp3Dom( "configuration" );

        Xpp3Dom excludeModules = new Xpp3Dom( "excludeModules" );
        excludeModules.setValue( mavenSiteExcludeModules );
        configuration.addChild( excludeModules );

        Xpp3Dom reportPlugins = new Xpp3Dom( "reportPlugins" );
        configuration.addChild( reportPlugins );

        Xpp3Dom plugin = new Xpp3Dom( "plugin" );
        reportPlugins.addChild( plugin );

        Xpp3Dom groupId = new Xpp3Dom( "groupId" );
        groupId.setValue( mavenSiteJstoolsGroup );
        plugin.addChild( groupId );

        Xpp3Dom artifactId = new Xpp3Dom( "artifactId" );
        artifactId.setValue( mavenSiteJstoolsArtifact );
        plugin.addChild( artifactId );

        Xpp3Dom version = new Xpp3Dom( "version" );
        version.setValue( mavenSiteJstoolsVersion );
        plugin.addChild( version );

        Xpp3Dom pluginConfiguration = new Xpp3Dom( "configuration" );
        plugin.addChild( pluginConfiguration );

        Xpp3Dom jsDir = new Xpp3Dom( "jsDir" );
        jsDir.setValue( mavenSiteJstoolsReportsJsDir );
        pluginConfiguration.addChild( jsDir );

        Xpp3Dom reportSets = new Xpp3Dom( "reportSets" );
        pluginConfiguration.addChild( reportSets );

        Xpp3Dom reportSet = new Xpp3Dom( "reportSet" );
        reportSets.addChild( reportSet );

        if ( mavenSiteJstoolsReports.size() > 0 )
        {
            Xpp3Dom reports = new Xpp3Dom( "reports" );
            for ( String reportValue : mavenSiteJstoolsReports )
            {
                Xpp3Dom report = new Xpp3Dom( "report" );
                report.setValue( reportValue );
                reports.addChild( report );
            }
            reportSet.addChild( reports );
        }

        // Set the configuration on the plugin
        mavenSitePlugin.setConfiguration( configuration );

        // Construct plugin executions
        List pluginExecutions = new ArrayList();

        PluginExecution pluginExecution = new PluginExecution();
        pluginExecution.addGoal( "site" );
        pluginExecution.setPhase( "site" );
        pluginExecution.setId( "default-site" );
        pluginExecution.setConfiguration( configuration );
        pluginExecutions.add( pluginExecution );

        mavenSitePlugin.setExecutions( pluginExecutions );

        // Add the plugin to the current project
        project.getBuildPlugins().add( mavenSitePlugin );
    }

    /**
     * Configure the maven-surefire-plugin with the configuration parameters injected into this class from
     * components.xml and add the plugin to the current project.
     */
    private void configureMavenSurefire( MavenProject project )
    {
        // Construct plugin executions
        List pluginExecutions = new ArrayList();

        PluginExecution pluginExecution = new PluginExecution();
        pluginExecution.addGoal( "test" );
        pluginExecutions.add( pluginExecution );

        mavenSurefirePlugin.setExecutions( pluginExecutions );

        // Add the plugin to the current project
        project.getBuildPlugins().add( mavenSurefirePlugin );
    }

    /**
     * Add the maven-compiler-plugin to the current project.
     */
    private void configureMavenCompiler( MavenProject project )
    {
        // Construct plugin executions
        List pluginExecutions = new ArrayList();

        PluginExecution pluginExecution = new PluginExecution();
        pluginExecution.setId( "default-testCompile" );
        pluginExecution.setPhase( "test-compile" );
        pluginExecution.addGoal( "testCompile" );
        pluginExecutions.add( pluginExecution );

        mavenCompilerPlugin.setExecutions( pluginExecutions );

        project.getBuildPlugins().add( mavenCompilerPlugin );
    }

    /**
     * Configure the jetty-maven-plugin with the configuration parameters injected into this class from components.xml
     * and add the plugin to the current project.
     */
    private void configureJetty( MavenProject project )
    {
        // Construct the Xpp3Dom structure for configuration
        Xpp3Dom configuration = new Xpp3Dom( "configuration" );
        Xpp3Dom webAppConfig = new Xpp3Dom( "webAppConfig" );
        configuration.addChild( webAppConfig );

        Xpp3Dom contextPath = new Xpp3Dom( "contextPath" );
        contextPath.setValue( jettyContextPath );
        webAppConfig.addChild( contextPath );

        if ( jettyResourceBases.size() > 0 )
        {
            Xpp3Dom resourceBases = new Xpp3Dom( "resourceBases" );
            for ( String resourceBaseValue : jettyResourceBases )
            {
                Xpp3Dom resourceBase = new Xpp3Dom( "resourceBases" );
                resourceBase.setValue( resourceBaseValue );
                resourceBases.addChild( resourceBase );
            }
            webAppConfig.addChild( resourceBases );
        }

        // Set the configuration on the plugin
        jettyPlugin.setConfiguration( configuration );
        // Add the plugin to the current project
        project.getBuildPlugins().add( jettyPlugin );
    }

    /**
     * Add the standard resource patterns for a JS project. In essence we prevent the resource plugin from considering
     * html and js files when copying as the JS Import Maven Plugin takes care of copying (and filtering) these (it has
     * to).
     * 
     * @param project the project to add resources to.
     */
    private void addResources( MavenProject project )
    {
        projectHelper.addResource( project, htmlResourceDir, null,
                                   Arrays.asList( new String[] { htmlResourceExcludes } ) );

        projectHelper.addTestResource( project, htmlTestResourceDir, null,
                                       Arrays.asList( new String[] { htmlTestResourceExcludes } ) );

        projectHelper.addResource( project, jsResourceDir, null, Arrays.asList( new String[] { jsResourceExcludes } ) );

        projectHelper.addTestResource( project, jsTestResourceDir, null,
                                       Arrays.asList( new String[] { jsTestResourceExcludes } ) );
    }

    /**
     * Add dependencies for things that support the building of JS applications.
     * 
     * @param project the project to add to.
     */
    private void addDependencies( MavenProject project )
    {
        List dependencies = project.getDependencies();

        // Build collection of dependencies to allow for efficient lookup
        Map dependencyMap = new HashMap( dependencies.size() );
        for ( Dependency dependency : dependencies )
        {
            dependencyMap.put( dependency.getGroupId() + ":" + dependency.getArtifactId(), dependency );
        }

        // Add dependencies if they aren't already defined in the project
        if ( !dependencyMap.containsKey( almondDependency.getGroupId() + ":" + almondDependency.getArtifactId() ) )
        {
            dependencies.add( almondDependency );
        }

        if ( !dependencyMap.containsKey( qunitDependency.getGroupId() + ":" + qunitDependency.getArtifactId() ) )
        {
            qunitDependency.setScope( "test" );
            dependencies.add( qunitDependency );
        }

        if ( !dependencyMap.containsKey( jstestrunnerJUnitDependency.getGroupId() + ":"
            + jstestrunnerJUnitDependency.getArtifactId() ) )
        {
            jstestrunnerJUnitDependency.setScope( "test" );
            dependencies.add( jstestrunnerJUnitDependency );
        }
    }

    /**
     * Add in default artifact and artifact attachments in target/min/classes/*.js
     * 
     * @param project the Maven project to add artifact/attachments to.
     */
    private void addArtifacts( MavenProject project )
    {
        File minTargetFolder =
            new File( project.getBasedir(), "target" + File.separator + "min" + File.separator + "classes" );

        // Note that the Java compiler plugin will override this artifact file assignment. However by default JS
        // projects do not bind the compiler goal other than for conducting tests.
        project.getArtifact().setFile( new File( minTargetFolder, "1.js" ) );

        projectHelper.attachArtifact( project, new File( minTargetFolder, "1-min.js" ), "min" );
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy