import java.io.OutputStream;
import java.util.Enumeration;
import java.util.Iterator;
+import java.util.Set;
import java.util.StringTokenizer;
+import java.util.TreeSet;
import java.util.jar.Attributes;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import javax.jcr.Repository;
import javax.jcr.RepositoryException;
import javax.jcr.RepositoryFactory;
+import javax.jcr.Session;
import javax.jcr.SimpleCredentials;
import javax.jcr.nodetype.NodeType;
import org.argeo.jcr.ArgeoNames;
import org.argeo.jcr.ArgeoTypes;
import org.argeo.jcr.JcrUtils;
-import org.argeo.slc.BasicNameVersion;
+import org.argeo.slc.DefaultNameVersion;
import org.argeo.slc.NameVersion;
import org.argeo.slc.SlcException;
+import org.argeo.slc.aether.ArtifactIdComparator;
import org.argeo.slc.jcr.SlcNames;
import org.argeo.slc.jcr.SlcTypes;
import org.argeo.slc.repo.maven.MavenConventionsUtils;
/** Read the OSGi {@link NameVersion} */
public static NameVersion readNameVersion(Manifest manifest) {
- BasicNameVersion nameVersion = new BasicNameVersion();
+ DefaultNameVersion nameVersion = new DefaultNameVersion();
nameVersion.setName(manifest.getMainAttributes().getValue(
Constants.BUNDLE_SYMBOLICNAME));
}
}
+ /**
+ * Write group indexes: 'binaries' lists all bundles and their versions,
+ * 'sources' list theire sources, and 'sdk' aggregates both.
+ */
+ public static void writeGroupIndexes(Session session,
+ String artifactBasePath, String groupId, String version,
+ Set<Artifact> binaries, Set<Artifact> sources) {
+ try {
+ Set<Artifact> indexes = new TreeSet<Artifact>(
+ new ArtifactIdComparator());
+ Artifact binariesArtifact = writeIndex(session, artifactBasePath,
+ groupId, RepoConstants.BINARIES_ARTIFACT_ID, version,
+ binaries);
+ indexes.add(binariesArtifact);
+ if (sources != null) {
+ Artifact sourcesArtifact = writeIndex(session,
+ artifactBasePath, groupId,
+ RepoConstants.SOURCES_ARTIFACT_ID, version, sources);
+ indexes.add(sourcesArtifact);
+ }
+ // sdk
+ writeIndex(session, artifactBasePath, groupId,
+ RepoConstants.SDK_ARTIFACT_ID, version, indexes);
+ session.save();
+ } catch (RepositoryException e) {
+ throw new SlcException("Cannot write indexes for group " + groupId,
+ e);
+ }
+ }
+
+ /** Write a group index. */
+ private static Artifact writeIndex(Session session,
+ String artifactBasePath, String groupId, String artifactId,
+ String version, Set<Artifact> artifacts) throws RepositoryException {
+ Artifact artifact = new DefaultArtifact(groupId, artifactId, "pom",
+ version);
+ String pom = MavenConventionsUtils.artifactsAsDependencyPom(artifact,
+ artifacts, null);
+ Node node = RepoUtils.copyBytesAsArtifact(
+ session.getNode(artifactBasePath), artifact, pom.getBytes());
+ addMavenChecksums(node);
+ return artifact;
+ }
+
+ /** Add files containing the SHA-1 and MD5 checksums. */
+ public static void addMavenChecksums(Node node) throws RepositoryException {
+ // TODO optimize
+ String sha = JcrUtils.checksumFile(node, "SHA-1");
+ JcrUtils.copyBytesAsFile(node.getParent(), node.getName() + ".sha1",
+ sha.getBytes());
+ String md5 = JcrUtils.checksumFile(node, "MD5");
+ JcrUtils.copyBytesAsFile(node.getParent(), node.getName() + ".md5",
+ md5.getBytes());
+ }
+
/**
* Custom copy since the one in commons does not fit the needs when copying
* a workspace completely.
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import javax.jcr.Node;
import javax.jcr.Property;
+import javax.jcr.RepositoryException;
import javax.jcr.Session;
import org.apache.commons.io.IOUtils;
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.aether.ArtifactIdComparator;
import org.argeo.slc.repo.OsgiFactory;
import org.argeo.slc.repo.RepoUtils;
import org.sonatype.aether.artifact.Artifact;
-
-/** Download a software distribution and generates the related OSGi bundles. */
+import org.sonatype.aether.util.artifact.DefaultArtifact;
+import org.springframework.util.AntPathMatcher;
+import org.springframework.util.PathMatcher;
+
+/**
+ * Download a software distribution and generates the related OSGi bundles from
+ * the jars, or import them directly if they are already OSGi bundles and don't
+ * need further modification.
+ */
public class ArchiveWrapper implements Runnable {
private final static Log log = LogFactory.getLog(ArchiveWrapper.class);
private OsgiFactory osgiFactory;
-
private String version;
- // private String groupId;
-
+
private String uri;
-
+ private List<String> fallbackUris = new ArrayList<String>();
+
+ // jars to wrap as OSGi bundles
private Map<String, BndWrapper> wrappers = new HashMap<String, BndWrapper>();
+ // pattern of OSGi bundles to import
+ private PathMatcher pathMatcher = new AntPathMatcher();
+ private Map<String, String> includes = new HashMap<String, String>();
+ private List<String> excludes = new ArrayList<String>();
+
+ private Boolean mavenGroupIndexes = false;
+
public void init() {
- for (BndWrapper wrapper : wrappers.values()) {
- if (wrapper.getVersion() == null)
- wrapper.setVersion(version);
- }
+ if (version != null)
+ for (BndWrapper wrapper : wrappers.values()) {
+ if (wrapper.getVersion() == null)
+ wrapper.setVersion(version);
+ }
}
public void destroy() {
}
public void run() {
+ if (mavenGroupIndexes && (version == null))
+ throw new SlcException(
+ "'mavenGroupIndexes' requires 'version' to be set");
+
+ Map<String, Set<Artifact>> binaries = new HashMap<String, Set<Artifact>>();
+ Map<String, Set<Artifact>> sources = new HashMap<String, Set<Artifact>>();
Session distSession = null;
Session javaSession = null;
.getProperty(Property.JCR_DATA).getBinary().getStream());
ZipEntry zentry = null;
- ByteArrayOutputStream out = null;
- ByteArrayInputStream in = null;
- while ((zentry = zin.getNextEntry()) != null) {
- try {
- String name = zentry.getName();
- // if (log.isDebugEnabled())
- // log.debug("Scanning " + name);
- if (wrappers.containsKey(name)) {
-
- BndWrapper wrapper = (BndWrapper) wrappers.get(name);
- // if (wrapper.getVersion() == null)
- // wrapper.setVersion(version);// FIXME stateful?
-
- out = new ByteArrayOutputStream((int) zentry.getSize());
- // we must copy since the stream is closed by BND
- byte[] sourceJarBytes = IOUtils.toByteArray(zin);
- in = new ByteArrayInputStream(sourceJarBytes);
- wrapper.wrapJar(in, out);
-
- Artifact newArtifact = wrapper.getArtifact();
- Node newJarNode = RepoUtils.copyBytesAsArtifact(
- javaSession.getRootNode(), newArtifact,
- out.toByteArray());
- osgiFactory.indexNode(newJarNode);
- newJarNode.getSession().save();
- if (log.isDebugEnabled())
- log.debug("Wrapped " + name + " to "
- + newJarNode.getPath());
+ entries: while ((zentry = zin.getNextEntry()) != null) {
+ String name = zentry.getName();
+ if (wrappers.containsKey(name)) {
+ BndWrapper wrapper = (BndWrapper) wrappers.get(name);
+ // we must copy since the stream is closed by BND
+ byte[] sourceJarBytes = IOUtils.toByteArray(zin);
+ Artifact artifact = wrapZipEntry(javaSession, zentry,
+ sourceJarBytes, wrapper);
+ addArtifactToIndex(binaries, wrapper.getGroupId(), artifact);
+ } else {
+ for (String exclude : excludes)
+ if (pathMatcher.match(exclude, name))
+ continue entries;
+
+ for (String include : includes.keySet()) {
+ if (pathMatcher.match(include, name)) {
+ String groupId = includes.get(include);
+ byte[] sourceJarBytes = IOUtils.toByteArray(zin);
+ Artifact artifact = importZipEntry(javaSession,
+ zentry, sourceJarBytes, groupId);
+ if (artifact.getArtifactId().endsWith(".source"))
+ addArtifactToIndex(sources, groupId, artifact);
+ else
+ addArtifactToIndex(binaries, groupId, artifact);
+ }
}
- } finally {
- IOUtils.closeQuietly(out);
- IOUtils.closeQuietly(in);
}
}
+
+ // indexes
+ if (mavenGroupIndexes && version != null) {
+ for (String groupId : binaries.keySet()) {
+ RepoUtils.writeGroupIndexes(javaSession, "/", groupId,
+ version, binaries.get(groupId),
+ sources.containsKey(groupId) ? sources.get(groupId)
+ : null);
+ }
+ }
+
} catch (Exception e) {
throw new SlcException("Cannot wrap distribution " + uri, e);
} finally {
}
}
- // public List<ArtifactDistribution> provides() {
- // List<ArtifactDistribution> res = new ArrayList<ArtifactDistribution>();
- // for (BndWrapper bndWrapper : wrappers.values()) {
- // ArtifactDistribution ad = new ArtifactDistribution(groupId + ":"
- // + bndWrapper.getName() + ":" + bndWrapper.getVersion());
- // res.add(ad);
- // }
- // return res;
- // }
+ protected Artifact wrapZipEntry(Session javaSession, ZipEntry zentry,
+ byte[] sourceJarBytes, BndWrapper wrapper)
+ throws RepositoryException {
+ ByteArrayOutputStream out = null;
+ ByteArrayInputStream in = null;
+ Node newJarNode;
+ try {
+ out = new ByteArrayOutputStream((int) zentry.getSize());
+ in = new ByteArrayInputStream(sourceJarBytes);
+ wrapper.wrapJar(in, out);
+
+ Artifact artifact = wrapper.getArtifact();
+ newJarNode = RepoUtils.copyBytesAsArtifact(
+ javaSession.getRootNode(), artifact, out.toByteArray());
+ osgiFactory.indexNode(newJarNode);
+ newJarNode.getSession().save();
+ if (log.isDebugEnabled())
+ log.debug("Wrapped jar " + zentry.getName() + " to "
+ + newJarNode.getPath());
+ return artifact;
+ } finally {
+ IOUtils.closeQuietly(in);
+ IOUtils.closeQuietly(out);
+ }
+ }
+
+ protected Artifact importZipEntry(Session javaSession, ZipEntry zentry,
+ byte[] sourceJarBytes, String groupId) throws RepositoryException {
+ ByteArrayInputStream in = null;
+ Node newJarNode;
+ try {
+ in = new ByteArrayInputStream(sourceJarBytes);
+ NameVersion nameVersion = RepoUtils.readNameVersion(in);
+ Artifact artifact = new DefaultArtifact(groupId,
+ nameVersion.getName(), "jar", nameVersion.getVersion());
+ newJarNode = RepoUtils.copyBytesAsArtifact(
+ javaSession.getRootNode(), artifact, sourceJarBytes);
+ osgiFactory.indexNode(newJarNode);
+ newJarNode.getSession().save();
+ if (log.isDebugEnabled())
+ log.debug("Imported OSGi bundle " + zentry.getName() + " to "
+ + newJarNode.getPath());
+ return artifact;
+ } finally {
+ IOUtils.closeQuietly(in);
+ }
+ }
+
+ private void addArtifactToIndex(Map<String, Set<Artifact>> index,
+ String groupId, Artifact artifact) {
+ if (!index.containsKey(groupId))
+ index.put(groupId,
+ new TreeSet<Artifact>(new ArtifactIdComparator()));
+ index.get(groupId).add(artifact);
+ }
public void setUri(String uri) {
this.uri = uri;
this.version = version;
}
+ public void setPathMatcher(PathMatcher pathMatcher) {
+ this.pathMatcher = pathMatcher;
+ }
+
+ public void setIncludes(Map<String, String> includes) {
+ this.includes = includes;
+ }
+
+ public void setExcludes(List<String> excludes) {
+ this.excludes = excludes;
+ }
+
+ public void setMavenGroupIndexes(Boolean mavenGroupIndexes) {
+ this.mavenGroupIndexes = mavenGroupIndexes;
+ }
+
}
import org.argeo.slc.jcr.SlcNames;
import org.argeo.slc.jcr.SlcTypes;
import org.argeo.slc.repo.ArtifactIndexer;
+import org.argeo.slc.repo.RepoConstants;
import org.argeo.slc.repo.RepoUtils;
import org.argeo.slc.repo.maven.MavenConventionsUtils;
import org.osgi.framework.Constants;
* group of OSGi bundles.
*/
public class NormalizeGroup implements Runnable, SlcNames {
- public final static String BINARIES_ARTIFACT_ID = "binaries";
- public final static String SOURCES_ARTIFACT_ID = "sources";
- public final static String SDK_ARTIFACT_ID = "sdk";
-
private final static Log log = LogFactory.getLog(NormalizeGroup.class);
private Repository repository;
// indexes
Set<Artifact> indexes = new TreeSet<Artifact>(
new ArtifactIdComparator());
- Artifact indexArtifact = writeIndex(session, BINARIES_ARTIFACT_ID,
+ Artifact indexArtifact = writeIndex(session, RepoConstants.BINARIES_ARTIFACT_ID,
binaries);
indexes.add(indexArtifact);
- indexArtifact = writeIndex(session, SOURCES_ARTIFACT_ID, sources);
+ indexArtifact = writeIndex(session, RepoConstants.SOURCES_ARTIFACT_ID, sources);
indexes.add(indexArtifact);
// sdk
- writeIndex(session, SDK_ARTIFACT_ID, indexes);
+ writeIndex(session, RepoConstants.SDK_ARTIFACT_ID, indexes);
if (monitor != null)
monitor.worked(1);
}
p.append("<dependency>\n");
p.append("\t<groupId>").append(groupId).append("</groupId>\n");
p.append("\t<artifactId>")
- .append(ownSymbolicName.endsWith(".source") ? SOURCES_ARTIFACT_ID
- : BINARIES_ARTIFACT_ID).append("</artifactId>\n");
+ .append(ownSymbolicName.endsWith(".source") ? RepoConstants.SOURCES_ARTIFACT_ID
+ : RepoConstants.BINARIES_ARTIFACT_ID).append("</artifactId>\n");
p.append("\t<version>").append(version).append("</version>\n");
p.append("\t<type>pom</type>\n");
p.append("\t<scope>import</scope>\n");