From 418a82cb85b477af9f2b8d850ca14c8512546643 Mon Sep 17 00:00:00 2001 From: Mathieu Baudier Date: Wed, 9 May 2012 09:37:10 +0000 Subject: [PATCH] MIgrate binaries to target workspace git-svn-id: https://svn.argeo.org/slc/trunk@5296 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- .../java/org/argeo/slc/repo/RepoUtils.java | 69 +++++++- .../repo/maven/ImportMavenDependencies.java | 26 +-- .../argeo/slc/repo/maven/Migration_01_03.java | 160 +++++++++++++----- 3 files changed, 196 insertions(+), 59 deletions(-) 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 17f9fd643..80569b159 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 @@ -1,5 +1,6 @@ package org.argeo.slc.repo; +import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; @@ -15,16 +16,23 @@ import java.util.jar.JarInputStream; import java.util.jar.JarOutputStream; import java.util.jar.Manifest; +import javax.jcr.Node; +import javax.jcr.RepositoryException; + import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.argeo.slc.BasicNameVersion; import org.argeo.slc.NameVersion; +import org.argeo.slc.SlcException; +import org.argeo.slc.jcr.SlcNames; +import org.argeo.slc.jcr.SlcTypes; import org.sonatype.aether.artifact.Artifact; +import org.sonatype.aether.util.artifact.DefaultArtifact; /** Utilities around repo */ -public class RepoUtils { +public class RepoUtils implements SlcNames { private final static Log log = LogFactory.getLog(RepoUtils.class); /** Packages a regular sources jar as PDE source. */ @@ -127,6 +135,41 @@ public class RepoUtils { } } + /** Copy a jar changing onlythe manifest */ + public static void copyJar(InputStream in, OutputStream out, + Manifest manifest) { + JarInputStream jarIn = null; + JarOutputStream jarOut = null; + try { + jarIn = new JarInputStream(in); + jarOut = new JarOutputStream(out, manifest); + JarEntry jarEntry = null; + while ((jarEntry = jarIn.getNextJarEntry()) != null) { + jarOut.putNextEntry(jarEntry); + IOUtils.copy(jarIn, jarOut); + jarIn.closeEntry(); + jarOut.closeEntry(); + } + } catch (IOException e) { + throw new SlcException("Could not copy jar with MANIFEST " + + manifest.getMainAttributes(), e); + } finally { + IOUtils.closeQuietly(jarIn); + IOUtils.closeQuietly(jarOut); + } + } + + /** Reads a jar file, modify its manifest */ + public static byte[] modifyManifest(InputStream in, Manifest manifest) { + ByteArrayOutputStream out = new ByteArrayOutputStream(200 * 1024); + try { + copyJar(in, out, manifest); + return out.toByteArray(); + } finally { + IOUtils.closeQuietly(out); + } + } + /** Read the OSGi {@link NameVersion} */ public static NameVersion readNameVersion(Artifact artifact) { File artifactFile = artifact.getFile(); @@ -177,6 +220,30 @@ public class RepoUtils { return null; } + /* + * DATA MODEL + */ + /** The artifact described by this node */ + public static Artifact asArtifact(Node node) throws RepositoryException { + if (node.isNodeType(SlcTypes.SLC_ARTIFACT_VERSION_BASE)) { + // FIXME update data model to store packaging at this level + String extension = "jar"; + return new DefaultArtifact(node.getProperty(SLC_GROUP_ID) + .getString(), + node.getProperty(SLC_ARTIFACT_ID).getString(), extension, + node.getProperty(SLC_ARTIFACT_VERSION).getString()); + } else if (node.isNodeType(SlcTypes.SLC_ARTIFACT)) { + return new DefaultArtifact(node.getProperty(SLC_GROUP_ID) + .getString(), + node.getProperty(SLC_ARTIFACT_ID).getString(), node + .getProperty(SLC_ARTIFACT_CLASSIFIER).getString(), + node.getProperty(SLC_ARTIFACT_EXTENSION).getString(), node + .getProperty(SLC_ARTIFACT_VERSION).getString()); + } else { + throw new SlcException("Unsupported node type for " + node); + } + } + private RepoUtils() { } } diff --git a/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/maven/ImportMavenDependencies.java b/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/maven/ImportMavenDependencies.java index bde774526..0bda72b7e 100644 --- a/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/maven/ImportMavenDependencies.java +++ b/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/maven/ImportMavenDependencies.java @@ -91,6 +91,8 @@ public class ImportMavenDependencies implements Runnable { node.remove(); } session.save(); + + // sync syncDistribution(session, artifacts); } catch (Exception e) { throw new SlcException("Cannot import distribution", e); @@ -186,8 +188,7 @@ public class ImportMavenDependencies implements Runnable { artifactComparator); Long begin = System.currentTimeMillis(); try { - JcrUtils.mkdirs(jcrSession, artifactBasePath, NodeType.NT_FOLDER, - NodeType.NT_FOLDER, false); + JcrUtils.mkfolders(jcrSession, artifactBasePath); artifacts: for (Artifact artifact : artifacts) { // skip excluded if (excludedArtifacts.contains(artifact.getGroupId() + ":" @@ -210,8 +211,7 @@ public class ImportMavenDependencies implements Runnable { .artifactParentPath(artifactBasePath, artifact); Node parentNode; if (!jcrSession.itemExists(parentPath)) - parentNode = JcrUtils.mkdirs(jcrSession, parentPath, - NodeType.NT_FOLDER, NodeType.NT_FOLDER, false); + parentNode = JcrUtils.mkfolders(jcrSession, parentPath); else parentNode = jcrSession.getNode(parentPath); @@ -263,7 +263,7 @@ public class ImportMavenDependencies implements Runnable { Artifact origSourceArtifact = new DefaultArtifact( artifact.getGroupId(), artifact.getArtifactId(), "sources", artifact.getExtension(), artifact.getVersion()); - Artifact targetSourceArtifact = new DefaultArtifact( + Artifact newSourceArtifact = new DefaultArtifact( artifact.getGroupId(), artifact.getArtifactId() + ".source", artifact.getExtension(), artifact.getVersion()); @@ -272,22 +272,22 @@ public class ImportMavenDependencies implements Runnable { .getResolvedFile(origSourceArtifact); } catch (Exception e) { // also try artifact following the conventions - origSourceArtifact = targetSourceArtifact; + origSourceArtifact = newSourceArtifact; origSourceFile = aetherTemplate .getResolvedFile(origSourceArtifact); } - String sourceParentPath = MavenConventionsUtils.artifactParentPath( - artifactBasePath, targetSourceArtifact); - Node sourceParentNode = JcrUtils.mkdirs(session, sourceParentPath, - NodeType.NT_FOLDER); + String newSourceParentPath = MavenConventionsUtils + .artifactParentPath(artifactBasePath, newSourceArtifact); + Node newSourceParentNode = JcrUtils.mkfolders(session, + newSourceParentPath); NameVersion bundleNameVersion = RepoUtils .readNameVersion(artifactFile); RepoUtils.packagesAsPdeSource(origSourceFile, bundleNameVersion, out); - String targetSourceFileName = MavenConventionsUtils - .artifactFileName(targetSourceArtifact); - JcrUtils.copyBytesAsFile(sourceParentNode, targetSourceFileName, + String newSourceFileName = MavenConventionsUtils + .artifactFileName(newSourceArtifact); + JcrUtils.copyBytesAsFile(newSourceParentNode, newSourceFileName, out.toByteArray()); } catch (Exception e) { log.error("Cannot add PDE source for " + artifact + ": " + e); diff --git a/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/maven/Migration_01_03.java b/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/maven/Migration_01_03.java index 27207118d..b93831cc1 100644 --- a/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/maven/Migration_01_03.java +++ b/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/maven/Migration_01_03.java @@ -3,14 +3,17 @@ package org.argeo.slc.repo.maven; import java.io.IOException; import java.util.Arrays; import java.util.List; +import java.util.jar.Attributes.Name; import java.util.jar.Manifest; import javax.jcr.Binary; import javax.jcr.Node; import javax.jcr.NodeIterator; +import javax.jcr.Property; import javax.jcr.Repository; import javax.jcr.RepositoryException; import javax.jcr.Session; +import javax.jcr.nodetype.NodeType; import javax.jcr.query.QueryManager; import javax.jcr.query.QueryResult; import javax.jcr.query.qom.Ordering; @@ -24,31 +27,42 @@ import org.argeo.jcr.JcrUtils; import org.argeo.slc.SlcException; import org.argeo.slc.jcr.SlcNames; import org.argeo.slc.jcr.SlcTypes; +import org.argeo.slc.repo.ArtifactIndexer; +import org.argeo.slc.repo.JarFileIndexer; +import org.argeo.slc.repo.RepoUtils; import org.osgi.framework.Constants; +import org.sonatype.aether.artifact.Artifact; +import org.sonatype.aether.util.artifact.DefaultArtifact; /** * Migrate the distribution from 1.2 to 1.4 by cleaning naming and dependencies. * The dependency to the SpringSource Enterprise Bundle repository is removed as - * well as theire naming convention. All third party are move to org.argeo.tp + * well as their naming conventions. All third party are move to org.argeo.tp * group IDs. Maven dependency for Eclipse artifacts don't use version ranges * anymore. Verison constraints on javax.* packages are removed (since they lead * to "use package conflicts" when Eclipse and Spring Security are used * together). */ public class Migration_01_03 implements Runnable, SlcNames { + final String SPRING_SOURCE_PREFIX = "com.springsource"; private final static Log log = LogFactory.getLog(Migration_01_03.class); private Repository repository; private String sourceWorkspace; private String targetWorkspace; - private Session sourceSession; + private Session origSession; private Session targetSession; private List systemPackages; + private String artifactBasePath = "/"; + + private ArtifactIndexer artifactIndexer = new ArtifactIndexer(); + private JarFileIndexer jarFileIndexer = new JarFileIndexer(); + public void init() throws RepositoryException { - sourceSession = JcrUtils.loginOrCreateWorkspace(repository, + origSession = JcrUtils.loginOrCreateWorkspace(repository, sourceWorkspace); targetSession = JcrUtils.loginOrCreateWorkspace(repository, targetWorkspace); @@ -59,91 +73,106 @@ public class Migration_01_03 implements Runnable, SlcNames { } public void destroy() { - JcrUtils.logoutQuietly(sourceSession); + JcrUtils.logoutQuietly(origSession); JcrUtils.logoutQuietly(targetSession); } public void run() { - log.debug(System.getProperty("org.osgi.framework.system.packages")); + try { - NodeIterator sourceArtifacts = listArtifactVersions(sourceSession); - while (sourceArtifacts.hasNext()) { - Node sourceArtifactNode = sourceArtifacts.nextNode(); + NodeIterator origArtifacts = listArtifactVersions(origSession); + + // clear target + NodeIterator nit = targetSession.getNode(artifactBasePath) + .getNodes(); + while (nit.hasNext()) { + Node node = nit.nextNode(); + if (node.isNodeType(NodeType.NT_FOLDER) + || node.isNodeType(NodeType.NT_UNSTRUCTURED)) + node.remove(); + } + targetSession.save(); + + // process + while (origArtifacts.hasNext()) { + Node origArtifactNode = origArtifacts.nextNode(); if (log.isTraceEnabled()) - log.trace(sourceArtifactNode); + log.trace(origArtifactNode); - processSourceArtifactVersion(sourceArtifactNode); + processOrigArtifactVersion(origArtifactNode); } } catch (Exception e) { throw new SlcException("Cannot perform v1.3 migration from " + sourceWorkspace + " to " + targetWorkspace, e); + } finally { + JcrUtils.discardQuietly(targetSession); } } - protected void processSourceArtifactVersion(Node sourceArtifactNode) + protected void processOrigArtifactVersion(Node origArtifactNode) throws RepositoryException, IOException { - // find jar node - String sourceJarNodeName = sourceArtifactNode.getProperty( - SLC_ARTIFACT_ID).getString() - + "-" - + sourceArtifactNode.getProperty(SLC_ARTIFACT_VERSION) - .getString() + ".jar"; - if (!sourceArtifactNode.hasNode(sourceJarNodeName)) + Artifact origArtifact = RepoUtils.asArtifact(origArtifactNode); + String origJarNodeName = MavenConventionsUtils + .artifactFileName(origArtifact); + if (!origArtifactNode.hasNode(origJarNodeName)) throw new SlcException("Cannot find jar node for " - + sourceArtifactNode); - Node sourceJarNode = sourceArtifactNode.getNode(sourceJarNodeName); + + origArtifactNode); + Node origJarNode = origArtifactNode.getNode(origJarNodeName); // read MANIFEST - Binary manifestBinary = sourceJarNode.getProperty(SLC_MANIFEST) + Binary manifestBinary = origJarNode.getProperty(SLC_MANIFEST) .getBinary(); - Manifest sourceManifest = new Manifest(manifestBinary.getStream()); + Manifest origManifest = new Manifest(manifestBinary.getStream()); JcrUtils.closeQuietly(manifestBinary); Boolean manifestModified = false; - Manifest targetManifest = new Manifest(sourceManifest); + Manifest targetManifest = new Manifest(origManifest); // transform symbolic name - String sourceSymbolicName = sourceManifest.getMainAttributes() - .getValue(Constants.BUNDLE_SYMBOLICNAME); - final String SPRING_SOURCE_PREFIX = "com.springsource"; - if (sourceSymbolicName.startsWith(SPRING_SOURCE_PREFIX) - && !sourceSymbolicName.equals(SPRING_SOURCE_PREFIX + ".json")) { - String targetSymbolicName = sourceSymbolicName + String origSymbolicName = origManifest.getMainAttributes().getValue( + Constants.BUNDLE_SYMBOLICNAME); + final String targetSymbolicName; + if (origSymbolicName.startsWith(SPRING_SOURCE_PREFIX) + && !origSymbolicName.equals(SPRING_SOURCE_PREFIX + ".json")) { + targetSymbolicName = origSymbolicName .substring(SPRING_SOURCE_PREFIX.length() + 1); if (log.isDebugEnabled()) log.debug(Constants.BUNDLE_SYMBOLICNAME + " to " - + targetSymbolicName + " \t\tfrom " - + sourceSymbolicName); + + targetSymbolicName + " \t\tfrom " + origSymbolicName); targetManifest.getMainAttributes().putValue( Constants.BUNDLE_SYMBOLICNAME, targetSymbolicName); manifestModified = true; + } else { + targetSymbolicName = origSymbolicName; } // check fragment host - if (sourceManifest.getMainAttributes().containsKey( - Constants.FRAGMENT_HOST)) { - String fragmentHost = sourceManifest.getMainAttributes().getValue( - Constants.FRAGMENT_HOST); - if (fragmentHost.startsWith(SPRING_SOURCE_PREFIX) - && !fragmentHost.equals(SPRING_SOURCE_PREFIX + ".json")) { - String targetFragmentHost = fragmentHost + if (origManifest.getMainAttributes().containsKey( + new Name(Constants.FRAGMENT_HOST))) { + String origFragmentHost = origManifest.getMainAttributes() + .getValue(Constants.FRAGMENT_HOST); + if (origFragmentHost.startsWith(SPRING_SOURCE_PREFIX) + && !origFragmentHost.equals(SPRING_SOURCE_PREFIX + ".json")) { + String targetFragmentHost = origFragmentHost .substring(SPRING_SOURCE_PREFIX.length() + 1); if (log.isDebugEnabled()) log.debug(Constants.FRAGMENT_HOST + " to " - + targetFragmentHost + " from " + fragmentHost); + + targetFragmentHost + " from " + origFragmentHost); targetManifest.getMainAttributes().putValue( Constants.FRAGMENT_HOST, targetFragmentHost); manifestModified = true; } } + // we assume there is no Require-Bundle in com.springsource.* bundles + // javax with versions StringBuffer targetImportPackages = new StringBuffer(""); - NodeIterator sourceImportPackages = sourceJarNode.getNodes(SLC_ + NodeIterator origImportPackages = origJarNode.getNodes(SLC_ + Constants.IMPORT_PACKAGE); Boolean importPackagesModified = false; - while (sourceImportPackages.hasNext()) { - Node importPackage = sourceImportPackages.nextNode(); + while (origImportPackages.hasNext()) { + Node importPackage = origImportPackages.nextNode(); String pkg = importPackage.getProperty(SLC_NAME).getString(); targetImportPackages.append(pkg); if (importPackage.hasProperty(SLC_VERSION)) { @@ -156,7 +185,7 @@ public class Migration_01_03 implements Runnable, SlcNames { targetVersion = "0"; importPackagesModified = true; if (log.isDebugEnabled()) - log.debug(sourceSymbolicName + log.debug(origSymbolicName + ": Nullify version of " + pkg + " from " + sourceVersion); } @@ -171,7 +200,7 @@ public class Migration_01_03 implements Runnable, SlcNames { targetImportPackages.append(";resolution:=\"optional\""); } - if (sourceImportPackages.hasNext()) + if (origImportPackages.hasNext()) targetImportPackages.append(","); } @@ -182,8 +211,49 @@ public class Migration_01_03 implements Runnable, SlcNames { } if (!manifestModified && log.isTraceEnabled()) { - log.trace("MANIFEST of " + sourceSymbolicName + " was not modified"); + log.trace("MANIFEST of " + origSymbolicName + " was not modified"); } + + // target coordinates + final String targetGroupId; + if (origArtifact.getGroupId().startsWith("org.eclipse")) + targetGroupId = "org.argeo.tp.eclipse"; + else + targetGroupId = "org.argeo.tp"; + + String targetArtifactId = targetSymbolicName.split(";")[0]; + Artifact targetArtifact = new DefaultArtifact(targetGroupId, + targetArtifactId, "jar", origArtifact.getVersion()); + String targetParentPath = MavenConventionsUtils.artifactParentPath( + artifactBasePath, targetArtifact); + String targetFileName = MavenConventionsUtils + .artifactFileName(targetArtifact); + String targetJarPath = targetParentPath + '/' + targetFileName; + + // copy + Node targetParentNode = JcrUtils.mkfolders(targetSession, + targetParentPath); + targetSession.save(); + if (manifestModified) { + Binary origBinary = origJarNode.getNode(Node.JCR_CONTENT) + .getProperty(Property.JCR_DATA).getBinary(); + byte[] targetJarBytes = RepoUtils.modifyManifest( + origBinary.getStream(), targetManifest); + JcrUtils.copyBytesAsFile(targetParentNode, targetFileName, + targetJarBytes); + JcrUtils.closeQuietly(origBinary); + } else {// just copy + targetSession.getWorkspace().copy(sourceWorkspace, + origJarNode.getPath(), targetJarPath); + } + targetSession.save(); + + // reindex + Node targetJarNode = targetSession.getNode(targetJarPath); + artifactIndexer.index(targetJarNode); + jarFileIndexer.index(targetJarNode); + + targetSession.save(); } /* -- 2.39.2