Start working on A2 factory.
authorMathieu Baudier <mbaudier@argeo.org>
Fri, 4 Feb 2022 08:18:01 +0000 (09:18 +0100)
committerMathieu Baudier <mbaudier@argeo.org>
Fri, 4 Feb 2022 08:18:01 +0000 (09:18 +0100)
20 files changed:
.gitignore
Makefile [new file with mode: 0644]
branch.properties [new file with mode: 0644]
configure [new file with mode: 0644]
org.argeo.slc.api/src/org/argeo/slc/ManifestConstants.java [new file with mode: 0644]
org.argeo.slc.api/src/org/argeo/slc/NameVersion.java
org.argeo.slc.build/.classpath [new file with mode: 0644]
org.argeo.slc.build/.project [new file with mode: 0644]
org.argeo.slc.build/bnd.bnd [new file with mode: 0644]
org.argeo.slc.build/build.properties [new file with mode: 0644]
org.argeo.slc.build/src/org/argeo/slc/build/A2DistributionUnit.java [new file with mode: 0644]
org.argeo.slc.build/src/org/argeo/slc/build/A2Factory.java [new file with mode: 0644]
org.argeo.slc.build/src/org/argeo/slc/build/bnd/BndManifestFactory.java [new file with mode: 0644]
org.argeo.slc.build/src/org/argeo/slc/build/m2/Artifact.java [new file with mode: 0644]
org.argeo.slc.build/src/org/argeo/slc/build/m2/DefaultArtifact.java [new file with mode: 0644]
org.argeo.slc.build/src/org/argeo/slc/build/m2/MavenConventionsUtils.java [new file with mode: 0644]
org.argeo.slc.repo/src/org/argeo/slc/repo/FreeLicense.java
org.argeo.slc.repo/src/org/argeo/slc/repo/osgi/ArgeoOsgiDistributionImpl.java
org.argeo.slc.repo/src/org/argeo/slc/repo/osgi/BndWrapper.java
sdk/includes.mk [new file with mode: 0644]

index 492e809ea5293775af439187d46c91da46ee80da..d6fc805c79105221a8bdf18ad8ed8557f7d93887 100644 (file)
@@ -2,3 +2,5 @@
 **/target/
 **/generated/
 **/MANIFEST.MF
