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

netflix.nebula.dependency.recommender.provider.MavenBomRecommendationProvider Maven / Gradle / Ivy

Go to download

Allows projects to leave off version numbers in dependencies section and have versions recommended by other sources

There is a newer version: 12.5.1
Show newest version
package netflix.nebula.dependency.recommender.provider;

import org.apache.maven.model.Dependency;
import org.apache.maven.model.Model;
import org.apache.maven.model.Repository;
import org.apache.maven.model.building.*;
import org.apache.maven.model.interpolation.StringSearchModelInterpolator;
import org.apache.maven.model.path.DefaultPathTranslator;
import org.apache.maven.model.path.DefaultUrlNormalizer;
import org.apache.maven.model.resolution.InvalidRepositoryException;
import org.apache.maven.model.resolution.ModelResolver;
import org.apache.maven.model.resolution.UnresolvableModelException;
import org.codehaus.plexus.interpolation.MapBasedValueSource;
import org.codehaus.plexus.interpolation.PropertiesBasedValueSource;
import org.codehaus.plexus.interpolation.ValueSource;
import org.gradle.api.Project;
import org.gradle.api.artifacts.repositories.ArtifactRepository;
import org.gradle.api.artifacts.repositories.MavenArtifactRepository;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class MavenBomRecommendationProvider extends FileBasedRecommendationProvider {
    private Map recommendations;

    public MavenBomRecommendationProvider(Project project) {
        super(project);
    }

    private class SimpleModelSource implements ModelSource {
        InputStream in;

        public SimpleModelSource(InputStream in) {
            this.in = in;
        }

        @Override
        public InputStream getInputStream() throws IOException {
            return in;
        }

        @Override
        public String getLocation() {
            return null;
        }
    }

    @Override
    public String getVersion(String org, String name) throws Exception {
        if(recommendations == null) {
            recommendations = new HashMap<>();

            DefaultModelBuildingRequest request = new DefaultModelBuildingRequest();

            request.setModelResolver(new ModelResolver() {
                @Override
                public ModelSource resolveModel(String groupId, String artifactId, String version) throws UnresolvableModelException {
                    String relativeUrl = "";
                    for(String groupIdPart : groupId.split("\\."))
                        relativeUrl += groupIdPart + "/";
                    relativeUrl += artifactId + "/" + version + "/" + artifactId + "-" + version + ".pom";
                    try {
                        // try to find the parent pom in each maven repository specified in the gradle file
                        for(ArtifactRepository repo : project.getRepositories()) {
                            if(!(repo instanceof MavenArtifactRepository))
                                continue;
                            URL url = new URL(((MavenArtifactRepository) repo).getUrl().toString() + "/" + relativeUrl);
                            try {
                                return new SimpleModelSource(url.openStream());
                            } catch (IOException e) {
                                // try the next repo
                            }
                        }
                    } catch (MalformedURLException e) {
                        throw new RuntimeException(e); // should never happen
                    }
                    return null;
                }

                @Override
                public void addRepository(Repository repository) throws InvalidRepositoryException {
                    // do nothing
                }

                @Override
                public ModelResolver newCopy() {
                    return this; // do nothing
                }
            });

            request.setModelSource(new SimpleModelSource(getInput()));

            DefaultModelBuilder modelBuilder = new DefaultModelBuilderFactory().newInstance();
            modelBuilder.setModelInterpolator(new ProjectPropertiesModelInterpolator(project));

            ModelBuildingResult result = modelBuilder.build(request);
            for (Dependency d : result.getEffectiveModel().getDependencyManagement().getDependencies()) {
                recommendations.put(d.getGroupId() + ":" + d.getArtifactId(), d.getVersion());
            }
        }
        return recommendations.get(org + ":" + name);
    }

    @SuppressWarnings("unchecked")
    @Override
    public InputStreamProvider setModule(Object dependencyNotation) {
        if(dependencyNotation == null)
            throw new IllegalArgumentException("Module may not be null");

        if(Map.class.isAssignableFrom(dependencyNotation.getClass()))
            ((Map) dependencyNotation).put("ext", "pom");
        else if(!dependencyNotation.toString().endsWith("@pom"))
            dependencyNotation = dependencyNotation.toString() + "@pom";
        return super.setModule(dependencyNotation);
    }

    private static class ProjectPropertiesModelInterpolator extends StringSearchModelInterpolator {
        private final Project project;

        ProjectPropertiesModelInterpolator(Project project) {
            this.project = project;
            setUrlNormalizer(new DefaultUrlNormalizer());
            setPathTranslator(new DefaultPathTranslator());
        }

        public List createValueSources(Model model, File projectDir, ModelBuildingRequest request, ModelProblemCollector collector) {
            List sources = new ArrayList<>();
            sources.addAll(super.createValueSources(model, projectDir, request, collector));
            sources.add(new PropertiesBasedValueSource(System.getProperties()));
            sources.add(new MapBasedValueSource(project.getProperties()));
            return sources;
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy