package org.argeo.slc.repo;
+import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
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. */
}
}
+ /** 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();
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() {
}
}
node.remove();
}
session.save();
+
+ // sync
syncDistribution(session, artifacts);
} catch (Exception e) {
throw new SlcException("Cannot import distribution", e);
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() + ":"
.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);
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());
.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);
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;
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);
}
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)) {
targetVersion = "0";
importPackagesModified = true;
if (log.isDebugEnabled())
- log.debug(sourceSymbolicName
+ log.debug(origSymbolicName
+ ": Nullify version of " + pkg + " from "
+ sourceVersion);
}
targetImportPackages.append(";resolution:=\"optional\"");
}
- if (sourceImportPackages.hasNext())
+ if (origImportPackages.hasNext())
targetImportPackages.append(",");
}
}
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();
}
/*