MIgrate binaries to target workspace
authorMathieu Baudier <mbaudier@argeo.org>
Wed, 9 May 2012 09:37:10 +0000 (09:37 +0000)
committerMathieu Baudier <mbaudier@argeo.org>
Wed, 9 May 2012 09:37:10 +0000 (09:37 +0000)
git-svn-id: https://svn.argeo.org/slc/trunk@5296 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/RepoUtils.java
runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/maven/ImportMavenDependencies.java
runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/maven/Migration_01_03.java

index 17f9fd6436679b9c37c6e35f0f26999f94a9ff67..80569b159cc495b14164942d37bd3f0c8be622ff 100644 (file)
@@ -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() {
        }
 }
index bde774526c48354f35bb6e70ceb9292e54e493fe..0bda72b7e87e91d272eaa86e0cf7d5b99f767345 100644 (file)
@@ -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);
index 27207118dfc1ff49498544041f629e23ced05fab..b93831cc191c8bf0f071791030b84cba30e4582d 100644 (file)
@@ -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<String> 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();
        }
 
        /*