X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;f=runtime%2Forg.argeo.slc.repo%2Fsrc%2Fmain%2Fjava%2Forg%2Fargeo%2Fslc%2Frepo%2Fmaven%2FMigration_01_03.java;h=56ffd7f67f5dd18cbba7863a8fc0448a33da1113;hb=0e2862f3efc104beecea43b054e2ba00b03fd2c2;hp=5a04ba1e72f77e2244a6432261089aa90e2d8490;hpb=fa2bad4fbf272c2ee4c5dd57e896da1692bbe097;p=gpl%2Fargeo-slc.git 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 5a04ba1e7..56ffd7f67 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 @@ -1,51 +1,378 @@ package org.argeo.slc.repo.maven; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +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; +import javax.jcr.query.qom.QueryObjectModel; import javax.jcr.query.qom.QueryObjectModelFactory; +import javax.jcr.query.qom.Selector; +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.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 { +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 List excludedBundles = new ArrayList(); + private Map symbolicNamesMapping = new HashMap(); + + 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); + + // works only in OSGi!! + systemPackages = Arrays.asList(System.getProperty( + "org.osgi.framework.system.packages").split(",")); } public void destroy() { - JcrUtils.logoutQuietly(sourceSession); + JcrUtils.logoutQuietly(origSession); JcrUtils.logoutQuietly(targetSession); } public void run() { + try { + // 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(); + node.getSession().save(); + if (log.isDebugEnabled()) + log.debug("Cleared " + node); + } + } + + NodeIterator origArtifacts = listArtifactVersions(origSession); + // process + while (origArtifacts.hasNext()) { + Node origArtifactNode = origArtifacts.nextNode(); + if (log.isTraceEnabled()) + log.trace(origArtifactNode); + + processOrigArtifactVersion(origArtifactNode); + } + } catch (Exception e) { + throw new SlcException("Cannot perform v1.3 migration from " + + sourceWorkspace + " to " + targetWorkspace, e); + } finally { + JcrUtils.discardQuietly(targetSession); + } } + protected void processOrigArtifactVersion(Node origArtifactNode) + throws RepositoryException, IOException { + Artifact origArtifact = RepoUtils.asArtifact(origArtifactNode); + String origJarNodeName = MavenConventionsUtils + .artifactFileName(origArtifact); + if (!origArtifactNode.hasNode(origJarNodeName)) + throw new SlcException("Cannot find jar node for " + + origArtifactNode); + Node origJarNode = origArtifactNode.getNode(origJarNodeName); + + // read MANIFEST + Binary manifestBinary = origJarNode.getProperty(SLC_MANIFEST) + .getBinary(); + Manifest origManifest = new Manifest(manifestBinary.getStream()); + JcrUtils.closeQuietly(manifestBinary); + + Boolean manifestModified = false; + Manifest targetManifest = new Manifest(origManifest); + + // transform symbolic name + String origSymbolicName = origManifest.getMainAttributes().getValue( + Constants.BUNDLE_SYMBOLICNAME); + final String targetSymbolicName; + if (symbolicNamesMapping.containsKey(origSymbolicName)) { + targetSymbolicName = symbolicNamesMapping.get(origSymbolicName); + } else if (origSymbolicName.startsWith(SPRING_SOURCE_PREFIX) + && !origSymbolicName.equals(SPRING_SOURCE_PREFIX + ".json")) { + targetSymbolicName = origSymbolicName + .substring(SPRING_SOURCE_PREFIX.length() + 1); + } else { + targetSymbolicName = origSymbolicName; + } + + if (!targetSymbolicName.equals(origSymbolicName)) { + targetManifest.getMainAttributes().putValue( + Constants.BUNDLE_SYMBOLICNAME, targetSymbolicName); + manifestModified = true; + if (log.isDebugEnabled()) + log.debug(Constants.BUNDLE_SYMBOLICNAME + " to " + + targetSymbolicName + " \t\tfrom " + origSymbolicName); + } + + // skip excluded bundles + if (excludedBundles.contains(targetSymbolicName)) + return; + + // check fragment host + if (origManifest.getMainAttributes().containsKey( + new Name(Constants.FRAGMENT_HOST))) { + String origFragmentHost = origManifest.getMainAttributes() + .getValue(Constants.FRAGMENT_HOST); + String targetFragmentHost; + if (symbolicNamesMapping.containsKey(origFragmentHost)) { + targetFragmentHost = symbolicNamesMapping.get(origFragmentHost); + } else if (origFragmentHost.startsWith(SPRING_SOURCE_PREFIX) + && !origFragmentHost.equals(SPRING_SOURCE_PREFIX + ".json")) { + targetFragmentHost = origFragmentHost + .substring(SPRING_SOURCE_PREFIX.length() + 1); + } else { + targetFragmentHost = origFragmentHost; + } + + if (!targetFragmentHost.equals(origFragmentHost)) { + targetManifest.getMainAttributes().putValue( + Constants.FRAGMENT_HOST, targetFragmentHost); + manifestModified = true; + if (log.isDebugEnabled()) + log.debug(Constants.FRAGMENT_HOST + " to " + + targetFragmentHost + " from " + origFragmentHost); + } + } + + // we assume there is no Require-Bundle in com.springsource.* bundles + + // javax with versions + StringBuffer targetImportPackages = new StringBuffer(""); + NodeIterator origImportPackages = origJarNode.getNodes(SLC_ + + Constants.IMPORT_PACKAGE); + Boolean importPackagesModified = false; + while (origImportPackages.hasNext()) { + Node importPackage = origImportPackages.nextNode(); + String pkg = importPackage.getProperty(SLC_NAME).getString(); + targetImportPackages.append(pkg); + if (importPackage.hasProperty(SLC_VERSION)) { + String sourceVersion = importPackage.getProperty(SLC_VERSION) + .getString(); + String targetVersion = sourceVersion; + if (systemPackages.contains(pkg)) { + if (!(sourceVersion.trim().equals("0") || sourceVersion + .trim().equals("0.0.0"))) { + targetVersion = null; + importPackagesModified = true; + if (log.isDebugEnabled()) + log.debug(origSymbolicName + + ": Nullify version of " + pkg + " from " + + sourceVersion); + } + } + if (targetVersion != null) + targetImportPackages.append(";version=\"") + .append(targetVersion).append("\""); + } + if (importPackage.hasProperty(SLC_OPTIONAL)) { + Boolean optional = importPackage.getProperty(SLC_OPTIONAL) + .getBoolean(); + if (optional) + targetImportPackages.append(";resolution:=\"optional\""); + + } + if (origImportPackages.hasNext()) + targetImportPackages.append(","); + } + + if (importPackagesModified) { + targetManifest.getMainAttributes().putValue( + Constants.IMPORT_PACKAGE, targetImportPackages.toString()); + manifestModified = true; + } + + if (!manifestModified && log.isTraceEnabled()) { + 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(); + + // sources + Artifact origSourceArtifact = new DefaultArtifact( + origArtifact.getGroupId(), origArtifact.getArtifactId() + + ".source", "jar", origArtifact.getVersion()); + String origSourcePath = MavenConventionsUtils.artifactPath( + artifactBasePath, origSourceArtifact); + if (origSession.itemExists(origSourcePath)) { + Node origSourceJarNode = origSession.getNode(origSourcePath); + + Artifact targetSourceArtifact = new DefaultArtifact(targetGroupId, + targetArtifactId + ".source", "jar", + origArtifact.getVersion()); + String targetSourceParentPath = MavenConventionsUtils + .artifactParentPath(artifactBasePath, targetSourceArtifact); + String targetSourceFileName = MavenConventionsUtils + .artifactFileName(targetSourceArtifact); + String targetSourceJarPath = targetSourceParentPath + '/' + + targetSourceFileName; + + Node targetSourceParentNode = JcrUtils.mkfolders(targetSession, + targetSourceParentPath); + targetSession.save(); + + if (!targetSymbolicName.equals(origSymbolicName)) { + Binary origBinary = origSourceJarNode.getNode(Node.JCR_CONTENT) + .getProperty(Property.JCR_DATA).getBinary(); + NameVersion targetNameVersion = RepoUtils + .readNameVersion(targetManifest); + byte[] targetJarBytes = RepoUtils.packageAsPdeSource( + origBinary.getStream(), targetNameVersion); + JcrUtils.copyBytesAsFile(targetSourceParentNode, + targetSourceFileName, targetJarBytes); + JcrUtils.closeQuietly(origBinary); + } else {// just copy + targetSession.getWorkspace().copy(sourceWorkspace, + origSourceJarNode.getPath(), targetSourceJarPath); + } + targetSession.save(); + + // reindex + Node targetSourceJarNode = targetSession + .getNode(targetSourceJarPath); + artifactIndexer.index(targetSourceJarNode); + jarFileIndexer.index(targetSourceJarNode); + + targetSession.save(); + } + } + + /* + * UTILITIES + */ + static NodeIterator listArtifactVersions(Session session) throws RepositoryException { - QueryObjectModelFactory qomf = session.getWorkspace().getQueryManager() - .getQOMFactory(); - return null; + QueryManager queryManager = session.getWorkspace().getQueryManager(); + QueryObjectModelFactory factory = queryManager.getQOMFactory(); + + final String artifactVersionsSelector = "artifactVersions"; + Selector source = factory.selector(SlcTypes.SLC_ARTIFACT_VERSION_BASE, + artifactVersionsSelector); + + Ordering orderByArtifactId = factory.ascending(factory.propertyValue( + artifactVersionsSelector, SlcNames.SLC_ARTIFACT_ID)); + Ordering[] orderings = { orderByArtifactId }; + + QueryObjectModel query = factory.createQuery(source, null, orderings, + null); + + QueryResult result = query.execute(); + return result.getNodes(); + } + + public void setRepository(Repository repository) { + this.repository = repository; + } + + public void setSourceWorkspace(String sourceWorkspace) { + this.sourceWorkspace = sourceWorkspace; + } + + public void setTargetWorkspace(String targetWorkspace) { + this.targetWorkspace = targetWorkspace; + } + + public void setExcludedBundles(List excludedBundles) { + this.excludedBundles = excludedBundles; } + + public void setSymbolicNamesMapping(Map symbolicNamesMapping) { + this.symbolicNamesMapping = symbolicNamesMapping; + } + }