package aQute.bnd.repository.maven.pom.provider; import java.io.File; import java.io.InputStream; import java.net.URI; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.SortedSet; import org.osgi.resource.Capability; import org.osgi.resource.Requirement; import org.osgi.util.promise.Promise; import aQute.bnd.annotation.plugin.BndPlugin; import aQute.bnd.build.Workspace; import aQute.bnd.http.HttpClient; import aQute.bnd.osgi.Processor; import aQute.bnd.osgi.repository.BaseRepository; import aQute.bnd.osgi.repository.BridgeRepository; import aQute.bnd.osgi.repository.BridgeRepository.ResourceInfo; import aQute.bnd.service.Actionable; import aQute.bnd.service.Plugin; import aQute.bnd.service.Refreshable; import aQute.bnd.service.Registry; import aQute.bnd.service.RegistryPlugin; import aQute.bnd.service.RepositoryPlugin; import aQute.bnd.util.repository.DownloadListenerPromise; import aQute.bnd.version.Version; import aQute.lib.converter.Converter; import aQute.lib.exceptions.Exceptions; import aQute.lib.io.IO; import aQute.lib.strings.Strings; import aQute.libg.reporter.slf4j.Slf4jReporter; import aQute.maven.api.Archive; import aQute.maven.api.Revision; import aQute.maven.provider.MavenBackingRepository; import aQute.maven.provider.MavenRepository; import aQute.service.reporter.Reporter; /** * This is the Bnd repository for Maven. */ @BndPlugin(name = "PomRepository") public class BndPomRepository extends BaseRepository implements Plugin, RegistryPlugin, RepositoryPlugin, Refreshable, Actionable { static final String MAVEN_REPO_LOCAL = System.getProperty("maven.repo.local", "~/.m2/repository"); boolean inited; private PomConfiguration configuration; private Registry registry; private String name; private Reporter reporter = new Slf4jReporter(BndPomRepository.class); private InnerRepository repoImpl; private List<Revision> revisions; private BridgeRepository bridge; private List<URI> pomFiles; private String query; private String queryUrl; public synchronized void init() { try { if (inited) return; inited = true; Workspace workspace = registry.getPlugin(Workspace.class); HttpClient client = registry.getPlugin(HttpClient.class); File localRepo = IO.getFile(configuration.local(MAVEN_REPO_LOCAL)); File location = workspace.getFile(getLocation()); List<MavenBackingRepository> release = MavenBackingRepository.create(configuration.releaseUrls(), reporter, localRepo, client); List<MavenBackingRepository> snapshot = MavenBackingRepository.create(configuration.snapshotUrls(), reporter, localRepo, client); MavenRepository repository = new MavenRepository(localRepo, name, release, snapshot, Processor.getExecutor(), reporter, null); if (pomFiles != null) { repoImpl = new PomRepository(repository, client, location).uris(pomFiles); } else if (revisions != null) { repoImpl = new PomRepository(repository, client, location).revisions(revisions); } else if (query != null) { repoImpl = new SearchRepository(repository, location, query, queryUrl, workspace, client); } else { repository.close(); throw new IllegalStateException("We have neither a pom, revision, or query set!"); } bridge = new BridgeRepository(repoImpl); } catch (Exception e) { throw Exceptions.duck(e); } } @Override public boolean refresh() throws Exception { init(); repoImpl.refresh(); bridge = new BridgeRepository(repoImpl); return true; } @Override public void setProperties(Map<String,String> map) throws Exception { configuration = Converter.cnv(PomConfiguration.class, map); if (configuration.name() == null) throw new IllegalArgumentException("Must get a name"); this.name = configuration.name(); if (configuration.pom() != null) { List<String> parts = Strings.split(configuration.pom()); pomFiles = new ArrayList<>(); for (String part : parts) { File f = IO.getFile(part); if (f.isFile()) { pomFiles.add(f.toURI()); } else { pomFiles.add(URI.create(part)); } } if (pomFiles.isEmpty()) { throw new IllegalArgumentException("Pom is neither a file nor a revision " + configuration.pom()); } } else if (configuration.revision() != null) { List<String> parts = Strings.split(configuration.revision()); revisions = new ArrayList<>(); for (String part : parts) { Revision revision = Revision.valueOf(part); if (revision != null) { revisions.add(revision); } } if (revisions.isEmpty()) { throw new IllegalArgumentException( "Revision is neither a file nor a revision " + configuration.revision()); } } else if (configuration.query() != null) { this.query = configuration.query(); this.queryUrl = configuration.queryUrl("http://search.maven.org/solrsearch/select"); } else { throw new IllegalArgumentException("Neither pom, revision nor query property are set"); } inited = false; } @Override public Map<Requirement,Collection<Capability>> findProviders(Collection< ? extends Requirement> requirements) { init(); return repoImpl.findProviders(requirements); } @Override public void setReporter(Reporter processor) { this.reporter = processor; } @Override public void setRegistry(Registry registry) { this.registry = registry; } @Override public PutResult put(InputStream stream, PutOptions options) throws Exception { throw new UnsupportedOperationException(); } @Override public File get(String bsn, Version version, Map<String,String> properties, DownloadListener... listeners) throws Exception { init(); ResourceInfo resource = bridge.getInfo(bsn, version); if (resource == null) return null; String name = resource.getInfo().name(); Archive archive = Archive.valueOf(name); Promise<File> p = repoImpl.getMavenRepository().get(archive); if (listeners.length == 0) return p.getValue(); new DownloadListenerPromise(reporter, name + ": get " + bsn + ";" + version, p, listeners); return repoImpl.getMavenRepository().toLocalFile(archive); } @Override public boolean canWrite() { return false; } @Override public List<String> list(String pattern) throws Exception { init(); return bridge.list(pattern); } @Override public SortedSet<Version> versions(String bsn) throws Exception { init(); return bridge.versions(bsn); } @Override public String getName() { return name; } @Override public String getLocation() { return configuration.location("cnf/cache/pom-" + name + ".xml"); } public String toString() { return name; } @Override public File getRoot() throws Exception { return repoImpl.getLocation(); } @Override public Map<String,Runnable> actions(Object... target) throws Exception { return null; } @Override public String tooltip(Object... target) throws Exception { init(); return bridge.tooltip(target); } @Override public String title(Object... target) throws Exception { init(); return bridge.title(target); } }