X-Git-Url: https://git.argeo.org/?a=blobdiff_plain;f=org.argeo.slc.repo%2Fsrc%2Forg%2Fargeo%2Fslc%2Frepo%2FArtifactIndexer.java;fp=org.argeo.slc.repo%2Fsrc%2Forg%2Fargeo%2Fslc%2Frepo%2FArtifactIndexer.java;h=209f2b667dacdec58225c1d73f7ce78b1d5e720c;hb=825d60c5348dbe3f5be25b0bccf7bdebfe694219;hp=0000000000000000000000000000000000000000;hpb=5e991fff5cba01858dcc5747a27e637325bc5c8e;p=gpl%2Fargeo-jcr.git diff --git a/org.argeo.slc.repo/src/org/argeo/slc/repo/ArtifactIndexer.java b/org.argeo.slc.repo/src/org/argeo/slc/repo/ArtifactIndexer.java new file mode 100644 index 0000000..209f2b6 --- /dev/null +++ b/org.argeo.slc.repo/src/org/argeo/slc/repo/ArtifactIndexer.java @@ -0,0 +1,217 @@ +package org.argeo.slc.repo; + +import javax.jcr.Node; +import javax.jcr.NodeIterator; +import javax.jcr.RepositoryException; +import javax.jcr.nodetype.NodeType; + +import org.argeo.api.cms.CmsLog; +import org.argeo.jcr.JcrUtils; +import org.argeo.slc.SlcException; +import org.argeo.slc.SlcNames; +import org.argeo.slc.SlcTypes; +import org.argeo.slc.repo.maven.AetherUtils; +import org.eclipse.aether.artifact.Artifact; +import org.osgi.framework.Constants; + +/** + * Add {@link Artifact} properties to a {@link Node}. Does nothing if the node + * name doesn't start with the artifact id (in order to skip Maven metadata XML + * files and other non artifact files). + */ +public class ArtifactIndexer implements NodeIndexer, SlcNames { + private CmsLog log = CmsLog.getLog(ArtifactIndexer.class); + private Boolean force = false; + + public Boolean support(String path) { + String relativePath = getRelativePath(path); + if (relativePath == null) + return false; + Artifact artifact = null; + try { + artifact = AetherUtils.convertPathToArtifact(relativePath, null); + } catch (Exception e) { + if (log.isTraceEnabled()) + log.trace("Malformed path " + path + ", skipping silently", e); + } + return artifact != null; + } + + public void index(Node fileNode) { + Artifact artifact = null; + try { + if (!support(fileNode.getPath())) + return; + + // Already indexed + if (!force && fileNode.isNodeType(SlcTypes.SLC_ARTIFACT)) + return; + + if (!fileNode.isNodeType(NodeType.NT_FILE)) + return; + + String relativePath = getRelativePath(fileNode.getPath()); + if (relativePath == null) + return; + artifact = AetherUtils.convertPathToArtifact(relativePath, null); + // support() guarantees that artifact won't be null, no NPE check + fileNode.addMixin(SlcTypes.SLC_ARTIFACT); + fileNode.setProperty(SlcNames.SLC_ARTIFACT_ID, artifact.getArtifactId()); + fileNode.setProperty(SlcNames.SLC_GROUP_ID, artifact.getGroupId()); + fileNode.setProperty(SlcNames.SLC_ARTIFACT_VERSION, artifact.getVersion()); + fileNode.setProperty(SlcNames.SLC_ARTIFACT_EXTENSION, artifact.getExtension()); + // can be null but ok for JCR API + fileNode.setProperty(SlcNames.SLC_ARTIFACT_CLASSIFIER, artifact.getClassifier()); + JcrUtils.updateLastModified(fileNode); + + // make sure there are checksums + String shaNodeName = fileNode.getName() + ".sha1"; + if (!fileNode.getParent().hasNode(shaNodeName)) { + String sha = JcrUtils.checksumFile(fileNode, "SHA-1"); + JcrUtils.copyBytesAsFile(fileNode.getParent(), shaNodeName, sha.getBytes()); + } + String md5NodeName = fileNode.getName() + ".md5"; + if (!fileNode.getParent().hasNode(md5NodeName)) { + String md5 = JcrUtils.checksumFile(fileNode, "MD5"); + JcrUtils.copyBytesAsFile(fileNode.getParent(), md5NodeName, md5.getBytes()); + } + + // Create a default pom if none already exist + String fileNodeName = fileNode.getName(); + String pomName = null; + if (fileNodeName.endsWith(".jar")) + pomName = fileNodeName.substring(0, fileNodeName.length() - ".jar".length()) + ".pom"; + + if (pomName != null && !fileNode.getParent().hasNode(pomName)) { + String pom = generatePomForBundle(fileNode); + Node pomNode = JcrUtils.copyBytesAsFile(fileNode.getParent(), pomName, pom.getBytes()); + // corresponding check sums + String sha = JcrUtils.checksumFile(pomNode, "SHA-1"); + JcrUtils.copyBytesAsFile(fileNode.getParent(), pomName + ".sha1", sha.getBytes()); + String md5 = JcrUtils.checksumFile(fileNode, "MD5"); + JcrUtils.copyBytesAsFile(fileNode.getParent(), pomName + ".md5", md5.getBytes()); + } + + // set higher levels + Node artifactVersionBase = fileNode.getParent(); + if (!artifactVersionBase.isNodeType(SlcTypes.SLC_ARTIFACT_VERSION_BASE)) { + artifactVersionBase.addMixin(SlcTypes.SLC_ARTIFACT_VERSION_BASE); + artifactVersionBase.setProperty(SlcNames.SLC_ARTIFACT_VERSION, artifact.getBaseVersion()); + artifactVersionBase.setProperty(SlcNames.SLC_ARTIFACT_ID, artifact.getArtifactId()); + artifactVersionBase.setProperty(SlcNames.SLC_GROUP_ID, artifact.getGroupId()); + } + JcrUtils.updateLastModified(artifactVersionBase); + + // pom + if (artifact.getExtension().equals("pom")) { + // TODO read to make it a distribution + } + + Node artifactBase = artifactVersionBase.getParent(); + if (!artifactBase.isNodeType(SlcTypes.SLC_ARTIFACT_BASE)) { + artifactBase.addMixin(SlcTypes.SLC_ARTIFACT_BASE); + artifactBase.setProperty(SlcNames.SLC_ARTIFACT_ID, artifact.getArtifactId()); + artifactBase.setProperty(SlcNames.SLC_GROUP_ID, artifact.getGroupId()); + } + JcrUtils.updateLastModified(artifactBase); + + Node groupBase = artifactBase.getParent(); + if (!groupBase.isNodeType(SlcTypes.SLC_GROUP_BASE)) { + // if (groupBase.isNodeType(SlcTypes.SLC_ARTIFACT_BASE)) { + // log.warn("Group base " + groupBase.getPath() + // + " is also artifact base"); + // } + groupBase.addMixin(SlcTypes.SLC_GROUP_BASE); + groupBase.setProperty(SlcNames.SLC_GROUP_BASE_ID, artifact.getGroupId()); + } + JcrUtils.updateLastModifiedAndParents(groupBase, RepoConstants.DEFAULT_ARTIFACTS_BASE_PATH); + + if (log.isTraceEnabled()) + log.trace("Indexed artifact " + artifact + " on " + fileNode); + } catch (Exception e) { + throw new SlcException("Cannot index artifact " + artifact + " metadata on node " + fileNode, e); + } + } + + private String getRelativePath(String nodePath) { + String basePath = RepoConstants.DEFAULT_ARTIFACTS_BASE_PATH; + if (!nodePath.startsWith(basePath)) + return null; + String relativePath = nodePath.substring(basePath.length()); + return relativePath; + } + + public void setForce(Boolean force) { + this.force = force; + } + + private String generatePomForBundle(Node n) throws RepositoryException { + StringBuffer p = new StringBuffer(); + p.append("\n"); + p.append( + "\n"); + p.append("4.0.0"); + + // Categorized name version + p.append("").append(JcrUtils.get(n, SLC_GROUP_ID)).append("\n"); + p.append("").append(JcrUtils.get(n, SLC_ARTIFACT_ID)).append("\n"); + p.append("").append(JcrUtils.get(n, SLC_ARTIFACT_VERSION)).append("\n"); + // TODO make it more generic + p.append("jar\n"); + if (n.hasProperty(SLC_ + Constants.BUNDLE_NAME)) + p.append("").append(JcrUtils.get(n, SLC_ + Constants.BUNDLE_NAME)).append("\n"); + if (n.hasProperty(SLC_ + Constants.BUNDLE_DESCRIPTION)) + p.append("").append(JcrUtils.get(n, SLC_ + Constants.BUNDLE_DESCRIPTION)) + .append("\n"); + + // Dependencies in case of a distribution + if (n.isNodeType(SlcTypes.SLC_MODULAR_DISTRIBUTION)) { + p.append(getDependenciesSnippet(n.getNode(SlcNames.SLC_MODULES).getNodes())); + p.append(getDependencyManagementSnippet(n.getNode(SlcNames.SLC_MODULES).getNodes())); + } + p.append("\n"); + return p.toString(); + } + + private String getDependenciesSnippet(NodeIterator nit) throws RepositoryException { + StringBuilder b = new StringBuilder(); + b.append("\n"); + while (nit.hasNext()) { + Node currModule = nit.nextNode(); + if (currModule.isNodeType(SlcTypes.SLC_MODULE_COORDINATES)) { + b.append(getDependencySnippet(currModule.getProperty(SlcNames.SLC_CATEGORY).getString(), + currModule.getProperty(SlcNames.SLC_NAME).getString(), null)); + } + } + b.append("\n"); + return b.toString(); + } + + private String getDependencyManagementSnippet(NodeIterator nit) throws RepositoryException { + StringBuilder b = new StringBuilder(); + b.append("\n"); + b.append("\n"); + while (nit.hasNext()) { + Node currModule = nit.nextNode(); + if (currModule.isNodeType(SlcTypes.SLC_MODULE_COORDINATES)) { + b.append(getDependencySnippet(currModule.getProperty(SlcNames.SLC_CATEGORY).getString(), + currModule.getProperty(SlcNames.SLC_NAME).getString(), + currModule.getProperty(SlcNames.SLC_VERSION).getString())); + } + } + b.append("\n"); + b.append("\n"); + return b.toString(); + } + + private String getDependencySnippet(String category, String name, String version) { + StringBuilder b = new StringBuilder(); + b.append("\n"); + b.append("\t").append(category).append("\n"); + b.append("\t").append(name).append("\n"); + if (version != null) + b.append("\t").append(version).append("\n"); + b.append("\n"); + return b.toString(); + } +} \ No newline at end of file