+/sdk.mk
+/output/
diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..d6bda78
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,89 @@
+include sdk.mk
+.PHONY: clean all osgi
+
+all: osgi
+
+BUNDLE_PREFIX = org.argeo
+A2_CATEGORY = org.argeo
+
+BUNDLES = \
+org.argeo.slc.api \
+org.argeo.slc.build \
+
+BUILD_CLASSPATH = \
+/usr/share/java/osgi-core/osgi.core.jar:$\
+/usr/share/java/osgi-compendium/osgi.cmpn.jar:$\
+/usr/share/java/ecj/ecj.jar:$\
+/usr/share/java/aqute-bnd/biz.aQute.bndlib.jar:$\
+/usr/share/java/slf4j/api.jar:$\
+/usr/share/java/commons-io.jar:$\
+/usr/share/java/commons-cli.jar:$\
+/usr/share/java/commons-exec.jar:$\
+
+# TODO relativize from SDK_SRC_BASE
+BUILD_BASE = $(SDK_BUILD_BASE)
+
+#
+# GENERIC
+#
+JVM := /usr/lib/jvm/jre-11/bin/java
+JAVADOC := /usr/lib/jvm/jre-11/bin/javadoc
+ECJ_JAR := /usr/share/java/ecj/ecj.jar
+BND_TOOL := /usr/bin/bnd
+
+WORKSPACE_BNDS := $(shell cd $(SDK_SRC_BASE) && find cnf -name '*.bnd')
+#BND_WORKSPACES := $(foreach bundle, $(BUNDLES), ./$(dir $(bundle)))
+BUILD_WORKSPACE_BNDS := $(WORKSPACE_BNDS:%=$(SDK_BUILD_BASE)/%)
+
+cnf: $(BUILD_WORKSPACE_BNDS)
+
+A2_BUNDLES = $(BUNDLES:%=$(SDK_BUILD_BASE)/a2/$(A2_CATEGORY)/%.$(MAJOR).$(MINOR).jar)
+
+#JAVA_SRCS = $(shell find $(BUNDLE_PREFIX).* -name '*.java')
+JAVA_SRCS = $(foreach bundle, $(BUNDLES), $(shell find $(bundle) -name '*.java'))
+ECJ_SRCS = $(foreach bundle, $(BUNDLES), $(bundle)/src[-d $(BUILD_BASE)/$(bundle)/bin])
+
+osgi: cnf $(A2_BUNDLES)
+
+clean:
+       rm -rf $(BUILD_BASE)/*-compiled
+       rm -rf $(BUILD_BASE)/{cnf,a2}
+       rm -rf $(BUILD_BASE)/$(BUNDLE_PREFIX).* 
+
+# SDK level
+$(SDK_BUILD_BASE)/cnf/%.bnd: cnf/%.bnd
+       mkdir -p $(dir $@)
+       cp $< $@
+       
+$(SDK_BUILD_BASE)/eclipse/cnf/%.bnd: cnf/%.bnd
+       mkdir -p $(dir $@)
+       cp $< $@
+
+$(SDK_BUILD_BASE)/rcp/cnf/%.bnd: cnf/%.bnd
+       mkdir -p $(dir $@)
+       cp $< $@
+
+$(SDK_BUILD_BASE)/a2/$(A2_CATEGORY)/%.$(MAJOR).$(MINOR).jar : $(BUILD_BASE)/%/bundle.jar
+       mkdir -p $(dir $@)
+       cp $< $@
+
+# Build level
+$(BUILD_BASE)/%/bundle.jar : %/bnd.bnd $(BUILD_BASE)/java-compiled 
+       rsync -r --exclude "*.java" $(dir  $<)src/ $(dir $@)bin
+       rsync -r $(dir  $<)src/ $(dir $@)src
+       if [ -d "$(dir  $<)OSGI-INF" ]; then rsync -r $(dir  $<)OSGI-INF/ $(dir $@)/OSGI-INF; fi
+       cp $< $(dir $@)
+       cd $(dir $@) && $(BND_TOOL) build
+       mv $(dir $@)generated/*.jar $(dir $@)bundle.jar
+
+$(BUILD_BASE)/java-compiled : $(JAVA_SRCS)
+       $(JVM) -jar $(ECJ_JAR) -11 -nowarn -time -cp $(BUILD_CLASSPATH) \
+       $(ECJ_SRCS)
+       touch $@
+       
+null  :=
+space := $(null) #
+pathsep := :
+
+#WITH_LIST    := $(subst $(space),$(pathsep),$(strip $(WITH_LIST)))
+       
diff --git a/branch.properties b/branch.properties
new file mode 100644 (file)
index 0000000..7a7e579
--- /dev/null
@@ -0,0 +1,2 @@
+MAJOR=2
+MINOR=3
diff --git a/configure b/configure
new file mode 100644 (file)
index 0000000..4587bf4
--- /dev/null
+++ b/configure
@@ -0,0 +1,48 @@
+#!/bin/sh
+
+# We build where we are
+SDK_BUILD_BASE=$(pwd -P)/output
+
+# Source are located where this script is
+SDK_SRC_BASE="$(cd "$(dirname "$0")"; pwd -P)"
+
+SDK_MK=$SDK_SRC_BASE/sdk.mk
+
+#echo SDK_BUILD_BASE=$SDK_BUILD_BASE
+#echo SDK_SRC_BASE=$SDK_SRC_BASE
+#echo SDK_MK=$SDK_MK
+
+if [ -f "$SDK_MK" ]; 
+then
+
+echo "File $SDK_MK already exists. Remove it in order to configure a new build location:"
+echo "rm $SDK_MK"
+exit 1
+
+else
+
+# Create build directory, so that it can be used right away
+# and we check whether we have the rights
+mkdir -p $SDK_BUILD_BASE
+if [ -f "$SDK_MK" ];
+then
+echo "Cannot create $SDK_BUILD_BASE, SDK configuration has failed."
+exit 2
+fi
+
+# Generate sdk.mk
+cat > "$SDK_MK" <<EOF
+SDK_SRC_BASE := $SDK_SRC_BASE
+SDK_BUILD_BASE := $SDK_BUILD_BASE
+
+include \$(SDK_SRC_BASE)/branch.properties
+include \$(SDK_SRC_BASE)/sdk/includes.mk
+EOF
+
+
+echo SDK was configured.
+echo "Base for sources : $SDK_SRC_BASE"
+echo "Base for builds  : $SDK_BUILD_BASE"
+exit 0
+fi
+
diff --git a/org.argeo.slc.api/src/org/argeo/slc/ManifestConstants.java b/org.argeo.slc.api/src/org/argeo/slc/ManifestConstants.java
new file mode 100644 (file)
index 0000000..fb01d70
--- /dev/null
@@ -0,0 +1,25 @@
+package org.argeo.slc;
+
+public enum ManifestConstants {
+       // OSGi
+       BUNDLE_SYMBOLICNAME("Bundle-SymbolicName"), //
+       BUNDLE_VERSION("Bundle-Version"), //
+       // SLC
+       SLC_CATEGORY("SLC-Category"), //
+       SLC_ORIGIN_M2("SLC-Origin-M2"), //
+       SLC_ORIGIN_MANIFEST_NOT_MODIFIED("SLC-Origin-ManifestNotModified"), //
+       SLC_ORIGIN_URI("SLC-Origin-URI"),//
+       ;
+
+       final String value;
+
+       private ManifestConstants(String value) {
+               this.value = value;
+       }
+
+       @Override
+       public String toString() {
+               return value;
+       }
+
+}
index 19060490a7efa84e01cb57da14c6916f4d9bc911..45ce5835dabc8977c7c9374d6fe5bb718f677aab 100644 (file)
@@ -6,8 +6,19 @@ package org.argeo.slc;
  */
 public interface NameVersion {
        /** The name of the component. */
-       public String getName();
+       String getName();
 
        /** The version of the component. */
-       public String getVersion();
+       String getVersion();
+
+       /**
+        * The forward compatible branch of this version, by default it is
+        * [major].[minor].
+        */
+       default String getBranch() {
+               String[] parts = getVersion().split("\\.");
+               if (parts.length < 2)
+                       throw new IllegalStateException("Version " + getVersion() + " cannot be interpreted as branch.");
+               return parts[0] + "." + parts[1];
+       }
 }
