001/*
002 * Extra Bnd Repository Plugins
003 * Copyright (C) 2019  Michael N. Lipp
004 * 
005 * This program is free software; you can redistribute it and/or modify it 
006 * under the terms of the GNU Affero General Public License as published by 
007 * the Free Software Foundation; either version 3 of the License, or 
008 * (at your option) any later version.
009 * 
010 * This program is distributed in the hope that it will be useful, but 
011 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
012 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License 
013 * for more details.
014 * 
015 * You should have received a copy of the GNU Affero General Public License along 
016 * with this program; if not, see <http://www.gnu.org/licenses/>.
017 */
018
019package de.mnl.osgi.bnd.maven;
020
021import aQute.maven.api.Archive;
022import aQute.maven.api.Program;
023import aQute.maven.api.Revision;
024import aQute.maven.provider.MavenRepository;
025import aQute.service.reporter.Reporter;
026
027import java.io.File;
028
029import org.apache.maven.building.FileSource;
030import org.apache.maven.model.Dependency;
031import org.apache.maven.model.Parent;
032import org.apache.maven.model.Repository;
033import org.apache.maven.model.building.ModelSource;
034import org.apache.maven.model.resolution.InvalidRepositoryException;
035import org.apache.maven.model.resolution.ModelResolver;
036import org.apache.maven.model.resolution.UnresolvableModelException;
037
038/**
039 * Resolves (raw) model requests using a bnd {@link MavenRepository}
040 * as backend.  
041 */
042@SuppressWarnings("deprecation")
043public class BndModelResolver implements ModelResolver, Cloneable {
044
045    private final MavenRepository bndRepository;
046    private final Reporter reporter;
047
048    public BndModelResolver(MavenRepository bndRepository, Reporter reporter) {
049        this.bndRepository = bndRepository;
050        this.reporter = reporter;
051    }
052
053    @Override
054    public ModelSource resolveModel(String groupId, String artifactId,
055            String version) throws UnresolvableModelException {
056        Revision revision
057            = Program.valueOf(groupId, artifactId).version(version);
058        Archive pomArchive = revision.getPomArchive();
059        try {
060            File pomFile = bndRepository.get(pomArchive).getValue();
061            if (pomFile == null) {
062                throw new UnresolvableModelException("Not found.", groupId,
063                    artifactId, version);
064            }
065            return new FileModelSource(pomFile);
066        } catch (Exception e) {
067            throw new UnresolvableModelException(e, groupId, artifactId,
068                version);
069        }
070    }
071
072    @Override
073    public ModelSource resolveModel(Parent parent)
074            throws UnresolvableModelException {
075        Revision revision
076            = Program.valueOf(parent.getGroupId(), parent.getArtifactId())
077                .version(parent.getVersion());
078        try {
079            Archive pomArchive
080                = bndRepository.getResolvedArchive(revision, "pom", "");
081            parent.setVersion(pomArchive.getRevision().version.toString());
082            File pomFile = bndRepository.get(pomArchive).getValue();
083            if (pomFile == null) {
084                throw new UnresolvableModelException("Not found.",
085                    parent.getGroupId(), parent.getArtifactId(),
086                    parent.getVersion());
087            }
088            return new FileModelSource(pomFile);
089        } catch (Exception e) {
090            throw new UnresolvableModelException(e, parent.getGroupId(),
091                parent.getArtifactId(), parent.getVersion());
092        }
093    }
094
095    @Override
096    public ModelSource resolveModel(Dependency dependency)
097            throws UnresolvableModelException {
098        Revision revision
099            = Program.valueOf(dependency.getGroupId(),
100                dependency.getArtifactId()).version(dependency.getVersion());
101        try {
102            Archive pomArchive
103                = bndRepository.getResolvedArchive(revision, "pom", "");
104            dependency.setVersion(pomArchive.getRevision().version.toString());
105            File pomFile = bndRepository.get(pomArchive).getValue();
106            if (pomFile == null) {
107                throw new UnresolvableModelException("Not found.",
108                    dependency.getGroupId(), dependency.getArtifactId(),
109                    dependency.getVersion());
110            }
111            return new FileModelSource(pomFile);
112        } catch (Exception e) {
113            throw new UnresolvableModelException(e, dependency.getGroupId(),
114                dependency.getArtifactId(), dependency.getVersion());
115        }
116    }
117
118    @Override
119    public void addRepository(Repository repository)
120            throws InvalidRepositoryException {
121        reporter.warning("Attempt to add repository %s (not supported).",
122            repository);
123    }
124
125    @Override
126    public void addRepository(Repository repository, boolean replace)
127            throws InvalidRepositoryException {
128        reporter.warning(
129            "Attempt to add/replace repository %s (not supported).",
130            repository);
131    }
132
133    @Override
134    public ModelResolver newCopy() {
135        try {
136            return (BndModelResolver) clone();
137        } catch (CloneNotSupportedException e) {
138            // Doesn't happen
139            return null;
140        }
141    }
142
143    public static class FileModelSource extends FileSource
144            implements ModelSource {
145        public FileModelSource(File file) {
146            super(file);
147        }
148    }
149}