+ // add legal notices and licenses
+ for (Path p : listLegalFilesToInclude(source).values()) {
+ jarOut.putNextEntry(new JarEntry(p.getFileName().toString()));
+ Files.copy(p, jarOut);
+ }
+
+ // add sources
+ // TODO add effective BND, Eclipse project file, etc., in order to be able to
+ // repackage
+ if (!sourceBundles) {
+ copySourcesToJar(srcP, jarOut, "OSGI-OPT/src/");
+ }
+ }
+
+ if (sourceBundles) {// create separate sources jar
+ Path a2srcJarDirectory = bundleParent != null ? a2srcOutput.resolve(bundleParent).resolve(category)
+ : a2srcOutput.resolve(category);
+ Files.createDirectories(a2srcJarDirectory);
+ Path srcJarP = a2srcJarDirectory.resolve(compiled.getFileName() + "." + major + "." + minor + ".src.jar");
+ Manifest srcManifest = new Manifest();
+ srcManifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
+ srcManifest.getMainAttributes().putValue("Bundle-SymbolicName", bundleSymbolicName + ".src");
+ srcManifest.getMainAttributes().putValue("Bundle-Version",
+ manifest.getMainAttributes().getValue("Bundle-Version").toString());
+ srcManifest.getMainAttributes().putValue("Eclipse-SourceBundle",
+ bundleSymbolicName + ";version=\"" + manifest.getMainAttributes().getValue("Bundle-Version"));
+
+ try (JarOutputStream srcJarOut = new JarOutputStream(Files.newOutputStream(srcJarP), srcManifest)) {
+ copySourcesToJar(srcP, srcJarOut, "");
+ // add legal notices and licenses
+ for (Path p : listLegalFilesToInclude(source).values()) {
+ srcJarOut.putNextEntry(new JarEntry(p.getFileName().toString()));
+ Files.copy(p, srcJarOut);
+ }
+ }
+ }
+ }
+
+ /** List the relevant legal files to include, from the SDK source base. */
+ Map<String, Path> listLegalFilesToInclude(Path bundleBase) throws IOException {
+ Map<String, Path> toInclude = new HashMap<>();
+ if (!noSdkLegal) {
+ DirectoryStream<Path> sdkSrcLegal = Files.newDirectoryStream(sdkSrcBase, (p) -> {
+ String fileName = p.getFileName().toString();
+ return switch (fileName) {
+ case "NOTICE":
+ case "LICENSE":
+ case "COPYING":
+ case "COPYING.LESSER":
+ yield true;
+ default:
+ yield false;
+ };
+ });
+ for (Path p : sdkSrcLegal)
+ toInclude.put(p.getFileName().toString(), p);
+ }
+ for (Iterator<Map.Entry<String, Path>> entries = toInclude.entrySet().iterator(); entries.hasNext();) {
+ Map.Entry<String, Path> entry = entries.next();
+ Path inBundle = bundleBase.resolve(entry.getValue().getFileName());
+ // remove file if it is also defined at bundle level
+ // since it has already been copied
+ // and has priority
+ if (Files.exists(inBundle))
+ entries.remove();