From: Mathieu Baudier Date: Tue, 17 Sep 2013 08:20:35 +0000 (+0000) Subject: Generalize ArchiveWrapper and deprecates ImportBundlesZip X-Git-Tag: argeo-slc-2.1.7~314 X-Git-Url: http://git.argeo.org/?a=commitdiff_plain;h=1f0e95374536f1e521eb7b29a6704c1a9d79b94c;p=gpl%2Fargeo-slc.git Generalize ArchiveWrapper and deprecates ImportBundlesZip git-svn-id: https://svn.argeo.org/slc/trunk@6486 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- diff --git a/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/RepoConstants.java b/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/RepoConstants.java index 9ec9c43e9..7a81e7102 100644 --- a/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/RepoConstants.java +++ b/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/RepoConstants.java @@ -28,4 +28,7 @@ public interface RepoConstants { + "/slc:distributions"; public final static String REPOSITORIES_BASE_PATH = REPO_BASEPATH + "/slc:repositories"; + public final static String BINARIES_ARTIFACT_ID = "binaries"; + public final static String SOURCES_ARTIFACT_ID = "sources"; + public final static String SDK_ARTIFACT_ID = "sdk"; } diff --git a/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/RepoUtils.java b/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/RepoUtils.java index f00c910a4..5f798c144 100644 --- a/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/RepoUtils.java +++ b/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/RepoUtils.java @@ -23,7 +23,9 @@ import java.io.InputStream; import java.io.OutputStream; import java.util.Enumeration; import java.util.Iterator; +import java.util.Set; import java.util.StringTokenizer; +import java.util.TreeSet; import java.util.jar.Attributes; import java.util.jar.JarEntry; import java.util.jar.JarFile; @@ -40,6 +42,7 @@ import javax.jcr.PropertyIterator; import javax.jcr.Repository; import javax.jcr.RepositoryException; import javax.jcr.RepositoryFactory; +import javax.jcr.Session; import javax.jcr.SimpleCredentials; import javax.jcr.nodetype.NodeType; @@ -51,9 +54,10 @@ import org.argeo.jcr.ArgeoJcrUtils; import org.argeo.jcr.ArgeoNames; import org.argeo.jcr.ArgeoTypes; import org.argeo.jcr.JcrUtils; -import org.argeo.slc.BasicNameVersion; +import org.argeo.slc.DefaultNameVersion; import org.argeo.slc.NameVersion; import org.argeo.slc.SlcException; +import org.argeo.slc.aether.ArtifactIdComparator; import org.argeo.slc.jcr.SlcNames; import org.argeo.slc.jcr.SlcTypes; import org.argeo.slc.repo.maven.MavenConventionsUtils; @@ -269,7 +273,7 @@ public class RepoUtils implements ArgeoNames, SlcNames { /** Read the OSGi {@link NameVersion} */ public static NameVersion readNameVersion(Manifest manifest) { - BasicNameVersion nameVersion = new BasicNameVersion(); + DefaultNameVersion nameVersion = new DefaultNameVersion(); nameVersion.setName(manifest.getMainAttributes().getValue( Constants.BUNDLE_SYMBOLICNAME)); @@ -413,6 +417,61 @@ public class RepoUtils implements ArgeoNames, SlcNames { } } + /** + * Write group indexes: 'binaries' lists all bundles and their versions, + * 'sources' list theire sources, and 'sdk' aggregates both. + */ + public static void writeGroupIndexes(Session session, + String artifactBasePath, String groupId, String version, + Set binaries, Set sources) { + try { + Set indexes = new TreeSet( + new ArtifactIdComparator()); + Artifact binariesArtifact = writeIndex(session, artifactBasePath, + groupId, RepoConstants.BINARIES_ARTIFACT_ID, version, + binaries); + indexes.add(binariesArtifact); + if (sources != null) { + Artifact sourcesArtifact = writeIndex(session, + artifactBasePath, groupId, + RepoConstants.SOURCES_ARTIFACT_ID, version, sources); + indexes.add(sourcesArtifact); + } + // sdk + writeIndex(session, artifactBasePath, groupId, + RepoConstants.SDK_ARTIFACT_ID, version, indexes); + session.save(); + } catch (RepositoryException e) { + throw new SlcException("Cannot write indexes for group " + groupId, + e); + } + } + + /** Write a group index. */ + private static Artifact writeIndex(Session session, + String artifactBasePath, String groupId, String artifactId, + String version, Set artifacts) throws RepositoryException { + Artifact artifact = new DefaultArtifact(groupId, artifactId, "pom", + version); + String pom = MavenConventionsUtils.artifactsAsDependencyPom(artifact, + artifacts, null); + Node node = RepoUtils.copyBytesAsArtifact( + session.getNode(artifactBasePath), artifact, pom.getBytes()); + addMavenChecksums(node); + return artifact; + } + + /** Add files containing the SHA-1 and MD5 checksums. */ + public static void addMavenChecksums(Node node) throws RepositoryException { + // TODO optimize + String sha = JcrUtils.checksumFile(node, "SHA-1"); + JcrUtils.copyBytesAsFile(node.getParent(), node.getName() + ".sha1", + sha.getBytes()); + String md5 = JcrUtils.checksumFile(node, "MD5"); + JcrUtils.copyBytesAsFile(node.getParent(), node.getName() + ".md5", + md5.getBytes()); + } + /** * Custom copy since the one in commons does not fit the needs when copying * a workspace completely. diff --git a/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/osgi/ArchiveWrapper.java b/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/osgi/ArchiveWrapper.java index 843951843..8d1cee58d 100644 --- a/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/osgi/ArchiveWrapper.java +++ b/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/osgi/ArchiveWrapper.java @@ -2,42 +2,65 @@ package org.argeo.slc.repo.osgi; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; +import java.util.Set; +import java.util.TreeSet; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import javax.jcr.Node; import javax.jcr.Property; +import javax.jcr.RepositoryException; import javax.jcr.Session; import org.apache.commons.io.IOUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.argeo.jcr.JcrUtils; +import org.argeo.slc.NameVersion; import org.argeo.slc.SlcException; +import org.argeo.slc.aether.ArtifactIdComparator; import org.argeo.slc.repo.OsgiFactory; import org.argeo.slc.repo.RepoUtils; import org.sonatype.aether.artifact.Artifact; - -/** Download a software distribution and generates the related OSGi bundles. */ +import org.sonatype.aether.util.artifact.DefaultArtifact; +import org.springframework.util.AntPathMatcher; +import org.springframework.util.PathMatcher; + +/** + * Download a software distribution and generates the related OSGi bundles from + * the jars, or import them directly if they are already OSGi bundles and don't + * need further modification. + */ public class ArchiveWrapper implements Runnable { private final static Log log = LogFactory.getLog(ArchiveWrapper.class); private OsgiFactory osgiFactory; - private String version; - // private String groupId; - + private String uri; - + private List fallbackUris = new ArrayList(); + + // jars to wrap as OSGi bundles private Map wrappers = new HashMap(); + // pattern of OSGi bundles to import + private PathMatcher pathMatcher = new AntPathMatcher(); + private Map includes = new HashMap(); + private List excludes = new ArrayList(); + + private Boolean mavenGroupIndexes = false; + public void init() { - for (BndWrapper wrapper : wrappers.values()) { - if (wrapper.getVersion() == null) - wrapper.setVersion(version); - } + if (version != null) + for (BndWrapper wrapper : wrappers.values()) { + if (wrapper.getVersion() == null) + wrapper.setVersion(version); + } } public void destroy() { @@ -45,6 +68,12 @@ public class ArchiveWrapper implements Runnable { } public void run() { + if (mavenGroupIndexes && (version == null)) + throw new SlcException( + "'mavenGroupIndexes' requires 'version' to be set"); + + Map> binaries = new HashMap>(); + Map> sources = new HashMap>(); Session distSession = null; Session javaSession = null; @@ -61,40 +90,45 @@ public class ArchiveWrapper implements Runnable { .getProperty(Property.JCR_DATA).getBinary().getStream()); ZipEntry zentry = null; - ByteArrayOutputStream out = null; - ByteArrayInputStream in = null; - while ((zentry = zin.getNextEntry()) != null) { - try { - String name = zentry.getName(); - // if (log.isDebugEnabled()) - // log.debug("Scanning " + name); - if (wrappers.containsKey(name)) { - - BndWrapper wrapper = (BndWrapper) wrappers.get(name); - // if (wrapper.getVersion() == null) - // wrapper.setVersion(version);// FIXME stateful? - - out = new ByteArrayOutputStream((int) zentry.getSize()); - // we must copy since the stream is closed by BND - byte[] sourceJarBytes = IOUtils.toByteArray(zin); - in = new ByteArrayInputStream(sourceJarBytes); - wrapper.wrapJar(in, out); - - Artifact newArtifact = wrapper.getArtifact(); - Node newJarNode = RepoUtils.copyBytesAsArtifact( - javaSession.getRootNode(), newArtifact, - out.toByteArray()); - osgiFactory.indexNode(newJarNode); - newJarNode.getSession().save(); - if (log.isDebugEnabled()) - log.debug("Wrapped " + name + " to " - + newJarNode.getPath()); + entries: while ((zentry = zin.getNextEntry()) != null) { + String name = zentry.getName(); + if (wrappers.containsKey(name)) { + BndWrapper wrapper = (BndWrapper) wrappers.get(name); + // we must copy since the stream is closed by BND + byte[] sourceJarBytes = IOUtils.toByteArray(zin); + Artifact artifact = wrapZipEntry(javaSession, zentry, + sourceJarBytes, wrapper); + addArtifactToIndex(binaries, wrapper.getGroupId(), artifact); + } else { + for (String exclude : excludes) + if (pathMatcher.match(exclude, name)) + continue entries; + + for (String include : includes.keySet()) { + if (pathMatcher.match(include, name)) { + String groupId = includes.get(include); + byte[] sourceJarBytes = IOUtils.toByteArray(zin); + Artifact artifact = importZipEntry(javaSession, + zentry, sourceJarBytes, groupId); + if (artifact.getArtifactId().endsWith(".source")) + addArtifactToIndex(sources, groupId, artifact); + else + addArtifactToIndex(binaries, groupId, artifact); + } } - } finally { - IOUtils.closeQuietly(out); - IOUtils.closeQuietly(in); } } + + // indexes + if (mavenGroupIndexes && version != null) { + for (String groupId : binaries.keySet()) { + RepoUtils.writeGroupIndexes(javaSession, "/", groupId, + version, binaries.get(groupId), + sources.containsKey(groupId) ? sources.get(groupId) + : null); + } + } + } catch (Exception e) { throw new SlcException("Cannot wrap distribution " + uri, e); } finally { @@ -104,15 +138,61 @@ public class ArchiveWrapper implements Runnable { } } - // public List provides() { - // List res = new ArrayList(); - // for (BndWrapper bndWrapper : wrappers.values()) { - // ArtifactDistribution ad = new ArtifactDistribution(groupId + ":" - // + bndWrapper.getName() + ":" + bndWrapper.getVersion()); - // res.add(ad); - // } - // return res; - // } + protected Artifact wrapZipEntry(Session javaSession, ZipEntry zentry, + byte[] sourceJarBytes, BndWrapper wrapper) + throws RepositoryException { + ByteArrayOutputStream out = null; + ByteArrayInputStream in = null; + Node newJarNode; + try { + out = new ByteArrayOutputStream((int) zentry.getSize()); + in = new ByteArrayInputStream(sourceJarBytes); + wrapper.wrapJar(in, out); + + Artifact artifact = wrapper.getArtifact(); + newJarNode = RepoUtils.copyBytesAsArtifact( + javaSession.getRootNode(), artifact, out.toByteArray()); + osgiFactory.indexNode(newJarNode); + newJarNode.getSession().save(); + if (log.isDebugEnabled()) + log.debug("Wrapped jar " + zentry.getName() + " to " + + newJarNode.getPath()); + return artifact; + } finally { + IOUtils.closeQuietly(in); + IOUtils.closeQuietly(out); + } + } + + protected Artifact importZipEntry(Session javaSession, ZipEntry zentry, + byte[] sourceJarBytes, String groupId) throws RepositoryException { + ByteArrayInputStream in = null; + Node newJarNode; + try { + in = new ByteArrayInputStream(sourceJarBytes); + NameVersion nameVersion = RepoUtils.readNameVersion(in); + Artifact artifact = new DefaultArtifact(groupId, + nameVersion.getName(), "jar", nameVersion.getVersion()); + newJarNode = RepoUtils.copyBytesAsArtifact( + javaSession.getRootNode(), artifact, sourceJarBytes); + osgiFactory.indexNode(newJarNode); + newJarNode.getSession().save(); + if (log.isDebugEnabled()) + log.debug("Imported OSGi bundle " + zentry.getName() + " to " + + newJarNode.getPath()); + return artifact; + } finally { + IOUtils.closeQuietly(in); + } + } + + private void addArtifactToIndex(Map> index, + String groupId, Artifact artifact) { + if (!index.containsKey(groupId)) + index.put(groupId, + new TreeSet(new ArtifactIdComparator())); + index.get(groupId).add(artifact); + } public void setUri(String uri) { this.uri = uri; @@ -130,4 +210,20 @@ public class ArchiveWrapper implements Runnable { this.version = version; } + public void setPathMatcher(PathMatcher pathMatcher) { + this.pathMatcher = pathMatcher; + } + + public void setIncludes(Map includes) { + this.includes = includes; + } + + public void setExcludes(List excludes) { + this.excludes = excludes; + } + + public void setMavenGroupIndexes(Boolean mavenGroupIndexes) { + this.mavenGroupIndexes = mavenGroupIndexes; + } + } diff --git a/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/osgi/BndWrapper.java b/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/osgi/BndWrapper.java index f03a4d74b..00679e2c6 100644 --- a/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/osgi/BndWrapper.java +++ b/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/osgi/BndWrapper.java @@ -22,7 +22,7 @@ import aQute.lib.osgi.Builder; import aQute.lib.osgi.Constants; import aQute.lib.osgi.Jar; -/** Utilities around the BND library, which manipulates OSI meta-data. */ +/** Utilities around the BND library, which manipulates OSGi metadata. */ public class BndWrapper implements Constants, NameVersion, BeanNameAware { private final static Log log = LogFactory.getLog(BndWrapper.class); diff --git a/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/osgi/ImportBundlesZip.java b/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/osgi/ImportBundlesZip.java index 7d25cef8c..80574f8f6 100644 --- a/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/osgi/ImportBundlesZip.java +++ b/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/osgi/ImportBundlesZip.java @@ -43,7 +43,10 @@ import org.sonatype.aether.util.artifact.DefaultArtifact; /** * Import all bundles in a zip file (typically an Eclipse distribution) into the * workspace. + * + * @deprecated Use {@link ArchiveWrapper} instead. */ +@Deprecated public class ImportBundlesZip implements Runnable { private final static Log log = LogFactory.getLog(ImportBundlesZip.class); private Repository repository; @@ -100,8 +103,8 @@ public class ImportBundlesZip implements Runnable { continue entries; } - String bundleName = RepoUtils.extractBundleNameFromSourceName(nv - .getName()); + String bundleName = RepoUtils + .extractBundleNameFromSourceName(nv.getName()); // skip excluded bundles and their sources if (excludedBundles.contains(bundleName)) continue entries; diff --git a/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/osgi/NormalizeGroup.java b/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/osgi/NormalizeGroup.java index bc228285a..58f832c0a 100644 --- a/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/osgi/NormalizeGroup.java +++ b/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/osgi/NormalizeGroup.java @@ -38,6 +38,7 @@ import org.argeo.slc.aether.ArtifactIdComparator; import org.argeo.slc.jcr.SlcNames; import org.argeo.slc.jcr.SlcTypes; import org.argeo.slc.repo.ArtifactIndexer; +import org.argeo.slc.repo.RepoConstants; import org.argeo.slc.repo.RepoUtils; import org.argeo.slc.repo.maven.MavenConventionsUtils; import org.osgi.framework.Constants; @@ -50,10 +51,6 @@ import org.sonatype.aether.util.artifact.DefaultArtifact; * group of OSGi bundles. */ public class NormalizeGroup implements Runnable, SlcNames { - public final static String BINARIES_ARTIFACT_ID = "binaries"; - public final static String SOURCES_ARTIFACT_ID = "sources"; - public final static String SDK_ARTIFACT_ID = "sdk"; - private final static Log log = LogFactory.getLog(NormalizeGroup.class); private Repository repository; @@ -190,13 +187,13 @@ public class NormalizeGroup implements Runnable, SlcNames { // indexes Set indexes = new TreeSet( new ArtifactIdComparator()); - Artifact indexArtifact = writeIndex(session, BINARIES_ARTIFACT_ID, + Artifact indexArtifact = writeIndex(session, RepoConstants.BINARIES_ARTIFACT_ID, binaries); indexes.add(indexArtifact); - indexArtifact = writeIndex(session, SOURCES_ARTIFACT_ID, sources); + indexArtifact = writeIndex(session, RepoConstants.SOURCES_ARTIFACT_ID, sources); indexes.add(indexArtifact); // sdk - writeIndex(session, SDK_ARTIFACT_ID, indexes); + writeIndex(session, RepoConstants.SDK_ARTIFACT_ID, indexes); if (monitor != null) monitor.worked(1); } @@ -405,8 +402,8 @@ public class NormalizeGroup implements Runnable, SlcNames { p.append("\n"); p.append("\t").append(groupId).append("\n"); p.append("\t") - .append(ownSymbolicName.endsWith(".source") ? SOURCES_ARTIFACT_ID - : BINARIES_ARTIFACT_ID).append("\n"); + .append(ownSymbolicName.endsWith(".source") ? RepoConstants.SOURCES_ARTIFACT_ID + : RepoConstants.BINARIES_ARTIFACT_ID).append("\n"); p.append("\t").append(version).append("\n"); p.append("\tpom\n"); p.append("\timport\n");