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

io.syndesis.extension.maven.plugin.RepackageExtensionMojo Maven / Gradle / Ivy

There is a newer version: 1.13.2
Show newest version
/*
 * Copyright (C) 2016 Red Hat, Inc.
 *
 * 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 io.syndesis.extension.maven.plugin;

import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import com.fasterxml.jackson.databind.JsonNode;
import io.syndesis.common.util.Json;
import io.syndesis.extension.converter.ExtensionConverter;
import io.syndesis.common.model.extension.Extension;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.DependencyManagement;
import org.apache.maven.model.Model;
import org.apache.maven.model.io.DefaultModelWriter;
import org.apache.maven.model.io.ModelWriter;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.apache.maven.project.MavenProject;
import org.apache.maven.shared.artifact.filter.collection.ArtifactsFilter;
import org.apache.maven.shared.utils.StringUtils;
import org.eclipse.aether.RepositorySystem;
import org.eclipse.aether.RepositorySystemSession;
import org.eclipse.aether.artifact.Artifact;
import org.eclipse.aether.artifact.DefaultArtifact;
import org.eclipse.aether.repository.RemoteRepository;
import org.eclipse.aether.resolution.ArtifactRequest;
import org.eclipse.aether.resolution.ArtifactResolutionException;
import org.eclipse.aether.resolution.ArtifactResult;
import org.jboss.shrinkwrap.resolver.api.maven.Maven;
import org.jboss.shrinkwrap.resolver.api.maven.MavenResolverSystem;
import org.jboss.shrinkwrap.resolver.api.maven.MavenWorkingSession;
import org.jboss.shrinkwrap.resolver.api.maven.ScopeType;
import org.jboss.shrinkwrap.resolver.api.maven.coordinate.MavenCoordinate;
import org.jboss.shrinkwrap.resolver.api.maven.coordinate.MavenCoordinates;
import org.jboss.shrinkwrap.resolver.api.maven.coordinate.MavenDependencies;
import org.jboss.shrinkwrap.resolver.api.maven.coordinate.MavenDependency;
import org.jboss.shrinkwrap.resolver.impl.maven.MavenWorkingSessionContainer;
import org.springframework.boot.maven.Exclude;
import org.springframework.boot.maven.ExcludeFilter;

import io.syndesis.extension.maven.plugin.layout.ModuleLayoutFactory;

/**
 * Helper Maven plugin
 *
 * @author pantinor
 */
@SuppressWarnings({"PMD.ExcessiveImports"})
@Mojo(name = "repackage-extension", defaultPhase = LifecyclePhase.PACKAGE, requiresProject = true, threadSafe = true, requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME, requiresDependencyCollection = ResolutionScope.COMPILE_PLUS_RUNTIME)
public class RepackageExtensionMojo extends SupportMojo {

    public static final String SYNDESIS_BOM = "io.syndesis.extension:extension-bom:pom:";
    public static final String NET_MINIDEV_JSON_SMART = "net.minidev:json-smart";
    public static final String NET_MINIDEV_ACCESSORS_SMART = "net.minidev:accessors-smart";
    public static final String ORG_OW2_ASM_ASM = "org.ow2.asm:asm";
    public static final String SYNDESIS_ANNOTATION_PROCESSOR = "io.syndesis.extension:extension-annotation-processor";

    @Parameter
    protected String blackListedBoms;

    @Parameter
    protected String blackListedGAVs;

    @Component
    private RepositorySystem repoSystem;

    @Parameter(readonly = true, defaultValue = "${repositorySystemSession}")
    private RepositorySystemSession repoSession;

    @Parameter(readonly = true, defaultValue = "${project.remotePluginRepositories}")
    private List remoteRepos;

    @Parameter(readonly = true, defaultValue = "${project.build.directory}/classes/META-INF/syndesis/syndesis-extension-definition.json")
    private String metadataDestination;

    protected List bomsUsed = new ArrayList<>();

    protected Extension extensionDescriptor;

    @Override
    public void execute() throws MojoExecutionException, MojoFailureException {
        loadExtensionDescriptor();
        super.execute();
    }

    @Override
    protected void writeAdditionalPrivateFields() throws NoSuchFieldException, IllegalAccessException {
        boolean filter = true;
        if (extensionDescriptor != null && Extension.Type.Libraries.equals(extensionDescriptor.getExtensionType())) {
            filter = false;
            this.includeSystemScope = true;
        }
        writeFieldViaReflection("layoutFactory", new ModuleLayoutFactory(filter));
    }

    @Override
    protected Collection getAdditionalFilters() {
        Collection dependencies = new HashSet<>();

        if(StringUtils.isNotBlank(blackListedBoms)){
            addCustomBoms(dependencies);
        } else {
            addDefaultBOMs(dependencies);
        }

        if(StringUtils.isNotBlank(blackListedGAVs)){
            addCustomGAVs(dependencies);
        } else {
            addDefaultGAVs(dependencies);
        }

        if(getLog().isDebugEnabled()){
            getLog().debug("Filtering out dependencies from the following BOMs: " + bomsUsed);
            getLog().debug("Dependencies to be filtered out:");
            dependencies.stream().sorted(Comparator.comparing(MavenCoordinate::toCanonicalForm)).forEach(mavenDependency -> getLog().debug(mavenDependency.toCanonicalForm()));
        }
        List filters = new ArrayList<>(dependencies.size());

        for(MavenCoordinate dep : dependencies){
            filters.add(newExcludeFilter(dep));
        }

        return filters;
    }

    protected void addDefaultGAVs(Collection dependencies) {
        String[] defaultGAVs = new String[]{NET_MINIDEV_JSON_SMART, NET_MINIDEV_ACCESSORS_SMART, ORG_OW2_ASM_ASM, SYNDESIS_ANNOTATION_PROCESSOR};
        for (String gav : defaultGAVs){
            dependencies.add(newMavenDependency(gav));
        }
    }

