Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for platform URLs in automatic manifest generation plugins #3370

Merged
merged 1 commit into from
Jan 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions tools/src/tools/ExportArtifact.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*******************************************************************************
* Copyright (c) 2024 Christoph Läubrich and others.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Christoph Läubrich - initial API and implementation
*******************************************************************************/
package tools;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
import java.util.jar.JarFile;

/**
* prints a list of packages from a jar that can be used inside
* tycho-maven-plugin/src/main/resources/META-INF/maven/extension.xml
*/
public class ExportArtifact {
public static void main(String[] args) throws IOException {
Map<String, List<String>> packages = new TreeMap<>();
try (JarFile jarFile = new JarFile(args[0])) {
jarFile.stream().forEach(entry -> {
String name = entry.getName();
if (name.endsWith(".class")) {
int lastIndexOf = name.lastIndexOf('/');
if (lastIndexOf > 0) {
String pkg = name.substring(0, lastIndexOf).replace('/', '.');
packages.computeIfAbsent(pkg, x -> new ArrayList<>()).add(name);
}
}
});
}
for (Entry<String, List<String>> pkg : packages.entrySet()) {
if (pkg.getValue().isEmpty()) {
continue;
}
System.out.println("<exportedPackage>" + pkg.getKey() + "</exportedPackage>");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@
import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.component.annotations.Requirement;
import org.codehaus.plexus.logging.Logger;
import org.eclipse.tycho.core.bnd.BndPluginManager;

import aQute.bnd.build.Project;
import aQute.bnd.build.Workspace;
import aQute.bnd.osgi.Constants;
import aQute.bnd.service.RepositoryPlugin;

/**
* This component injects information from the BND model into the maven model,
Expand All @@ -64,7 +64,7 @@ public class BndMavenLifecycleParticipant extends AbstractMavenLifecycleParticip
private Logger logger;

@Requirement
private Map<String, RepositoryPlugin> repositoryPlugins;
private BndPluginManager bndPluginManager;

@Override
public void afterProjectsRead(MavenSession session) throws MavenExecutionException {
Expand Down Expand Up @@ -174,10 +174,7 @@ private Map<MavenProject, Project> getProjects(MavenSession session) {
File basedir = mavenProject.getBasedir();
Workspace ws = Workspace.findWorkspace(basedir.getParentFile());
if (workspaces.add(ws)) {
for (RepositoryPlugin repositoryPlugin : repositoryPlugins.values()) {
ws.addBasicPlugin(repositoryPlugin);
}
ws.refresh();
bndPluginManager.setupWorkspace(ws);
}
Project project = ws.getProject(basedir.getName());
mavenProject.setContextValue(Project.class.getName(), project);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.Map;
import java.util.function.Predicate;
import java.util.regex.Matcher;
import java.util.stream.Collectors;

import org.apache.maven.artifact.Artifact;
Expand All @@ -32,12 +32,16 @@
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.apache.maven.project.MavenProject;
import org.eclipse.tycho.ArtifactKey;
import org.eclipse.tycho.ArtifactType;
import org.eclipse.tycho.ClasspathEntry;
import org.eclipse.tycho.TargetPlatform;
import org.eclipse.tycho.TychoConstants;
import org.eclipse.tycho.bnd.MavenProjectJar;
import org.eclipse.tycho.classpath.ClasspathContributor;
import org.eclipse.tycho.core.TychoProject;
import org.eclipse.tycho.core.TychoProjectManager;
import org.eclipse.tycho.core.bnd.BndPluginManager;
import org.eclipse.tycho.core.osgitools.BundleClassPath;
import org.eclipse.tycho.core.osgitools.DefaultReactorProject;
import org.eclipse.tycho.core.osgitools.OsgiBundleProject;
Expand All @@ -49,7 +53,6 @@
import aQute.bnd.osgi.Constants;
import aQute.bnd.osgi.Jar;
import aQute.bnd.osgi.Processor;
import aQute.bnd.service.RepositoryPlugin;

/**
* The mojos support generation of the manifest file like it is done in PDE if
Expand All @@ -66,7 +69,7 @@ public class GenerateManifestMojo extends AbstractMojo {
};

@Component
private Map<String, RepositoryPlugin> repositoryPlugins;
private BndPluginManager bndPluginManager;

@Parameter(property = "project", readonly = true)
protected MavenProject mavenProject;
Expand All @@ -87,7 +90,32 @@ public void execute() throws MojoExecutionException, MojoFailureException {
File instructionsFile = new File(basedir, TychoConstants.PDE_BND);
if (instructionsFile.isFile()) {
try (Project project = new Project(getWorkspace(), basedir, instructionsFile);
ProjectBuilder builder = new ProjectBuilder(project);
ProjectBuilder builder = new ProjectBuilder(project) {
@Override
public Jar getJarFromName(String name, String from) {
Matcher m = TychoConstants.PLATFORM_URL_PATTERN.matcher(name);
if (m.matches()) {
TargetPlatform targetPlatform = projectManager.getTargetPlatform(mavenProject)
.orElse(null);
if (targetPlatform == null) {
return null;
}
String pluginId = m.group(2);
try {
ArtifactKey artifact = targetPlatform
.resolveArtifact(ArtifactType.TYPE_ECLIPSE_PLUGIN, pluginId, null);
File artifactLocation = targetPlatform.getArtifactLocation(artifact);
if (artifactLocation == null) {
return null;
}
return new Jar(artifactLocation);
} catch (Exception e) {
return null;
}
}
return super.getJarFromName(name, from);
}
};
Jar jar = new MavenProjectJar(mavenProject, CLASS_FILTER)) {
setupProject(project);
BundleClassPath bundleClassPath = osgi
Expand Down Expand Up @@ -138,10 +166,7 @@ Workspace getWorkspace() throws Exception {
run.setProperty(Constants.STANDALONE, "true");
Workspace workspace = Workspace.createStandaloneWorkspace(run,
new File(mavenProject.getBuild().getDirectory(), Project.BNDCNF).toURI());
for (RepositoryPlugin repositoryPlugin : repositoryPlugins.values()) {
workspace.addBasicPlugin(repositoryPlugin);
}
workspace.refresh();
bndPluginManager.setupWorkspace(workspace);
return workspace;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.regex.Matcher;

import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.component.annotations.Component;
Expand All @@ -27,7 +28,10 @@
import org.eclipse.tycho.ArtifactKey;
import org.eclipse.tycho.ArtifactType;
import org.eclipse.tycho.ClasspathEntry;
import org.eclipse.tycho.DependencyResolutionException;
import org.eclipse.tycho.IllegalArtifactReferenceException;
import org.eclipse.tycho.ReactorProject;
import org.eclipse.tycho.TargetPlatform;
import org.eclipse.tycho.TychoConstants;
import org.eclipse.tycho.classpath.ClasspathContributor;
import org.eclipse.tycho.core.TychoProjectManager;
Expand All @@ -54,7 +58,21 @@ public List<ClasspathEntry> getAdditionalClasspathEntries(MavenProject project,
if (classpath != null && !classpath.isBlank()) {
List<ClasspathEntry> additional = new ArrayList<>();
for (String file : classpath.split(",")) {
additional.add(new BndClasspathEntry(new File(project.getBasedir(), file.trim())));
Matcher m = TychoConstants.PLATFORM_URL_PATTERN.matcher(file);
if (m.matches()) {
TargetPlatform targetPlatform = projectManager.getTargetPlatform(project)
.orElseThrow(() -> new IllegalStateException("Project has no target platform"));
try {
ArtifactKey artifactKey = targetPlatform
.resolveArtifact(ArtifactType.TYPE_ECLIPSE_PLUGIN, m.group(2), null);
File location = targetPlatform.getArtifactLocation(artifactKey);
additional.add(new BndClasspathEntry(location, artifactKey));
} catch (DependencyResolutionException | IllegalArtifactReferenceException e) {
throw new RuntimeException("can't resolve classpath entry " + file, e);
}
} else {
additional.add(new BndClasspathEntry(new File(project.getBasedir(), file.trim()), null));
}
}
return additional;
}
Expand All @@ -66,17 +84,19 @@ public List<ClasspathEntry> getAdditionalClasspathEntries(MavenProject project,
return Collections.emptyList();
}

private static final class BndClasspathEntry implements ClasspathEntry, ArtifactKey {
private static final class BndClasspathEntry implements ClasspathEntry {

private File file;
private ArtifactKey artifactKey;

public BndClasspathEntry(File file) {
public BndClasspathEntry(File file, ArtifactKey artifactKey) {
this.file = file;
this.artifactKey = artifactKey == null ? new FileBasedKey(file) : artifactKey;
}

@Override
public ArtifactKey getArtifactKey() {
return this;
return artifactKey;
}

@Override
Expand All @@ -94,6 +114,16 @@ public Collection<AccessRule> getAccessRules() {
return null;
}

}

private static final class FileBasedKey implements ArtifactKey {

private File file;

public FileBasedKey(File file) {
this.file = file;
}

@Override
public String getType() {
return ArtifactType.TYPE_ECLIPSE_PLUGIN;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*******************************************************************************
* Copyright (c) 2024 Christoph Läubrich and others.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Christoph Läubrich - initial API and implementation
*******************************************************************************/
package org.eclipse.tycho.core.bnd;

import java.util.Map;

import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.component.annotations.Requirement;

import aQute.bnd.build.Workspace;
import aQute.bnd.service.RepositoryPlugin;

/**
* Manager that collects BndPlugins in the plexus domain and installs them into a workspace
*/
@Component(role = BndPluginManager.class)
public class BndPluginManager {
@Requirement
private Map<String, RepositoryPlugin> repositoryPlugins;

public void setupWorkspace(Workspace ws) {
repositoryPlugins.values().forEach(ws::addBasicPlugin);
ws.refresh();
}
}
Loading
Loading