X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;ds=sidebyside;f=org.argeo.slc.repo%2Fsrc%2Forg%2Fargeo%2Fslc%2Frepo%2Fmaven%2FMigration_01_03.java;fp=org.argeo.slc.repo%2Fsrc%2Forg%2Fargeo%2Fslc%2Frepo%2Fmaven%2FMigration_01_03.java;h=8e201253a27f74a176f99217b31f54b25dd03881;hb=825d60c5348dbe3f5be25b0bccf7bdebfe694219;hp=0000000000000000000000000000000000000000;hpb=5e991fff5cba01858dcc5747a27e637325bc5c8e;p=gpl%2Fargeo-jcr.git diff --git a/org.argeo.slc.repo/src/org/argeo/slc/repo/maven/Migration_01_03.java b/org.argeo.slc.repo/src/org/argeo/slc/repo/maven/Migration_01_03.java new file mode 100644 index 0000000..8e20125 --- /dev/null +++ b/org.argeo.slc.repo/src/org/argeo/slc/repo/maven/Migration_01_03.java @@ -0,0 +1,358 @@ +package org.argeo.slc.repo.maven; + +import java.io.IOException; +import java.util.ArrayList; +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.argeo.api.cms.CmsLog; +import org.argeo.jcr.JcrUtils; +import org.argeo.slc.NameVersion; +import org.argeo.slc.SlcException; +import org.argeo.slc.SlcNames; +import org.argeo.slc.SlcTypes; +import org.argeo.slc.repo.ArtifactIndexer; +import org.argeo.slc.repo.JarFileIndexer; +import org.argeo.slc.repo.RepoUtils; +import org.argeo.slc.repo.osgi.OsgiProfile; +import org.eclipse.aether.artifact.Artifact; +import org.eclipse.aether.artifact.DefaultArtifact; +import org.osgi.framework.Constants; + +/** + * 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 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 CmsLog log = CmsLog.getLog(Migration_01_03.class); + + private Repository repository; + private String sourceWorkspace; + private String targetWorkspace; + + private List excludedBundles = new ArrayList(); + private Map symbolicNamesMapping = new HashMap(); + + private Session origSession; + private Session targetSession; + + private List systemPackages = OsgiProfile.PROFILE_JAVA_SE_1_6.getSystemPackages(); + + private String artifactBasePath = "/"; + + private ArtifactIndexer artifactIndexer = new ArtifactIndexer(); + private JarFileIndexer jarFileIndexer = new JarFileIndexer(); + + public void init() throws RepositoryException { + 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(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); + + // skip eclipse artifacts + if ((origArtifact.getGroupId().startsWith("org.eclipse") + && !(origArtifact.getArtifactId().equals("org.eclipse.osgi") + || origArtifact.getArtifactId().equals("org.eclipse.osgi.source") + || origArtifact.getArtifactId().startsWith("org.eclipse.rwt.widgets.upload"))) + || origArtifact.getArtifactId().startsWith("com.ibm.icu")) { + if (log.isDebugEnabled()) + log.debug("Skip " + origArtifact); + return; + } + + // skip SpringSource ActiveMQ + if (origArtifact.getArtifactId().startsWith("com.springsource.org.apache.activemq")) + return; + + 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 if (origFragmentHost.equals("org.argeo.dep.jacob;bundle-version=\"[1.14.3,1.14.4)\"")) { + // this one for those who think I cannot be pragmatic - mbaudier + targetFragmentHost = "com.jacob;bundle-version=\"[1.14.3,1.14.4)\""; + } 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.getArtifactId().startsWith("org.eclipse.rwt.widgets.upload")) + targetGroupId = "org.argeo.tp.rap"; + else if (origArtifact.getArtifactId().startsWith("org.polymap")) + targetGroupId = "org.argeo.tp.rap"; + else if (origArtifact.getGroupId().startsWith("org.eclipse") + && !origArtifact.getArtifactId().equals("org.eclipse.osgi")) + throw new SlcException(origArtifact + " should have been excluded");// 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 { + 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; + } + +}