diff --git a/org.argeo.slc.build/.classpath b/org.argeo.slc.build/.classpath
new file mode 100644 (file)
index 0000000..e801ebf
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11"/>
+       <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+       <classpathentry kind="src" path="src"/>
+       <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/org.argeo.slc.build/.project b/org.argeo.slc.build/.project
new file mode 100644 (file)
index 0000000..29c4c9e
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>org.argeo.slc.build</name>
+       <comment></comment>
+       <projects>
+       </projects>
+       <buildSpec>
+               <buildCommand>
+                       <name>org.eclipse.jdt.core.javabuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.pde.ManifestBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.pde.SchemaBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+       </buildSpec>
+       <natures>
+               <nature>org.eclipse.pde.PluginNature</nature>
+               <nature>org.eclipse.jdt.core.javanature</nature>
+       </natures>
+</projectDescription>
diff --git a/org.argeo.slc.build/bnd.bnd b/org.argeo.slc.build/bnd.bnd
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/org.argeo.slc.build/build.properties b/org.argeo.slc.build/build.properties
new file mode 100644 (file)
index 0000000..5d082ea
--- /dev/null
@@ -0,0 +1,5 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .
+additional.bundles = org.argeo.init
diff --git a/org.argeo.slc.build/src/org/argeo/slc/build/A2DistributionUnit.java b/org.argeo.slc.build/src/org/argeo/slc/build/A2DistributionUnit.java
new file mode 100644 (file)
index 0000000..f822e7f
--- /dev/null
@@ -0,0 +1,9 @@
+package org.argeo.slc.build;
+
+import org.argeo.slc.DefaultCategoryNameVersion;
+
+public class A2DistributionUnit extends DefaultCategoryNameVersion {
+       private String originVersion;
+       
+       
+}
diff --git a/org.argeo.slc.build/src/org/argeo/slc/build/A2Factory.java b/org.argeo.slc.build/src/org/argeo/slc/build/A2Factory.java
new file mode 100644 (file)
index 0000000..d53c566
--- /dev/null
@@ -0,0 +1,295 @@
+package org.argeo.slc.build;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.System.Logger;
+import java.lang.System.Logger.Level;
+import java.net.URL;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.PathMatcher;
+import java.nio.file.Paths;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.jar.Attributes;
+import java.util.jar.JarEntry;
+import java.util.jar.JarInputStream;
+import java.util.jar.Manifest;
+
+import org.argeo.slc.DefaultNameVersion;
+import org.argeo.slc.ManifestConstants;
+import org.argeo.slc.NameVersion;
+
+public class A2Factory {
+       private final static Logger logger = System.getLogger(A2Factory.class.getName());
+
+       private Path originBase;
+       private Path factoryBase;
+
+       /** key is URI prefix, value list of base URLs */
+       private Map<String, List<String>> mirrors = new HashMap<String, List<String>>();
+
+       public A2Factory(Path originBase, Path factoryBase) {
+               super();
+               this.originBase = originBase;
+               this.factoryBase = factoryBase;
+
+               // TODO make it configurable
+               List<String> eclipseMirrors = new ArrayList<>();
+               eclipseMirrors.add("https://archive.eclipse.org/");
+
+               mirrors.put("http://www.eclipse.org/downloads", eclipseMirrors);
+       }
+
+       public void processEclipseArchive(Path duDir) {
+               try {
+                       String category = duDir.getParent().getFileName().toString();
+                       Path targetCategoryBase = factoryBase.resolve(category);
+                       Files.createDirectories(targetCategoryBase);
+                       Files.createDirectories(originBase);
+
+                       Path commonBnd = duDir.resolve("common.bnd");
+                       Properties commonProps = new Properties();
+                       try (InputStream in = Files.newInputStream(commonBnd)) {
+                               commonProps.load(in);
+                       }
+                       Properties includes = new Properties();
+                       try (InputStream in = Files.newInputStream(duDir.resolve("includes.properties"))) {
+                               includes.load(in);
+                       }
+                       String url = commonProps.getProperty(ManifestConstants.SLC_ORIGIN_URI.toString());
+                       Path downloaded = tryDownload(url, originBase);
+
+                       FileSystem zipFs = FileSystems.newFileSystem(downloaded, null);
+
+                       List<PathMatcher> pathMatchers = new ArrayList<>();
+                       for (Object pattern : includes.keySet()) {
+                               PathMatcher pathMatcher = zipFs.getPathMatcher("glob:/" + pattern);
+                               pathMatchers.add(pathMatcher);
+                       }
+
+                       Files.walkFileTree(zipFs.getRootDirectories().iterator().next(), new SimpleFileVisitor<Path>() {
+
+                               @Override
+                               public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
+                                       pathMatchers: for (PathMatcher pathMatcher : pathMatchers) {
+                                               if (pathMatcher.matches(file)) {
+//                                                     Path target = targetBase.resolve(file.getFileName().toString());
+//                                                     if (!Files.exists(target)) {
+//                                                             Files.copy(file, target);
+//                                                             logger.log(Level.DEBUG, () -> "Copied " + target + " from " + downloaded);
+//                                                     } else {
+//                                                             logger.log(Level.DEBUG, () -> target + " already exists.");
+//
+//                                                     }
+                                                       if (file.getFileName().toString().contains(".source_")) {
+                                                               processEclipseSourceJar(file, targetCategoryBase);
+                                                               logger.log(Level.DEBUG, () -> "Processed source " + file);
+
+                                                       } else {
+                                                               processBundleJar(file, targetCategoryBase);
+                                                               logger.log(Level.DEBUG, () -> "Processed " + file);
+                                                       }
+                                                       continue pathMatchers;
+                                               }
+                                       }
+                                       return super.visitFile(file, attrs);
+                               }
+                       });
+               } catch (IOException e) {
+                       throw new RuntimeException("Cannot process " + duDir, e);
+               }
+
+       }
+
+       protected void processBundleJar(Path file, Path targetBase) throws IOException {
+               NameVersion nameVersion;
+               Path targetBundleDir;
+               try (JarInputStream jarIn = new JarInputStream(Files.newInputStream(file), false)) {
+                       Manifest manifest = jarIn.getManifest();
+                       nameVersion = nameVersionFromManifest(manifest);
+                       targetBundleDir = targetBase.resolve(nameVersion.getName() + "." + nameVersion.getBranch());
+
+                       // TODO make it less dangerous?
+                       if (Files.exists(targetBundleDir)) {
+                               deleteDirectory(targetBundleDir);
+                       }
+
+                       // copy entries
+                       JarEntry entry;
+                       entries: while ((entry = jarIn.getNextJarEntry()) != null) {
+                               if (entry.isDirectory())
+                                       continue entries;
+                               Path target = targetBundleDir.resolve(entry.getName());
+                               Files.createDirectories(target.getParent());
+                               Files.copy(jarIn, target);
+                               logger.log(Level.TRACE, () -> "Copied " + target);
+                       }
+
+                       // copy MANIFEST
+                       Path manifestPath = targetBundleDir.resolve("META-INF/MANIFEST.MF");
+                       Files.createDirectories(manifestPath.getParent());
+                       try (OutputStream out = Files.newOutputStream(manifestPath)) {
+                               manifest.write(out);
+                       }
+               }
+
+       }
+
+       protected void processEclipseSourceJar(Path file, Path targetBase) throws IOException {
+               // NameVersion nameVersion;
+               Path targetBundleDir;
+               try (JarInputStream jarIn = new JarInputStream(Files.newInputStream(file), false)) {
+                       Manifest manifest = jarIn.getManifest();
+                       // nameVersion = nameVersionFromManifest(manifest);
+
+                       String[] relatedBundle = manifest.getMainAttributes().getValue("Eclipse-SourceBundle").split(";");
+                       String version = relatedBundle[1].substring("version=\"".length());
+                       version = version.substring(0, version.length() - 1);
+                       NameVersion nameVersion = new DefaultNameVersion(relatedBundle[0], version);
+                       targetBundleDir = targetBase.resolve(nameVersion.getName() + "." + nameVersion.getBranch());
+
+                       Path targetSourceDir = targetBundleDir.resolve("OSGI-OPT/src");
+
+                       // TODO make it less dangerous?
+                       if (Files.exists(targetSourceDir)) {
+                               deleteDirectory(targetSourceDir);
+                       } else {
+                               Files.createDirectories(targetSourceDir);
+                       }
+
+                       // copy entries
+                       JarEntry entry;
+                       entries: while ((entry = jarIn.getNextJarEntry()) != null) {
+                               if (entry.isDirectory())
+                                       continue entries;
+                               if (entry.getName().startsWith("META-INF"))// skip META-INF entries
+                                       continue entries;
+                               Path target = targetSourceDir.resolve(entry.getName());
+                               Files.createDirectories(target.getParent());
+                               Files.copy(jarIn, target);
+                               logger.log(Level.TRACE, () -> "Copied source " + target);
+                       }
+
+                       // copy MANIFEST
+//                     Path manifestPath = targetBundleDir.resolve("META-INF/MANIFEST.MF");
+//                     Files.createDirectories(manifestPath.getParent());
+//                     try (OutputStream out = Files.newOutputStream(manifestPath)) {
+//                             manifest.write(out);
+//                     }
+               }
+
+       }
+
+       static void deleteDirectory(Path path) throws IOException {
+               if (!Files.exists(path))
+                       return;
+               Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
+                       @Override
+                       public FileVisitResult postVisitDirectory(Path directory, IOException e) throws IOException {
+                               if (e != null)
+                                       throw e;
+                               Files.delete(directory);
+                               return FileVisitResult.CONTINUE;
+                       }
+
+                       @Override
+                       public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
+                               Files.delete(file);
+                               return FileVisitResult.CONTINUE;
+                       }
+               });
+       }
+
+       protected NameVersion nameVersionFromManifest(Manifest manifest) {
+               Attributes attrs = manifest.getMainAttributes();
+               // symbolic name
+               String symbolicName = attrs.getValue(ManifestConstants.BUNDLE_SYMBOLICNAME.toString());
+               // make sure there is no directive
+               symbolicName = symbolicName.split(";")[0];
+
+               String version = attrs.getValue(ManifestConstants.BUNDLE_VERSION.toString());
+               return new DefaultNameVersion(symbolicName, version);
+       }
+
+       protected Path tryDownload(String uri, Path dir) throws IOException {
+               // find mirror
+               List<String> urlBases = null;
+               String uriPrefix = null;
+               uriPrefixes: for (String uriPref : mirrors.keySet()) {
+                       if (uri.startsWith(uriPref)) {
+                               if (mirrors.get(uriPref).size() > 0) {
+                                       urlBases = mirrors.get(uriPref);
+                                       uriPrefix = uriPref;
+                                       break uriPrefixes;
+                               }
+                       }
+               }
+               if (urlBases == null)
+                       try {
+                               return download(uri, dir, null);
+                       } catch (FileNotFoundException e) {
+                               throw new FileNotFoundException("Cannot find " + uri);
+                       }
+
+               // try to download
+               for (String urlBase : urlBases) {
+                       String relativePath = uri.substring(uriPrefix.length());
+                       String url = urlBase + relativePath;
+                       try {
+                               return download(url, dir, null);
+                       } catch (FileNotFoundException e) {
+                               logger.log(Level.WARNING, "Cannot download " + url + ", trying another mirror");
+                       }
+               }
+               throw new FileNotFoundException("Cannot find " + uri);
+       }
+
+//     protected String simplifyName(URL u) {
+//     String  name = u.getPath().substring(u.getPath().lastIndexOf('/') + 1);
+//             
+//     }
+
+       public Path download(String url, Path dir, String name) throws IOException {
+
+               Path dest;
+               URL u = new URL(url);
+               if (name == null) {
+                       name = u.getPath().substring(u.getPath().lastIndexOf('/') + 1);
+               }
+
+               dest = dir.resolve(name);
+               if (Files.exists(dest)) {
+                       logger.log(Level.DEBUG, () -> "File " + dest + " already exists for " + url + ", not downloading again.");
+                       return dest;
+               }
+
+               try (InputStream in = u.openStream()) {
+                       Files.copy(in, dest);
+               }
+               return dest;
+       }
+
+       public static void main(String[] args) {
+               Path originBase = Paths.get("../output/origin");
+               Path factoryBase = Paths.get("../output/a2");
+               A2Factory factory = new A2Factory(originBase, factoryBase);
+
+               Path descriptorsBase = Paths.get(System.getProperty("user.home"), "/dev/git/unstable/argeo-tp/migration");
+
+               factory.processEclipseArchive(
+                               descriptorsBase.resolve("org.argeo.tp.eclipse.equinox").resolve("eclipse-equinox"));
+               factory.processEclipseArchive(descriptorsBase.resolve("org.argeo.tp.eclipse.rap").resolve("eclipse-rap"));
+               factory.processEclipseArchive(descriptorsBase.resolve("org.argeo.tp.eclipse.rcp").resolve("eclipse-rcp"));
+       }
+}
diff --git a/org.argeo.slc.build/src/org/argeo/slc/build/bnd/BndManifestFactory.java b/org.argeo.slc.build/src/org/argeo/slc/build/bnd/BndManifestFactory.java
new file mode 100644 (file)
index 0000000..f988c9e
--- /dev/null
@@ -0,0 +1,5 @@
+package org.argeo.slc.build.bnd;
+
+public class BndManifestFactory {
+
+}
diff --git a/org.argeo.slc.build/src/org/argeo/slc/build/m2/Artifact.java b/org.argeo.slc.build/src/org/argeo/slc/build/m2/Artifact.java
new file mode 100644 (file)
index 0000000..2d485b8
--- /dev/null
@@ -0,0 +1,24 @@
+package org.argeo.slc.build.m2;
+
+public interface Artifact {
+       String getGroupId();
+
+       String getArtifactId();
+
+       String getVersion();
+
+       default String getBaseVersion() {
+               return getVersion();
+       }
+
+//     boolean isSnapshot();
+
+       default String getClassifier() {
+               return "";
+       }
+
+       default String getExtension() {
+               return "jar";
+       }
+
+}
diff --git a/org.argeo.slc.build/src/org/argeo/slc/build/m2/DefaultArtifact.java b/org.argeo.slc.build/src/org/argeo/slc/build/m2/DefaultArtifact.java
new file mode 100644 (file)
index 0000000..922a0aa
--- /dev/null
@@ -0,0 +1,17 @@
+package org.argeo.slc.build.m2;
+
+import org.argeo.slc.DefaultCategoryNameVersion;
+
+public class DefaultArtifact extends DefaultCategoryNameVersion implements Artifact {
+
+       @Override
+       public String getGroupId() {
+               return getCategory();
+       }
+
+       @Override
+       public String getArtifactId() {
+               return getName();
+       }
+
+}
diff --git a/org.argeo.slc.build/src/org/argeo/slc/build/m2/MavenConventionsUtils.java b/org.argeo.slc.build/src/org/argeo/slc/build/m2/MavenConventionsUtils.java
new file mode 100644 (file)
index 0000000..358e2ef
--- /dev/null
@@ -0,0 +1,198 @@
+package org.argeo.slc.build.m2;
+
+import java.io.File;
+import java.util.Set;
+
+/**
+ * Static utilities around Maven which are NOT using the Maven APIs (conventions
+ * based).
+ */
+public class MavenConventionsUtils {
+       /**
+        * Path to the file identified by this artifact <b>without</b> using Maven
+        * APIs (convention based). Default location of repository
+        * (~/.m2/repository) is used here.
+        * 
+        * @see MavenConventionsUtils#artifactToFile(String, Artifact)
+        */
+       public static File artifactToFile(Artifact artifact) {
+               return artifactToFile(System.getProperty("user.home") + File.separator + ".m2" + File.separator + "repository",
+                               artifact);
+       }
+
+       /**
+        * Path to the file identified by this artifact <b>without</b> using Maven
+        * APIs (convention based).
+        * 
+        * @param repositoryPath
+        *            path to the related local repository location
+        * @param artifact
+        *            the artifact
+        */
+       public static File artifactToFile(String repositoryPath, Artifact artifact) {
+               return new File(repositoryPath + File.separator + artifact.getGroupId().replace('.', File.separatorChar)
+                               + File.separator + artifact.getArtifactId() + File.separator + artifact.getVersion() + File.separator
+                               + artifactFileName(artifact)).getAbsoluteFile();
+       }
+
+       /** The file name of this artifact when stored */
+       public static String artifactFileName(Artifact artifact) {
+               return artifact.getArtifactId() + '-' + artifact.getVersion()
+                               + (artifact.getClassifier().equals("") ? "" : '-' + artifact.getClassifier()) + '.'
+                               + artifact.getExtension();
+       }
+
+       /** Absolute path to the file */
+       public static String artifactPath(String artifactBasePath, Artifact artifact) {
+               return artifactParentPath(artifactBasePath, artifact) + '/' + artifactFileName(artifact);
+       }
+
+       /** Absolute path to the file */
+       public static String artifactUrl(String repoUrl, Artifact artifact) {
+               if (repoUrl.endsWith("/"))
+                       return repoUrl + artifactPath("/", artifact).substring(1);
+               else
+                       return repoUrl + artifactPath("/", artifact);
+       }
+
+       /** Absolute path to the directories where the files will be stored */
+       public static String artifactParentPath(String artifactBasePath, Artifact artifact) {
+               return artifactBasePath + (artifactBasePath.endsWith("/") ? "" : "/") + artifactParentPath(artifact);
+       }
+
+       /** Absolute path to the directory of this group */
+       public static String groupPath(String artifactBasePath, String groupId) {
+               return artifactBasePath + (artifactBasePath.endsWith("/") ? "" : "/") + groupId.replace('.', '/');
+       }
+
+       /** Relative path to the directories where the files will be stored */
+       public static String artifactParentPath(Artifact artifact) {
+               return artifact.getGroupId().replace('.', '/') + '/' + artifact.getArtifactId() + '/'
+                               + artifact.getBaseVersion();
+       }
+
+       public static String artifactsAsDependencyPom(Artifact pomArtifact, Set<Artifact> artifacts, Artifact parent) {
+               StringBuffer p = new StringBuffer();
+
+               // XML header
+               p.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
+               p.append(
+                               "<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 http://maven.apache.org/maven-v4_0_0.xsd\">\n");
+               p.append("<modelVersion>4.0.0</modelVersion>\n");
+
+               // Artifact
+               if (parent != null) {
+                       p.append("<parent>\n");
+                       p.append("<groupId>").append(parent.getGroupId()).append("</groupId>\n");
+                       p.append("<artifactId>").append(parent.getArtifactId()).append("</artifactId>\n");
+                       p.append("<version>").append(parent.getVersion()).append("</version>\n");
+                       p.append("</parent>\n");
+               }
+               p.append("<groupId>").append(pomArtifact.getGroupId()).append("</groupId>\n");
+               p.append("<artifactId>").append(pomArtifact.getArtifactId()).append("</artifactId>\n");
+               p.append("<version>").append(pomArtifact.getVersion()).append("</version>\n");
+               p.append("<packaging>pom</packaging>\n");
+
+               // Dependencies
+               p.append("<dependencies>\n");
+               for (Artifact a : artifacts) {
+                       p.append("\t<dependency>");
+                       p.append("<artifactId>").append(a.getArtifactId()).append("</artifactId>");
+                       p.append("<groupId>").append(a.getGroupId()).append("</groupId>");
+                       if (!a.getExtension().equals("jar"))
+                               p.append("<type>").append(a.getExtension()).append("</type>");
+                       p.append("</dependency>\n");
+               }
+               p.append("</dependencies>\n");
+
+               // Dependency management
+               p.append("<dependencyManagement>\n");
+               p.append("<dependencies>\n");
+               for (Artifact a : artifacts) {
+                       p.append("\t<dependency>");
+                       p.append("<artifactId>").append(a.getArtifactId()).append("</artifactId>");
+                       p.append("<version>").append(a.getVersion()).append("</version>");
+                       p.append("<groupId>").append(a.getGroupId()).append("</groupId>");
+                       if (a.getExtension().equals("pom")) {
+                               p.append("<type>").append(a.getExtension()).append("</type>");
+                               p.append("<scope>import</scope>");
+                       }
+                       p.append("</dependency>\n");
+               }
+               p.append("</dependencies>\n");
+               p.append("</dependencyManagement>\n");
+
+               // Repositories
+               // p.append("<repositories>\n");
+               // p.append("<repository><id>argeo</id><url>http://maven.argeo.org/argeo</url></repository>\n");
+               // p.append("</repositories>\n");
+
+               p.append("</project>\n");
+               return p.toString();
+       }
+
+//     /**
+//      * Directly parses Maven POM XML format in order to find all artifacts
+//      * references under the dependency and dependencyManagement tags. This is
+//      * meant to migrate existing pom registering a lot of artifacts, not to
+//      * replace Maven resolving.
+//      */
+//     public static void gatherPomDependencies(AetherTemplate aetherTemplate, Set<Artifact> artifacts,
+//                     Artifact pomArtifact) {
+//             if (log.isDebugEnabled())
+//                     log.debug("Gather dependencies for " + pomArtifact);
+//
+//             try {
+//                     File file = aetherTemplate.getResolvedFile(pomArtifact);
+//                     DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+//                     Document doc = documentBuilder.parse(file);
+//
+//                     // properties
+//                     Properties props = new Properties();
+//                     props.setProperty("project.version", pomArtifact.getBaseVersion());
+//                     NodeList properties = doc.getElementsByTagName("properties");
+//                     if (properties.getLength() > 0) {
+//                             NodeList propertiesElems = properties.item(0).getChildNodes();
+//                             for (int i = 0; i < propertiesElems.getLength(); i++) {
+//                                     if (propertiesElems.item(i) instanceof Element) {
+//                                             Element property = (Element) propertiesElems.item(i);
+//                                             props.put(property.getNodeName(), property.getTextContent());
+//                                     }
+//                             }
+//                     }
+//
+//                     // dependencies (direct and dependencyManagement)
+//                     NodeList dependencies = doc.getElementsByTagName("dependency");
+//                     for (int i = 0; i < dependencies.getLength(); i++) {
+//                             Element dependency = (Element) dependencies.item(i);
+//                             String groupId = dependency.getElementsByTagName("groupId").item(0).getTextContent().trim();
+//                             String artifactId = dependency.getElementsByTagName("artifactId").item(0).getTextContent().trim();
+//                             String version = dependency.getElementsByTagName("version").item(0).getTextContent().trim();
+//                             if (version.startsWith("${")) {
+//                                     String versionKey = version.substring(0, version.length() - 1).substring(2);
+//                                     if (!props.containsKey(versionKey))
+//                                             throw new SlcException("Cannot interpret version " + version);
+//                                     version = props.getProperty(versionKey);
+//                             }
+//                             NodeList scopes = dependency.getElementsByTagName("scope");
+//                             if (scopes.getLength() > 0 && scopes.item(0).getTextContent().equals("import")) {
+//                                     // recurse
+//                                     gatherPomDependencies(aetherTemplate, artifacts,
+//                                                     new DefaultArtifact(groupId, artifactId, "pom", version));
+//                             } else {
+//                                     // TODO: deal with scope?
+//                                     // TODO: deal with type
+//                                     String type = "jar";
+//                                     Artifact artifact = new DefaultArtifact(groupId, artifactId, type, version);
+//                                     artifacts.add(artifact);
+//                             }
+//                     }
+//             } catch (Exception e) {
+//                     throw new SlcException("Cannot process " + pomArtifact, e);
+//             }
+//     }
+
+       /** Prevent instantiation */
+       private MavenConventionsUtils() {
+       }
+}
index 1b8366692bd1d9b6e2fbd43a77bf2b400c9d8205..5cb290c8a75b3f847e34cbe4b8a74e0e4ad22009 100644 (file)
@@ -12,69 +12,60 @@ public abstract class FreeLicense implements License {
        final static String RESOURCES = "/org/argeo/slc/repo/license/";
 
        /** GNU */
-       public final static FreeLicense GPL_v3 = new FreeLicense(
-                       "GNU General Public License, version 3.0",
-                       "http://www.gnu.org/licenses/gpl-3.0.txt",
-                       "http://www.gnu.org/licenses/", RESOURCES + "gpl-3.0.txt") {
+       public final static FreeLicense GPL_v3 = new FreeLicense("GPL-3.0-or-later",
+                       "http://www.gnu.org/licenses/gpl-3.0.txt", null, RESOURCES + "gpl-3.0.txt") {
        };
 
-       public final static FreeLicense GPL_v2 = new FreeLicense(
-                       "GNU General Public License, version 2.0",
-                       "http://www.gnu.org/licenses/gpl-2.0.txt",
-                       "http://www.gnu.org/licenses/", RESOURCES + "gpl-2.0.txt") {
+       public final static FreeLicense GPL_v2 = new FreeLicense("GPL-2.0-or-later",
+                       "http://www.gnu.org/licenses/gpl-2.0.txt", null, RESOURCES + "gpl-2.0.txt") {
        };
        public final static FreeLicense GPL = GPL_v3;
 
-       public final static FreeLicense LGPL_v3 = new FreeLicense(
-                       "GNU Lesser General Public License, version 3.0",
-                       "http://www.gnu.org/licenses/lgpl-3.0.txt",
-                       "http://www.gnu.org/licenses/", RESOURCES + "lgpl-3.0.txt") {
+       public final static FreeLicense LGPL_v3 = new FreeLicense("LGPL-3.0-or-later",
+                       "http://www.gnu.org/licenses/lgpl-3.0.txt", null, RESOURCES + "lgpl-3.0.txt") {
        };
 
-       public final static FreeLicense LGPL_v2 = new FreeLicense(
-                       "GNU Lesser General Public License, version 2.1",
-                       "http://www.gnu.org/licenses/lgpl-2.1.txt",
-                       "http://www.gnu.org/licenses/", RESOURCES + "lgpl-2.1.txt") {
+       public final static FreeLicense LGPL_v2 = new FreeLicense("LGPL-2.0-or-later",
+                       "http://www.gnu.org/licenses/lgpl-2.1.txt", null, RESOURCES + "lgpl-2.1.txt") {
        };
        public final static FreeLicense LGPL = LGPL_v3;
 
        /** Apache */
-       public final static FreeLicense APACHE_v2 = new FreeLicense(
-                       "Apache License, Version 2.0",
-                       "http://www.apache.org/licenses/LICENSE-2.0.txt",
-                       "http://www.apache.org/licenses/", RESOURCES + "apache-2.0.txt") {
+       public final static FreeLicense APACHE_v2 = new FreeLicense("Apache-2.0",
+                       "http://www.apache.org/licenses/LICENSE-2.0.txt", null, RESOURCES + "apache-2.0.txt") {
        };
        public final static FreeLicense APACHE = APACHE_v2;
 
        /** Eclipse */
-       public final static FreeLicense EPL_v1 = new FreeLicense(
-                       "Eclipse Public License, Version 1.0",
-                       "http://www.eclipse.org/legal/epl-v10.html",
-                       "http://www.eclipse.org/legal/eplfaq.php", RESOURCES
-                                       + "epl-1.0.txt") {
+       public final static FreeLicense EPL_v1 = new FreeLicense("EPL-1.0", "http://www.eclipse.org/legal/epl-v10.html",
+                       null, RESOURCES + "epl-1.0.txt") {
+       };
+       public final static FreeLicense EPL_v2 = new FreeLicense("EPL-2.0", "http://www.eclipse.org/legal/epl-v20.html",
+                       null, RESOURCES + "epl-1.0.txt") {
        };
        public final static FreeLicense EPL = EPL_v1;
 
        /** Miscellaneous */
-       public final static FreeLicense MIT = new FreeLicense("The MIT License",
-                       "http://opensource.org/licenses/MIT", null, RESOURCES + "mit.txt") {
+       public final static FreeLicense MIT = new FreeLicense("MIT", "http://opensource.org/licenses/MIT", null,
+                       RESOURCES + "mit.txt") {
        };
 
-       public final static FreeLicense BSD_NEW = new FreeLicense(
-                       "The BSD 3-Clause License",
-                       "http://opensource.org/licenses/BSD-3-Clause", null, RESOURCES
-                                       + "bsd-3-clause.txt") {
+       public final static FreeLicense BSD_NEW = new FreeLicense("BSD-3-Clause",
+                       "http://opensource.org/licenses/BSD-3-Clause", null, RESOURCES + "bsd-3-clause.txt") {
        };
 
        public final static FreeLicense BSD = BSD_NEW;
 
-       public final static FreeLicense CDDL_v1 = new FreeLicense(
-                       "Common Development and Distribution License",
-                       "http://opensource.org/licenses/CDDL-1.0", null, RESOURCES
-                                       + "cddl-1.0.txt") {
+       public final static FreeLicense CDDL_v1 = new FreeLicense("CDDL-1.0", "http://opensource.org/licenses/CDDL-1.0",
+                       null, RESOURCES + "cddl-1.0.txt") {
        };
        public final static FreeLicense CDDL = CDDL_v1;
 
+       public final static FreeLicense MOZILLA_v2 = new FreeLicense("MPL-2.0", "https://opensource.org/licenses/MPL-2.0",
+                       null, RESOURCES + "cddl-1.0.txt") {
+       };
+       public final static FreeLicense MOZILLA = MOZILLA_v2;
+
        /** Public domain corner case */
        public final static License PUBLIC_DOMAIN = new License() {
 
@@ -140,8 +131,7 @@ public abstract class FreeLicense implements License {
                        String text = IOUtils.toString(in);
                        return text;
                } catch (Exception e) {
-                       throw new SlcException("Cannot retrieve license " + name + " from "
-                                       + url, e);
+                       throw new SlcException("Cannot retrieve license " + name + " from " + url, e);
                } finally {
                        IOUtils.closeQuietly(in);
                }
@@ -161,6 +151,11 @@ public abstract class FreeLicense implements License {
 
        @Override
        public String toString() {
-               return name + " (" + uri + ")";
+               StringBuilder sb = new StringBuilder(name != null ? name : uri);
+//             if (link != null)
+//                     sb.append(';').append("link=").append(link);
+//             else if (uri != null && name != null)
+//                     sb.append(';').append("link=").append(uri);
+               return sb.toString();
        }
 }
index 3d6adcd7b1f63df0ce33310f696e129528d6d5c3..dbfd576b4d999deb130ec520972874f582803161 100644 (file)
@@ -1,5 +1,8 @@
 package org.argeo.slc.repo.osgi;
 
+import static org.argeo.slc.ManifestConstants.SLC_ORIGIN_M2;
+import static org.argeo.slc.ManifestConstants.SLC_ORIGIN_URI;
+
 import java.io.IOException;
 import java.io.Writer;
 import java.nio.file.Files;
@@ -17,12 +20,14 @@ import java.util.TreeSet;
 
 import org.argeo.api.cms.CmsLog;
 import org.argeo.slc.CategoryNameVersion;
+import org.argeo.slc.ManifestConstants;
 import org.argeo.slc.ModuleSet;
 import org.argeo.slc.NameVersion;
 import org.argeo.slc.build.Distribution;
 import org.argeo.slc.execution.ExecutionFlow;
 import org.argeo.slc.repo.ArgeoOsgiDistribution;
 import org.argeo.slc.repo.ArtifactDistribution;
+import org.argeo.slc.repo.FreeLicense;
 import org.eclipse.aether.artifact.Artifact;
 import org.eclipse.aether.artifact.DefaultArtifact;
 import org.osgi.framework.Constants;
@@ -42,7 +47,7 @@ public class ArgeoOsgiDistributionImpl extends ArtifactDistribution implements A
        public void init() {
                if (log.isDebugEnabled())
                        log.debug(describe());
-               migrateTov2(Paths.get(System.getProperty("user.home"), "dev/git/unstable/argeo-tp/argeo-tp"));
+               migrateTov2(Paths.get(System.getProperty("user.home"), "dev/git/unstable/argeo-tp/migration"));
        }
 
        public void destroy() {
@@ -100,14 +105,14 @@ public class ArgeoOsgiDistributionImpl extends ArtifactDistribution implements A
                                                else
                                                        log.warn("No license for " + cnv);
                                                if (bw.getDoNotModify()) {
-                                                       props.put("SLC-Source-Original", "true");
+                                                       props.put(ManifestConstants.SLC_ORIGIN_MANIFEST_NOT_MODIFIED.toString(), "true");
                                                }
                                                // props.put("SLC-Category", cnv.getCategory());
 
                                                if (cnv instanceof MavenWrapper) {
                                                        MavenWrapper mw = (MavenWrapper) cnv;
                                                        String sourceCoords = mw.getSourceCoords();
-                                                       props.put("SLC-Source-M2", sourceCoords);
+                                                       props.put(SLC_ORIGIN_M2.toString(), sourceCoords);
                                                        Artifact mavenCnv = new DefaultArtifact(sourceCoords);
                                                        if (mavenCnv.getArtifactId().equals(cnv.getName()))
                                                                props.remove(Constants.BUNDLE_SYMBOLICNAME);
@@ -115,11 +120,11 @@ public class ArgeoOsgiDistributionImpl extends ArtifactDistribution implements A
                                                                props.remove(Constants.BUNDLE_VERSION);
                                                } else if (cnv instanceof UriWrapper) {
                                                        UriWrapper mw = (UriWrapper) cnv;
-                                                       props.put("SLC-Source-URI", mw.getEffectiveUri());
+                                                       props.put(SLC_ORIGIN_URI.toString(), mw.getEffectiveUri());
                                                        if (mw.getUri() == null && mw.getBaseUri() != null) {
                                                                log.warn("Base URI for " + cnv);
-                                                               props.put("SLC-Source-BaseURI", mw.getBaseUri());
-                                                               props.put("SLC-Source-VersionSeparator", mw.getVersionSeparator());
+                                                               props.put("SLC-Origin-BaseURI", mw.getBaseUri());
+                                                               props.put("SLC-Origin-VersionSeparator", mw.getVersionSeparator());
                                                        }
                                                } else {
                                                        log.warn("Unidentified BND wrapper " + cnv);
@@ -160,6 +165,62 @@ public class ArgeoOsgiDistributionImpl extends ArtifactDistribution implements A
                                log.debug(" includes: " + aw.getIncludes());
                                log.debug(" excludes: " + aw.getExcludes());
                                log.debug(" beans   : " + aw.getWrappers());
+
+                               String uri = aw.getUri();
+                               String duName = null;
+                               String category = null;
+                               String oldCategory = null;
+                               if (uri.startsWith("http://www.eclipse.org/downloads/rt/rap/3.10/e4/rap-e4")) {
+                                       duName = "eclipse-rap";
+                                       category = "org.argeo.tp.eclipse.rap";
+                                       oldCategory = "org.argeo.tp.rap.e4";
+                               } else if (uri.startsWith("http://www.eclipse.org/downloads/equinox/")) {
+                                       duName = "eclipse-equinox";
+                                       category = "org.argeo.tp.eclipse.equinox";
+                                       oldCategory = "org.argeo.tp.equinox";
+                               } else if (uri.startsWith("http://www.eclipse.org/downloads/eclipse/downloads/drops4")) {
+                                       duName = "eclipse-rcp";
+                                       category = "org.argeo.tp.eclipse.rcp";
+                                       oldCategory = "org.argeo.tp.rcp.e4";
+                               }
+
+                               if (duName != null) {
+                                       try {
+                                               Path duDir = baseDir.resolve(category).resolve(duName);
+                                               Files.createDirectories(duDir);
+                                               Path bndPath = duDir.resolve("common.bnd");
+                                               Path includesPath = duDir.resolve("includes.properties");
+
+                                               Map<String, String> props = new TreeMap<>();
+                                               props.put(ManifestConstants.SLC_ORIGIN_URI.toString(), aw.getUri());
+                                               props.put(ManifestConstants.SLC_ORIGIN_MANIFEST_NOT_MODIFIED.toString(), "true");
+                                               props.put(Constants.BUNDLE_LICENSE, FreeLicense.EPL.toString());
+                                               // write BND file
+                                               try (Writer bndWriter = Files.newBufferedWriter(bndPath);
+                                                               Writer includesWriter = Files.newBufferedWriter(includesPath);) {
+                                                       // writer.write("# " + cnv + "\n");
+                                                       props: for (String key : props.keySet()) {
+                                                               String value = props.get(key);
+                                                               if (Constants.EXPORT_PACKAGE.equals(key) && "*".equals(value.trim()))
+                                                                       continue props;
+
+                                                               bndWriter.write(key + ": " + value + '\n');
+                                                       }
+
+                                                       for (String key : aw.getIncludes().keySet()) {
+                                                               String value = aw.getIncludes().get(key);
+                                                               if (value.equals(oldCategory))
+                                                                       value = category;
+                                                               includesWriter.write(key + "=" + value + '\n');
+                                                       }
+                                                       if (log.isTraceEnabled())
+                                                               log.trace("Wrote " + bndPath);
+                                               }
+                                       } catch (IOException e) {
+                                               log.error("Could not process " + aw, e);
+                                       }
+
+                               }
                        }
                }
 
index efd1591cd12206dbd93ec15f0e51e77853af4b9c..57d7a81d2cbb968be5a7a7e31526156bf5a481b3 100644 (file)
@@ -86,12 +86,7 @@ public class BndWrapper implements Constants, CategoryNameVersion, Distribution
 
                                // License
                                if (license != null) {
-                                       StringBuilder sb = new StringBuilder(license.getUri());
-                                       if (license.getName() != null)
-                                               sb.append(';').append("description=").append(license.getName());
-                                       if (license.getLink() != null)
-                                               sb.append(';').append("link=").append(license.getLink());
-                                       properties.setProperty(BUNDLE_LICENSE, sb.toString());
+                                       properties.setProperty(BUNDLE_LICENSE, license.toString());
                                        // TODO add LICENSE.TXT
                                } else {
                                        log.warn("No license set for " + toString());
diff --git a/sdk/includes.mk b/sdk/includes.mk
new file mode 100644 (file)
index 0000000..e69de29