    protected MavenDependency newMavenDependency(String gav) {
        MavenCoordinate coordinate = MavenCoordinates.createCoordinate(gav.trim());
        return MavenDependencies.createDependency(coordinate, ScopeType.COMPILE, false );
    }

    protected ExcludeFilter newExcludeFilter(MavenCoordinate dep) {
        Exclude exclude = new Exclude();
        exclude.setGroupId(dep.getGroupId());
        exclude.setArtifactId(dep.getArtifactId());
        return new ExcludeFilter(exclude);
    }

    protected void addCustomBoms(Collection dependencies) {
        String[] boms = blackListedBoms.split(",");
        try {
            for (String bom : boms) {
                String trimmed = bom.trim();
                dependencies.addAll(obtainBomDependencies(trimmed));
            }
        } catch (IOException | MojoExecutionException e) {
            throw new IllegalStateException(e);
        }
        bomsUsed = Arrays.asList(boms);
    }

    private String resolveBomVersion(String bom, String containedArtifact, String property) {
        String propertyVal = project.getProperties().getProperty(property);
        if (propertyVal == null) {
            propertyVal = getVersionFromDependencyManagement(containedArtifact);
        }
        if (propertyVal == null) {
            propertyVal = "RELEASE";
        }
        return bom + propertyVal;
    }

    private String getVersionFromDependencyManagement(String artifact) {
        String[] parts = artifact.split(":");
        String groupId = parts.length > 0 ? parts[0] : "";
        String artifactId = parts.length > 1 ? parts[1] : "";
        for (Dependency dep : project.getDependencyManagement().getDependencies()) {
            if (groupId.equals(dep.getGroupId()) && artifactId.equals(dep.getArtifactId())) {
                return dep.getVersion();
            }
        }
        return null;
    }

    protected void addDefaultBOMs(Collection dependencies) {
        String[] defaultBoms = new String[]{
            resolveBomVersion(SYNDESIS_BOM, "io.syndesis:extension-api", "syndesis.version")
        };

        try {
            for(String bom : defaultBoms){
                dependencies.addAll(obtainBomDependencies(bom));
            }
            bomsUsed = Arrays.asList(defaultBoms);
        } catch (IOException | MojoExecutionException e) {
            throw new IllegalStateException(e);
        }
    }

    protected void addCustomGAVs(Collection dependencies) {
        String[] gavs = blackListedGAVs.split(",");

        for (String gav : gavs) {
            dependencies.add(newMavenDependency(gav));
        }
    }

    protected Set obtainBomDependencies(String urlLocation) throws IOException, MojoExecutionException {
        Artifact artifact = downloadAndInstallArtifact(urlLocation).getArtifact();

        File tempPom = new File(outputDirectory, ".syndesis-extension-plugin-temp-pom");
        try (BufferedWriter out = Files.newBufferedWriter(tempPom.toPath(), StandardCharsets.UTF_8)) {

            Dependency bom = new Dependency();
            bom.setGroupId(artifact.getGroupId());
            bom.setArtifactId(artifact.getArtifactId());
            bom.setVersion(artifact.getVersion());
            bom.setType(artifact.getExtension());
            bom.setScope("import");

            Model bomModel = new Model();
            bomModel.setDependencyManagement(new DependencyManagement());
            bomModel.getDependencyManagement().addDependency(bom);
            bomModel.setRepositories(project.getRepositories());
            MavenProject bomProject = new MavenProject();
            bomProject.setModel(bomModel);
            bomProject.setModelVersion(project.getModelVersion());
            bomProject.setGroupId(project.getGroupId());
            bomProject.setArtifactId(project.getArtifactId() + "-temp-bom");
            bomProject.setVersion(project.getVersion());


            ModelWriter modelWriter = new DefaultModelWriter();
            modelWriter.write(out, Collections.emptyMap(), bomProject.getModel());

            MavenResolverSystem resolver = Maven.resolver();
            resolver.loadPomFromFile(tempPom).importCompileAndRuntimeDependencies();
            MavenWorkingSession session =((MavenWorkingSessionContainer)resolver).getMavenWorkingSession();

            return session.getDependencyManagement();
        } finally {
            if (!tempPom.delete()) {
                getLog().warn("Cannot delete file " + tempPom);
            }
        }
    }

    /*
     * @param artifact The artifact coordinates in the format
     *            {@code :[:[:]]:}, must not be {@code null}.
     *
     */
    protected ArtifactResult downloadAndInstallArtifact(String artifact) throws MojoExecutionException {
        ArtifactResult result;

        ArtifactRequest request = new ArtifactRequest();
        request.setArtifact( new DefaultArtifact( artifact ) );
        request.setRepositories( remoteRepos );

        getLog().info( "Resolving artifact " + artifact + " from " + remoteRepos );
        try {
            result = repoSystem.resolveArtifact( repoSession, request );
            return result;
        } catch ( ArtifactResolutionException e ) {
            throw new MojoExecutionException( e.getMessage(), e );
        }
    }

    protected void loadExtensionDescriptor() throws MojoExecutionException {
        if (metadataDestination == null) {
            return;
        }
        File metadata = new File(metadataDestination);
        if (!metadata.exists()) {
            return;
        }

        try {
            JsonNode tree = Json.reader().readTree(Files.newBufferedReader(metadata.toPath(), StandardCharsets.UTF_8));
            this.extensionDescriptor = ExtensionConverter.getDefault().toInternalExtension(tree);
        } catch (IOException e) {
            throw new MojoExecutionException("Error while loading the extension metadata", e);
        }
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy