-
Notifications
You must be signed in to change notification settings - Fork 196
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Extract some generic bndlib code into a common module
(cherry picked from commit c478f65)
- Loading branch information
Showing
13 changed files
with
279 additions
and
196 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
eclipse.preferences.version=1 | ||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=17 | ||
org.eclipse.jdt.core.compiler.compliance=17 | ||
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled | ||
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning | ||
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore | ||
org.eclipse.jdt.core.compiler.release=enabled | ||
org.eclipse.jdt.core.compiler.source=17 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
<parent> | ||
<groupId>org.eclipse.tycho</groupId> | ||
<artifactId>tycho</artifactId> | ||
<version>4.0.12-SNAPSHOT</version> | ||
</parent> | ||
<artifactId>tycho-bndlib</artifactId> | ||
<name>Tycho BNDlib Extensions</name> | ||
<description>Provides extensions to BNDlib used by Tycho</description> | ||
<dependencies> | ||
<dependency> | ||
<groupId>biz.aQute.bnd</groupId> | ||
<artifactId>biz.aQute.bndlib</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.eclipse.jdt</groupId> | ||
<artifactId>org.eclipse.jdt.core</artifactId> | ||
</dependency> | ||
</dependencies> | ||
</project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
50 changes: 50 additions & 0 deletions
50
tycho-bndlib/src/main/java/org/eclipse/tycho/bndlib/JDTClazz.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
/******************************************************************************* | ||
* 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 java.util.HashSet; | ||
import java.util.Set; | ||
|
||
import aQute.bnd.osgi.Analyzer; | ||
import aQute.bnd.osgi.Clazz; | ||
import aQute.bnd.osgi.Descriptors.TypeRef; | ||
import aQute.bnd.osgi.Resource; | ||
|
||
/** | ||
* An extension to the (bndlib) {@link Clazz} that is capable to return | ||
* discovered information form the java sources. | ||
*/ | ||
final class JDTClazz extends Clazz { | ||
private Set<TypeRef> annotations = new HashSet<>(); | ||
private TypeRef className; | ||
|
||
JDTClazz(Analyzer analyzer, String path, Resource resource, TypeRef className) { | ||
super(analyzer, path, resource); | ||
this.className = className; | ||
} | ||
|
||
@Override | ||
public TypeRef getClassName() { | ||
return className; | ||
} | ||
|
||
@Override | ||
public Set<TypeRef> annotations() { | ||
return annotations; | ||
} | ||
|
||
void addAnnotation(TypeRef typeRef) { | ||
annotations.add(typeRef); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
181 changes: 181 additions & 0 deletions
181
tycho-bndlib/src/main/java/org/eclipse/tycho/bndlib/SourceCodeAnalyzerPlugin.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,181 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2023, 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.bndlib; | ||
|
||
import java.io.File; | ||
import java.io.IOException; | ||
import java.nio.file.FileVisitResult; | ||
import java.nio.file.FileVisitor; | ||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
import java.nio.file.attribute.BasicFileAttributes; | ||
import java.util.HashMap; | ||
import java.util.HashSet; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.Set; | ||
|
||
import org.eclipse.jdt.core.dom.AST; | ||
import org.eclipse.jdt.core.dom.ASTNode; | ||
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.MemberValuePair; | ||
import org.eclipse.jdt.core.dom.NormalAnnotation; | ||
import org.eclipse.jdt.core.dom.PackageDeclaration; | ||
import org.eclipse.jdt.core.dom.SingleMemberAnnotation; | ||
import org.eclipse.jdt.core.dom.StringLiteral; | ||
|
||
import aQute.bnd.header.Attrs; | ||
import aQute.bnd.osgi.Analyzer; | ||
import aQute.bnd.osgi.Builder; | ||
import aQute.bnd.osgi.Clazz; | ||
import aQute.bnd.osgi.Descriptors.PackageRef; | ||
import aQute.bnd.osgi.FileResource; | ||
import aQute.bnd.service.AnalyzerPlugin; | ||
|
||
/** | ||
* Enhances the analyzed classes by information obtained from the source code | ||
*/ | ||
public class SourceCodeAnalyzerPlugin implements AnalyzerPlugin { | ||
|
||
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_CLASS = PACKAGE_INFO + ".class"; | ||
private List<Path> sourcePaths; | ||
private Map<PackageRef, Clazz> packageInfoMap = new HashMap<>(); | ||
private boolean alreadyRun; | ||
|
||
public SourceCodeAnalyzerPlugin() { | ||
this(null); | ||
} | ||
|
||
public SourceCodeAnalyzerPlugin(List<Path> sourcePaths) { | ||
this.sourcePaths = sourcePaths; | ||
} | ||
|
||
@Override | ||
public boolean analyzeJar(Analyzer analyzer) throws Exception { | ||
if (alreadyRun) { | ||
return false; | ||
} | ||
alreadyRun = true; | ||
ASTParser parser = ASTParser.newParser(AST.getJLSLatest()); | ||
Set<String> seenPackages = new HashSet<>(); | ||
Set<Path> analyzedPath = new HashSet<>(); | ||
for (Path sourcePath : getSourcePath(analyzer)) { | ||
Files.walkFileTree(sourcePath, new FileVisitor<Path>() { | ||
|
||
@Override | ||
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { | ||
return FileVisitResult.CONTINUE; | ||
} | ||
|
||
@Override | ||
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { | ||
String fileName = file.getFileName().toString().toLowerCase(); | ||
if (fileName.endsWith(".java")) { | ||
boolean packageInfo = fileName.equals(PACKAGE_INFO_JAVA); | ||
if (packageInfo || analyzedPath.add(file.getParent())) { | ||
String source = Files.readString(file); | ||
parser.setSource(source.toCharArray()); | ||
ASTNode ast = parser.createAST(null); | ||
if (ast instanceof CompilationUnit cu) { | ||
PackageDeclaration packageDecl = cu.getPackage(); | ||
if (packageDecl != null) { | ||
String packageFqdn = packageDecl.getName().getFullyQualifiedName(); | ||
PackageRef packageRef = analyzer.getPackageRef(packageFqdn); | ||
if (seenPackages.add(packageFqdn)) { | ||
// make the package available to bnd analyzer | ||
analyzer.getContained().put(packageRef); | ||
} | ||
if (packageInfo) { | ||
JDTClazz clazz = new JDTClazz(analyzer, | ||
packageRef.getBinary() + "/" + PACKAGE_INFO_CLASS, | ||
new FileResource(file), | ||
analyzer.getTypeRef(packageRef.getBinary() + "/" + PACKAGE_INFO)); | ||
// check for export annotations | ||
boolean export = false; | ||
String version = null; | ||
for (Object raw : packageDecl.annotations()) { | ||
if (raw instanceof Annotation annot) { | ||
String annotationFqdn = annot.getTypeName().getFullyQualifiedName(); | ||
if (ANNOTATION_EXPORT.equals(annotationFqdn)) { | ||
export = true; | ||
clazz.addAnnotation( | ||
analyzer.getTypeRef(ANNOTATION_EXPORT.replace('.', '/'))); | ||
} else if (ANNOTATION_VERSION.equals(annotationFqdn)) { | ||
if (annot instanceof NormalAnnotation normal) { | ||
for (Object vp : normal.values()) { | ||
MemberValuePair pair = (MemberValuePair) vp; | ||
if ("value" | ||
.equals(pair.getName().getFullyQualifiedName())) { | ||
StringLiteral value = (StringLiteral) pair.getValue(); | ||
version = value.getLiteralValue(); | ||
} | ||
} | ||
} else if (annot instanceof SingleMemberAnnotation single) { | ||
StringLiteral value = (StringLiteral) single.getValue(); | ||
version = value.getLiteralValue(); | ||
} | ||
} | ||
} | ||
} | ||
if (export) { | ||
packageInfoMap.put(packageRef, clazz); | ||
if (version == null) { | ||
analyzer.getContained().put(packageRef); | ||
} else { | ||
analyzer.getContained().put(packageRef, | ||
Attrs.create("version", version)); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
return FileVisitResult.CONTINUE; | ||
} | ||
|
||
@Override | ||
public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException { | ||
return FileVisitResult.CONTINUE; | ||
} | ||
|
||
@Override | ||
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { | ||
return FileVisitResult.CONTINUE; | ||
} | ||
}); | ||
} | ||
return false; | ||
} | ||
|
||
private List<Path> getSourcePath(Analyzer analyzer) { | ||
if (sourcePaths != null) { | ||
return sourcePaths; | ||
} | ||
if (analyzer instanceof Builder builder) { | ||
return builder.getSourcePath().stream().map(File::toPath).toList(); | ||
} | ||
return List.of(); | ||
} | ||
|
||
public Clazz getPackageInfo(PackageRef packageRef) { | ||
return packageInfoMap.get(packageRef); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.