*/
package org.argeo.slc.repo.maven;
-import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
-import java.io.InputStream;
-import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashSet;
-import java.util.List;
import java.util.Properties;
import java.util.Set;
import java.util.TreeSet;
-import java.util.jar.Attributes;
-import java.util.jar.Attributes.Name;
-import java.util.jar.JarInputStream;
-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.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
-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.jcr.JcrUtils;
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.RepoConstants;
-import org.osgi.framework.Constants;
-import org.osgi.framework.Version;
import org.sonatype.aether.artifact.Artifact;
import org.sonatype.aether.graph.DependencyNode;
import org.sonatype.aether.util.artifact.DefaultArtifact;
private String rootCoordinates;
private Set<String> excludedArtifacts = new HashSet<String>();
- private Session jcrSession;
+ private Repository repository;
+ private String workspace;
+
private String artifactBasePath = RepoConstants.ARTIFACTS_BASE_PATH;
private String distributionsBasePath = RepoConstants.DISTRIBUTIONS_BASE_PATH;
private String distributionName;
private ArtifactIndexer artifactIndexer = new ArtifactIndexer();
+ private JarFileIndexer jarFileIndexer = new JarFileIndexer();
public void run() {
- log.debug(jcrSession.getUserID());
+ // resolve
Set<Artifact> artifacts = resolveDistribution();
- syncDistribution(artifacts);
+
+ // sync
+ Session session = null;
+ try {
+ session = JcrUtils.loginOrCreateWorkspace(repository, workspace);
+ // clear
+ NodeIterator nit = session.getNode(artifactBasePath).getNodes();
+ while (nit.hasNext()) {
+ Node node = nit.nextNode();
+ if (node.isNodeType(NodeType.NT_FOLDER))
+ node.remove();
+ }
+ session.save();
+ syncDistribution(session, artifacts);
+ } catch (Exception e) {
+ throw new SlcException("Cannot import distribution", e);
+ } finally {
+ JcrUtils.logoutQuietly(session);
+ }
}
public Set<Artifact> resolveDistribution() {
}
}
- protected void syncDistribution(Set<Artifact> artifacts) {
+ protected void syncDistribution(Session jcrSession, Set<Artifact> artifacts) {
Long begin = System.currentTimeMillis();
try {
JcrUtils.mkdirs(jcrSession, artifactBasePath);
artifacts: for (Artifact artifact : artifacts) {
File file = artifact.getFile();
if (file == null) {
- log.warn("File not found for " + artifact);
+ // log.warn("File not found for " + artifact);
file = artifactToFile(artifact);
if (artifactIndexer.support(fileNode.getPath()))
artifactIndexer.index(fileNode);
- if (fileNode.isNodeType(SlcTypes.SLC_JAR_FILE)) {
- processOsgiBundle(fileNode);
- }
+ if (jarFileIndexer.support(fileNode.getPath()))
+ jarFileIndexer.index(fileNode);
jcrSession.save();
- if (!jcrSession
- .itemExists(bundleDistributionPath(fileNode))
- && fileNode
- .isNodeType(SlcTypes.SLC_BUNDLE_ARTIFACT))
- jcrSession.getWorkspace().clone(
- jcrSession.getWorkspace().getName(),
- fileNode.getPath(),
- bundleDistributionPath(fileNode), false);
-
- if (log.isDebugEnabled())
- log.debug("Synchronized " + fileNode);
+ if (fileNode.hasProperty(SlcNames.SLC_SYMBOLIC_NAME)) {
+ String distPath = bundleDistributionPath(fileNode);
+ if (!jcrSession.itemExists(distPath)
+ && fileNode
+ .isNodeType(SlcTypes.SLC_BUNDLE_ARTIFACT))
+ jcrSession.getWorkspace().clone(
+ jcrSession.getWorkspace().getName(),
+ fileNode.getPath(), distPath, false);
+ if (log.isDebugEnabled())
+ log.debug("Synchronized " + fileNode);
+ }
} catch (Exception e) {
log.error("Could not synchronize " + artifact, e);
jcrSession.refresh(false);
+ artifact.getExtension());
}
- protected void processOsgiBundle(Node fileNode) {
- Binary manifestBinary = null;
- InputStream manifestIn = null;
- try {
- manifestBinary = fileNode.getProperty(SlcNames.SLC_MANIFEST)
- .getBinary();
- manifestIn = manifestBinary.getStream();
- Manifest manifest = new Manifest(manifestIn);
- Attributes attrs = manifest.getMainAttributes();
-
- if (log.isTraceEnabled())
- for (Object key : attrs.keySet())
- log.trace(key + ": " + attrs.getValue(key.toString()));
-
- if (!attrs.containsKey(new Name(Constants.BUNDLE_SYMBOLICNAME))) {
- log.warn(fileNode + " is not an OSGi bundle");
- return;// not an osgi bundle
- }
-
- fileNode.addMixin(SlcTypes.SLC_BUNDLE_ARTIFACT);
-
- // symbolic name
- String symbolicName = attrs.getValue(Constants.BUNDLE_SYMBOLICNAME);
- // make sure there is no directive
- symbolicName = symbolicName.split(";")[0];
- fileNode.setProperty(SlcNames.SLC_SYMBOLIC_NAME, symbolicName);
-
- // direct mapping
- addAttr(Constants.BUNDLE_SYMBOLICNAME, fileNode, attrs);
- addAttr(Constants.BUNDLE_NAME, fileNode, attrs);
- addAttr(Constants.BUNDLE_DESCRIPTION, fileNode, attrs);
- addAttr(Constants.BUNDLE_MANIFESTVERSION, fileNode, attrs);
- addAttr(Constants.BUNDLE_CATEGORY, fileNode, attrs);
- addAttr(Constants.BUNDLE_ACTIVATIONPOLICY, fileNode, attrs);
- addAttr(Constants.BUNDLE_COPYRIGHT, fileNode, attrs);
- addAttr(Constants.BUNDLE_VENDOR, fileNode, attrs);
- addAttr("Bundle-License", fileNode, attrs);
- addAttr(Constants.BUNDLE_DOCURL, fileNode, attrs);
- addAttr(Constants.BUNDLE_CONTACTADDRESS, fileNode, attrs);
- addAttr(Constants.BUNDLE_ACTIVATOR, fileNode, attrs);
- addAttr(Constants.BUNDLE_UPDATELOCATION, fileNode, attrs);
- addAttr(Constants.BUNDLE_LOCALIZATION, fileNode, attrs);
-
- // required execution environment
- if (attrs.containsKey(new Name(
- Constants.BUNDLE_REQUIREDEXECUTIONENVIRONMENT)))
- fileNode.setProperty(
- SlcNames.SLC_
- + Constants.BUNDLE_REQUIREDEXECUTIONENVIRONMENT,
- attrs.getValue(
- Constants.BUNDLE_REQUIREDEXECUTIONENVIRONMENT)
- .split(","));
-
- // bundle classpath
- if (attrs.containsKey(new Name(Constants.BUNDLE_CLASSPATH)))
- fileNode.setProperty(
- SlcNames.SLC_ + Constants.BUNDLE_CLASSPATH, attrs
- .getValue(Constants.BUNDLE_CLASSPATH)
- .split(","));
-
- // version
- Version version = new Version(
- attrs.getValue(Constants.BUNDLE_VERSION));
- fileNode.setProperty(SlcNames.SLC_BUNDLE_VERSION,
- version.toString());
- cleanSubNodes(fileNode, SlcNames.SLC_ + Constants.BUNDLE_VERSION);
- Node bundleVersionNode = fileNode.addNode(SlcNames.SLC_
- + Constants.BUNDLE_VERSION, SlcTypes.SLC_OSGI_VERSION);
- mapOsgiVersion(version, bundleVersionNode);
-
- // fragment
- cleanSubNodes(fileNode, SlcNames.SLC_ + Constants.FRAGMENT_HOST);
- if (attrs.containsKey(new Name(Constants.FRAGMENT_HOST))) {
- String fragmentHost = attrs.getValue(Constants.FRAGMENT_HOST);
- String[] tokens = fragmentHost.split(";");
- Node node = fileNode.addNode(SlcNames.SLC_
- + Constants.FRAGMENT_HOST, SlcTypes.SLC_FRAGMENT_HOST);
- node.setProperty(SlcNames.SLC_SYMBOLIC_NAME, tokens[0]);
- for (int i = 1; i < tokens.length; i++) {
- if (tokens[i]
- .startsWith(Constants.BUNDLE_VERSION_ATTRIBUTE)) {
- node.setProperty(SlcNames.SLC_BUNDLE_VERSION,
- attributeValue(tokens[i]));
- }
- }
- }
-
- // imported packages
- cleanSubNodes(fileNode, SlcNames.SLC_ + Constants.IMPORT_PACKAGE);
- if (attrs.containsKey(new Name(Constants.IMPORT_PACKAGE))) {
- String importPackages = attrs
- .getValue(Constants.IMPORT_PACKAGE);
- List<String> packages = parsePackages(importPackages);
- for (String pkg : packages) {
- String[] tokens = pkg.split(";");
- Node node = fileNode.addNode(SlcNames.SLC_
- + Constants.IMPORT_PACKAGE,
- SlcTypes.SLC_IMPORTED_PACKAGE);
- node.setProperty(SlcNames.SLC_NAME, tokens[0]);
- for (int i = 1; i < tokens.length; i++) {
- if (tokens[i].startsWith(Constants.VERSION_ATTRIBUTE)) {
- node.setProperty(SlcNames.SLC_VERSION,
- attributeValue(tokens[i]));
- } else if (tokens[i]
- .startsWith(Constants.RESOLUTION_DIRECTIVE)) {
- node.setProperty(
- SlcNames.SLC_OPTIONAL,
- directiveValue(tokens[i]).equals(
- Constants.RESOLUTION_OPTIONAL));
- }
- }
- }
- }
-
- // dynamic import package
- cleanSubNodes(fileNode, SlcNames.SLC_
- + Constants.DYNAMICIMPORT_PACKAGE);
- if (attrs.containsKey(new Name(Constants.DYNAMICIMPORT_PACKAGE))) {
- String importPackages = attrs
- .getValue(Constants.DYNAMICIMPORT_PACKAGE);
- List<String> packages = parsePackages(importPackages);
- for (String pkg : packages) {
- String[] tokens = pkg.split(";");
- Node node = fileNode.addNode(SlcNames.SLC_
- + Constants.DYNAMICIMPORT_PACKAGE,
- SlcTypes.SLC_DYNAMIC_IMPORTED_PACKAGE);
- node.setProperty(SlcNames.SLC_NAME, tokens[0]);
- for (int i = 1; i < tokens.length; i++) {
- if (tokens[i].startsWith(Constants.VERSION_ATTRIBUTE)) {
- node.setProperty(SlcNames.SLC_VERSION,
- attributeValue(tokens[i]));
- }
- }
- }
- }
-
- // exported packages
- cleanSubNodes(fileNode, SlcNames.SLC_ + Constants.EXPORT_PACKAGE);
- if (attrs.containsKey(new Name(Constants.EXPORT_PACKAGE))) {
- String exportPackages = attrs
- .getValue(Constants.EXPORT_PACKAGE);
- List<String> packages = parsePackages(exportPackages);
- for (String pkg : packages) {
- String[] tokens = pkg.split(";");
- Node node = fileNode.addNode(SlcNames.SLC_
- + Constants.EXPORT_PACKAGE,
- SlcTypes.SLC_EXPORTED_PACKAGE);
- node.setProperty(SlcNames.SLC_NAME, tokens[0]);
- // TODO: are these cleans really necessary?
- cleanSubNodes(node, SlcNames.SLC_USES);
- cleanSubNodes(node, SlcNames.SLC_VERSION);
- for (int i = 1; i < tokens.length; i++) {
- if (tokens[i].startsWith(Constants.VERSION_ATTRIBUTE)) {
- String versionStr = attributeValue(tokens[i]);
- Node versionNode = node.addNode(
- SlcNames.SLC_VERSION,
- SlcTypes.SLC_OSGI_VERSION);
- mapOsgiVersion(new Version(versionStr), versionNode);
- } else if (tokens[i]
- .startsWith(Constants.USES_DIRECTIVE)) {
- String usedPackages = directiveValue(tokens[i]);
- // log.debug("uses='" + usedPackages + "'");
- for (String usedPackage : usedPackages.split(",")) {
- // log.debug("usedPackage='" + usedPackage +
- // "'");
- Node usesNode = node.addNode(SlcNames.SLC_USES,
- SlcTypes.SLC_JAVA_PACKAGE);
- usesNode.setProperty(SlcNames.SLC_NAME,
- usedPackage);
- }
- }
- }
- }
- }
-
- // required bundle
- cleanSubNodes(fileNode, SlcNames.SLC_ + Constants.REQUIRE_BUNDLE);
- if (attrs.containsKey(new Name(Constants.REQUIRE_BUNDLE))) {
- String requireBundle = attrs.getValue(Constants.REQUIRE_BUNDLE);
- String[] bundles = requireBundle.split(",");
- for (String bundle : bundles) {
- String[] tokens = bundle.split(";");
- Node node = fileNode.addNode(SlcNames.SLC_
- + Constants.REQUIRE_BUNDLE,
- SlcTypes.SLC_REQUIRED_BUNDLE);
- node.setProperty(SlcNames.SLC_SYMBOLIC_NAME, tokens[0]);
- for (int i = 1; i < tokens.length; i++) {
- if (tokens[i]
- .startsWith(Constants.BUNDLE_VERSION_ATTRIBUTE)) {
- node.setProperty(SlcNames.SLC_BUNDLE_VERSION,
- attributeValue(tokens[i]));
- } else if (tokens[i]
- .startsWith(Constants.RESOLUTION_DIRECTIVE)) {
- node.setProperty(
- SlcNames.SLC_OPTIONAL,
- directiveValue(tokens[i]).equals(
- Constants.RESOLUTION_OPTIONAL));
- }
- }
- }
- }
- } catch (Exception e) {
- throw new SlcException("Cannot process OSGi bundle " + fileNode, e);
- } finally {
- if (manifestBinary != null)
- manifestBinary.dispose();
- IOUtils.closeQuietly(manifestIn);
- }
- }
-
- /** Parse package list with nested directive with ',' */
- private List<String> parsePackages(String str) {
- List<String> res = new ArrayList<String>();
- StringBuffer curr = new StringBuffer("");
- boolean in = false;
- for (char c : str.toCharArray()) {
- if (c == ',') {
- if (!in) {
- res.add(curr.toString());
- curr = new StringBuffer("");
- }
- } else if (c == '\"') {
- in = !in;
- curr.append(c);
- } else {
- curr.append(c);
- }
- }
- res.add(curr.toString());
- log.debug(res);
- return res;
- }
-
- private void addAttr(String key, Node node, Attributes attrs)
- throws RepositoryException {
- addAttr(new Name(key), node, attrs);
- }
-
- private void addAttr(Name key, Node node, Attributes attrs)
- throws RepositoryException {
- if (attrs.containsKey(key)) {
- String value = attrs.getValue(key);
- node.setProperty(SlcNames.SLC_ + key, value);
- }
- }
-
- private void cleanSubNodes(Node node, String name)
- throws RepositoryException {
- if (node.hasNode(name)) {
- NodeIterator nit = node.getNodes(name);
- while (nit.hasNext())
- nit.nextNode().remove();
- }
- }
-
- protected void mapOsgiVersion(Version version, Node versionNode)
- throws RepositoryException {
- versionNode.setProperty(SlcNames.SLC_AS_STRING, version.toString());
- versionNode.setProperty(SlcNames.SLC_MAJOR, version.getMajor());
- versionNode.setProperty(SlcNames.SLC_MINOR, version.getMinor());
- versionNode.setProperty(SlcNames.SLC_MICRO, version.getMicro());
- if (!version.getQualifier().equals(""))
- versionNode.setProperty(SlcNames.SLC_QUALIFIER,
- version.getQualifier());
- }
-
- private String attributeValue(String str) {
- return extractValue(str, "=");
- }
-
- private String directiveValue(String str) {
- return extractValue(str, ":=");
- }
-
- private String extractValue(String str, String eq) {
- String[] tokens = str.split(eq);
- // String key = tokens[0];
- String value = tokens[1].trim();
- // TODO: optimize?
- if (value.startsWith("\""))
- value = value.substring(1);
- if (value.endsWith("\""))
- value = value.substring(0, value.length() - 1);
- return value;
- }
-
- protected Node createFileNode(Node parentNode, File file) {
+ private Node createFileNode(Node parentNode, File file) {
Binary binary = null;
try {
Node fileNode = parentNode
.addNode(file.getName(), NodeType.NT_FILE);
Node contentNode = fileNode.addNode(Node.JCR_CONTENT,
NodeType.NT_RESOURCE);
- binary = jcrSession.getValueFactory().createBinary(
- new FileInputStream(file));
+ binary = contentNode.getSession().getValueFactory()
+ .createBinary(new FileInputStream(file));
contentNode.setProperty(Property.JCR_DATA, binary);
- // jar file
- if (FilenameUtils.isExtension(file.getName(), "jar")) {
- JarInputStream jarIn = null;
- ByteArrayOutputStream bo = null;
- ByteArrayInputStream bi = null;
- Binary manifestBinary = null;
- try {
- jarIn = new JarInputStream(binary.getStream());
- Manifest manifest = jarIn.getManifest();
- bo = new ByteArrayOutputStream();
- manifest.write(bo);
- bi = new ByteArrayInputStream(bo.toByteArray());
- manifestBinary = jcrSession.getValueFactory().createBinary(
- bi);
- fileNode.addMixin(SlcTypes.SLC_JAR_FILE);
- fileNode.setProperty(SlcNames.SLC_MANIFEST, manifestBinary);
- Attributes attrs = manifest.getMainAttributes();
- addAttr(Attributes.Name.MANIFEST_VERSION, fileNode, attrs);
- addAttr(Attributes.Name.SIGNATURE_VERSION, fileNode, attrs);
- addAttr(Attributes.Name.CLASS_PATH, fileNode, attrs);
- addAttr(Attributes.Name.MAIN_CLASS, fileNode, attrs);
- addAttr(Attributes.Name.EXTENSION_NAME, fileNode, attrs);
- addAttr(Attributes.Name.IMPLEMENTATION_VERSION, fileNode,
- attrs);
- addAttr(Attributes.Name.IMPLEMENTATION_VENDOR, fileNode,
- attrs);
- addAttr(Attributes.Name.IMPLEMENTATION_VENDOR_ID, fileNode,
- attrs);
- addAttr(Attributes.Name.SPECIFICATION_TITLE, fileNode,
- attrs);
- addAttr(Attributes.Name.SPECIFICATION_VERSION, fileNode,
- attrs);
- addAttr(Attributes.Name.SPECIFICATION_VENDOR, fileNode,
- attrs);
- addAttr(Attributes.Name.SEALED, fileNode, attrs);
- } finally {
- if (manifestBinary != null)
- manifestBinary.dispose();
- IOUtils.closeQuietly(bi);
- IOUtils.closeQuietly(bo);
- IOUtils.closeQuietly(jarIn);
- }
- }
return fileNode;
} catch (Exception e) {
throw new SlcException("Cannot create file node based on " + file
this.rootCoordinates = rootCoordinates;
}
- public void setJcrSession(Session jcrSession) {
- this.jcrSession = jcrSession;
- }
-
public void setDistributionName(String distributionName) {
this.distributionName = distributionName;
}
+ public void setRepository(Repository repository) {
+ this.repository = repository;
+ }
+
+ public void setWorkspace(String workspace) {
+ this.workspace = workspace;
+ }
+
}