com.github.praxissoftware.maven.plugins.GenerateFeaturesMojo.java Source code

Java tutorial

Introduction

Here is the source code for com.github.praxissoftware.maven.plugins.GenerateFeaturesMojo.java

Source

/**
 * Copyright 2012 Jason Rose <jasoncrose@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.github.praxissoftware.maven.plugins;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Writer;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.maven.artifact.Artifact;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.project.MavenProject;

import com.google.common.base.Charsets;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.base.Throwables;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Ordering;
import com.google.common.collect.Sets;
import com.google.common.io.CharStreams;
import com.google.common.io.Closeables;
import com.google.common.io.InputSupplier;
import com.sampullara.mustache.Mustache;
import com.sampullara.mustache.MustacheBuilder;

/**
 * Generates a single feature with all relevant dependencies inside of it.
 * @goal generate-features-xml
 */
public class GenerateFeaturesMojo extends AbstractMojo {

    /**
     * The Maven project to analyze.
     * 
     * @parameter expression="${project}"
     * @required
     * @readonly
     */
    private MavenProject project;

    /**
     * The file to output the features.xml to.
     * 
     * @parameter expression="${project.build.outputDirectory}/feature.xml"
     */
    private File outputFile;

    @SuppressWarnings("unchecked")
    @Override
    public void execute() throws MojoExecutionException {
        Writer out = null;
        try {

            // Get the template text from the jar's resources.
            final InputSupplier<InputStreamReader> supplier = CharStreams
                    .newReaderSupplier(new InputSupplier<InputStream>() {
                        @Override
                        public InputStream getInput() throws IOException {
                            return getClass().getClassLoader().getResourceAsStream("features.mustache.xml");
                        }
                    }, Charsets.UTF_8);
            final String template = CharStreams.toString(supplier);

            // Create the mustache factory from the loaded template.
            final Mustache mustache = new MustacheBuilder().parse(template, "features.mustache.xml");

            // Establish output stream.
            final File featureFile = setUpFile(outputFile);
            out = new FileWriter(featureFile);

            // Build context.
            final Map<String, Object> context = convert(project.getArtifact());

            final List<Map<String, Object>> dependencies = Lists.newArrayList();
            for (final Artifact dependency : Ordering.natural().onResultOf(new SortByCoordinates())
                    .sortedCopy(Iterables.filter((Collection<Artifact>) project.getDependencyArtifacts(),
                            new ArtifactsWeWant()))) {
                dependencies.add(convert(dependency));
            }
            context.put("dependencies", dependencies);

            getLog().info("Writing feature to " + outputFile.getAbsolutePath());

            // Render template.
            mustache.execute(out, context);
        } catch (final Exception e) {
            Throwables.propagateIfInstanceOf(e, MojoExecutionException.class);
            Throwables.propagateIfPossible(e);
            throw new MojoExecutionException("Unable to generate features.xml.", e);
        } finally {
            Closeables.closeQuietly(out);
        }
    }

    private Map<String, Object> convert(final Artifact artifact) {
        final Map<String, Object> map = Maps.newHashMap();
        map.put("groupId", artifact.getGroupId());
        map.put("artifactId", artifact.getArtifactId());
        map.put("version", artifact.isSnapshot() ? artifact.getBaseVersion() : artifact.getVersion());
        map.put("hasClassifier", artifact.getClassifier() != null);
        map.put("classifier", artifact.getClassifier());
        map.put("hasType", artifact.getType() != null);
        map.put("type", artifact.getType());
        return map;
    }

    private File setUpFile(final File target) {
        if (target.exists()) {
            target.delete();
        } else if (!target.getParentFile().exists()) {
            target.getParentFile().mkdirs();
        }
        return target;
    }

    private class ArtifactsWeWant implements Predicate<Artifact> {
        private final Set<String> valid = Sets.newHashSet("compile", "runtime");

        @Override
        public boolean apply(final Artifact input) {
            return valid.contains(input.getScope());
        }
    }

    private class SortByCoordinates implements Function<Artifact, String> {
        @Override
        public String apply(final Artifact input) {
            return String.format("%s:%s:%s:%s", input.getGroupId(), input.getArtifactId(), input.getVersion(),
                    input.getType());
        }
    }
}