Skip to content

Commit

Permalink
Evaluate Package Attributes from source
Browse files Browse the repository at this point in the history
Currently if the evaluation of a version property contains a reference
to a package attribute this fails in the initial phase because bnd
requires the classfiles to be present in such case it is read from an
package-info annotated file.

This now uses the SourceCodeAnalyzerPlugin to recover this information
from the java source files.

(cherry picked from commit 9eb105a)
  • Loading branch information
laeubi committed Feb 13, 2025
1 parent d37ccb3 commit ab91e71
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 14 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*******************************************************************************
* Copyright (c) 2025 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.bndlib;

import aQute.bnd.build.Project;
import aQute.bnd.build.ProjectBuilder;

/**
* A project builder that injects information from the sources into the builder
*/
public class JdtProjectBuilder extends ProjectBuilder {

public JdtProjectBuilder(Project project) {
super(project);
addBasicPlugin(new SourceCodeAnalyzerPlugin());
}

@Override
public String _packageattribute(String[] args) {
SourceCodeAnalyzerPlugin analyzerPlugin = getPlugin(SourceCodeAnalyzerPlugin.class);
try {
analyzerPlugin.analyzeJar(this);
} catch (Exception e) {
}
return super._packageattribute(args);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.Annotation;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.ImportDeclaration;
import org.eclipse.jdt.core.dom.MemberValuePair;
import org.eclipse.jdt.core.dom.Name;
import org.eclipse.jdt.core.dom.NormalAnnotation;
import org.eclipse.jdt.core.dom.PackageDeclaration;
import org.eclipse.jdt.core.dom.SingleMemberAnnotation;
Expand All @@ -49,10 +51,11 @@
*/
public class SourceCodeAnalyzerPlugin implements AnalyzerPlugin {

private static final String JAVA_EXTENSION = ".java";
private static final String PACKAGE_INFO = "package-info";
private static final String ANNOTATION_VERSION = "org.osgi.annotation.versioning.Version";
private static final String ANNOTATION_EXPORT = "org.osgi.annotation.bundle.Export";
private static final String PACKAGE_INFO_JAVA = PACKAGE_INFO + ".java";
private static final String PACKAGE_INFO_JAVA = PACKAGE_INFO + JAVA_EXTENSION;
private static final String PACKAGE_INFO_CLASS = PACKAGE_INFO + ".class";
private List<Path> sourcePaths;
private Map<PackageRef, Clazz> packageInfoMap = new HashMap<>();
Expand Down Expand Up @@ -86,7 +89,7 @@ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) th
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
String fileName = file.getFileName().toString().toLowerCase();
if (fileName.endsWith(".java")) {
if (fileName.endsWith(JAVA_EXTENSION)) {
boolean packageInfo = fileName.equals(PACKAGE_INFO_JAVA);
if (packageInfo || analyzedPath.add(file.getParent())) {
String source = Files.readString(file);
Expand All @@ -95,6 +98,7 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IO
if (ast instanceof CompilationUnit cu) {
PackageDeclaration packageDecl = cu.getPackage();
if (packageDecl != null) {
List<?> imports = cu.imports();
String packageFqdn = packageDecl.getName().getFullyQualifiedName();
PackageRef packageRef = analyzer.getPackageRef(packageFqdn);
if (seenPackages.add(packageFqdn)) {
Expand All @@ -111,12 +115,13 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IO
String version = null;
for (Object raw : packageDecl.annotations()) {
if (raw instanceof Annotation annot) {
String annotationFqdn = annot.getTypeName().getFullyQualifiedName();
if (ANNOTATION_EXPORT.equals(annotationFqdn)) {
Name typeName = annot.getTypeName();
String annotationFqdn = typeName.getFullyQualifiedName();
if (isType(annotationFqdn, ANNOTATION_EXPORT, imports)) {
export = true;
clazz.addAnnotation(
analyzer.getTypeRef(ANNOTATION_EXPORT.replace('.', '/')));
} else if (ANNOTATION_VERSION.equals(annotationFqdn)) {
} else if (isType(annotationFqdn, ANNOTATION_VERSION, imports)) {
if (annot instanceof NormalAnnotation normal) {
for (Object vp : normal.values()) {
MemberValuePair pair = (MemberValuePair) vp;
Expand All @@ -133,14 +138,12 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IO
}
}
}
if (version != null) {
// if the package is exported or not, the version info must be propagated
analyzer.getContained().put(packageRef, Attrs.create("version", version));
}
if (export) {
packageInfoMap.put(packageRef, clazz);
if (version == null) {
analyzer.getContained().put(packageRef);
} else {
analyzer.getContained().put(packageRef,
Attrs.create("version", version));
}
}
}
}
Expand Down Expand Up @@ -174,8 +177,24 @@ private List<Path> getSourcePath(Analyzer analyzer) {
return List.of();
}

public Clazz getPackageInfo(PackageRef packageRef) {
public Clazz getPackageInfoClass(PackageRef packageRef) {
return packageInfoMap.get(packageRef);
}

private static boolean isType(String simpleOrFqdn, String type, List<?> imports) {
if (type.equals(simpleOrFqdn)) {
return true;
}
if (type.endsWith("." + simpleOrFqdn)) {
for (Object object : imports) {
if (object instanceof ImportDeclaration importDecl) {
if (type.equals(importDecl.getName().getFullyQualifiedName())) {
return true;
}
}
}
}
return false;
}

}
5 changes: 5 additions & 0 deletions tycho-build/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -150,5 +150,10 @@
<artifactId>org.osgi.util.promise</artifactId>
<version>1.3.0</version>
</dependency>
<dependency>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-bndlib</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.component.annotations.Requirement;
import org.eclipse.tycho.TychoConstants;
import org.eclipse.tycho.bndlib.JdtProjectBuilder;
import org.eclipse.tycho.pomless.AbstractTychoMapping;
import org.eclipse.tycho.pomless.NoParentPomFound;
import org.eclipse.tycho.pomless.ParentModel;
Expand Down Expand Up @@ -168,7 +169,7 @@ protected void initModel(Model model, Reader artifactReader, Path artifactFile)
}

private static ProjectBuilder createBuilder(Project project) throws Exception {
ProjectBuilder builder = new ProjectBuilder(project);
ProjectBuilder builder = new JdtProjectBuilder(project);
builder.setBase(project.getBase());
builder.use(project);
builder.setFailOk(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ private Collection<IInstallableUnit> generateWithProcessor(MavenProject project,
public Clazz getPackageInfo(PackageRef packageRef) {
Clazz info = super.getPackageInfo(packageRef);
if (info == null) {
return plugin.getPackageInfo(packageRef);
return plugin.getPackageInfoClass(packageRef);
}
return info;
}
Expand Down

0 comments on commit ab91e71

Please sign in to comment.