**/target/
**/generated/
**/MANIFEST.MF
+/sdk.mk
+/output/
--- /dev/null
+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)))
+
--- /dev/null
+MAJOR=2
+MINOR=3
--- /dev/null
+#!/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
+
--- /dev/null
+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;
+ }
+
+}
*/
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];
+ }
}
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .
+additional.bundles = org.argeo.init
--- /dev/null
+package org.argeo.slc.build;
+
+import org.argeo.slc.DefaultCategoryNameVersion;
+
+public class A2DistributionUnit extends DefaultCategoryNameVersion {
+ private String originVersion;
+
+
+}
--- /dev/null
+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"));
+ }
+}
--- /dev/null
+package org.argeo.slc.build.bnd;
+
+public class BndManifestFactory {
+
+}
--- /dev/null
+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";
+ }
+
+}
--- /dev/null
+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();
+ }
+
+}
--- /dev/null
+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() {
+ }
+}
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() {
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);
}
@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();
}
}
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;
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;
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() {
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);
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);
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);
+ }
+
+ }
}
}
// 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());