1 package org
.argeo
.slc
.repo
;
4 import javax
.jcr
.NodeIterator
;
5 import javax
.jcr
.RepositoryException
;
6 import javax
.jcr
.nodetype
.NodeType
;
8 import org
.argeo
.api
.cms
.CmsLog
;
9 import org
.argeo
.jcr
.JcrUtils
;
10 import org
.argeo
.slc
.SlcException
;
11 import org
.argeo
.slc
.SlcNames
;
12 import org
.argeo
.slc
.SlcTypes
;
13 import org
.argeo
.slc
.repo
.maven
.AetherUtils
;
14 import org
.eclipse
.aether
.artifact
.Artifact
;
15 import org
.osgi
.framework
.Constants
;
18 * Add {@link Artifact} properties to a {@link Node}. Does nothing if the node
19 * name doesn't start with the artifact id (in order to skip Maven metadata XML
20 * files and other non artifact files).
22 public class ArtifactIndexer
implements NodeIndexer
, SlcNames
{
23 private CmsLog log
= CmsLog
.getLog(ArtifactIndexer
.class);
24 private Boolean force
= false;
26 public Boolean
support(String path
) {
27 String relativePath
= getRelativePath(path
);
28 if (relativePath
== null)
30 Artifact artifact
= null;
32 artifact
= AetherUtils
.convertPathToArtifact(relativePath
, null);
33 } catch (Exception e
) {
34 if (log
.isTraceEnabled())
35 log
.trace("Malformed path " + path
+ ", skipping silently", e
);
37 return artifact
!= null;
40 public void index(Node fileNode
) {
41 Artifact artifact
= null;
43 if (!support(fileNode
.getPath()))
47 if (!force
&& fileNode
.isNodeType(SlcTypes
.SLC_ARTIFACT
))
50 if (!fileNode
.isNodeType(NodeType
.NT_FILE
))
53 String relativePath
= getRelativePath(fileNode
.getPath());
54 if (relativePath
== null)
56 artifact
= AetherUtils
.convertPathToArtifact(relativePath
, null);
57 // support() guarantees that artifact won't be null, no NPE check
58 fileNode
.addMixin(SlcTypes
.SLC_ARTIFACT
);
59 fileNode
.setProperty(SlcNames
.SLC_ARTIFACT_ID
, artifact
.getArtifactId());
60 fileNode
.setProperty(SlcNames
.SLC_GROUP_ID
, artifact
.getGroupId());
61 fileNode
.setProperty(SlcNames
.SLC_ARTIFACT_VERSION
, artifact
.getVersion());
62 fileNode
.setProperty(SlcNames
.SLC_ARTIFACT_EXTENSION
, artifact
.getExtension());
63 // can be null but ok for JCR API
64 fileNode
.setProperty(SlcNames
.SLC_ARTIFACT_CLASSIFIER
, artifact
.getClassifier());
65 JcrUtils
.updateLastModified(fileNode
);
67 // make sure there are checksums
68 String shaNodeName
= fileNode
.getName() + ".sha1";
69 if (!fileNode
.getParent().hasNode(shaNodeName
)) {
70 String sha
= JcrUtils
.checksumFile(fileNode
, "SHA-1");
71 JcrUtils
.copyBytesAsFile(fileNode
.getParent(), shaNodeName
, sha
.getBytes());
73 String md5NodeName
= fileNode
.getName() + ".md5";
74 if (!fileNode
.getParent().hasNode(md5NodeName
)) {
75 String md5
= JcrUtils
.checksumFile(fileNode
, "MD5");
76 JcrUtils
.copyBytesAsFile(fileNode
.getParent(), md5NodeName
, md5
.getBytes());
79 // Create a default pom if none already exist
80 String fileNodeName
= fileNode
.getName();
81 String pomName
= null;
82 if (fileNodeName
.endsWith(".jar"))
83 pomName
= fileNodeName
.substring(0, fileNodeName
.length() - ".jar".length()) + ".pom";
85 if (pomName
!= null && !fileNode
.getParent().hasNode(pomName
)) {
86 String pom
= generatePomForBundle(fileNode
);
87 Node pomNode
= JcrUtils
.copyBytesAsFile(fileNode
.getParent(), pomName
, pom
.getBytes());
88 // corresponding check sums
89 String sha
= JcrUtils
.checksumFile(pomNode
, "SHA-1");
90 JcrUtils
.copyBytesAsFile(fileNode
.getParent(), pomName
+ ".sha1", sha
.getBytes());
91 String md5
= JcrUtils
.checksumFile(fileNode
, "MD5");
92 JcrUtils
.copyBytesAsFile(fileNode
.getParent(), pomName
+ ".md5", md5
.getBytes());
96 Node artifactVersionBase
= fileNode
.getParent();
97 if (!artifactVersionBase
.isNodeType(SlcTypes
.SLC_ARTIFACT_VERSION_BASE
)) {
98 artifactVersionBase
.addMixin(SlcTypes
.SLC_ARTIFACT_VERSION_BASE
);
99 artifactVersionBase
.setProperty(SlcNames
.SLC_ARTIFACT_VERSION
, artifact
.getBaseVersion());
100 artifactVersionBase
.setProperty(SlcNames
.SLC_ARTIFACT_ID
, artifact
.getArtifactId());
101 artifactVersionBase
.setProperty(SlcNames
.SLC_GROUP_ID
, artifact
.getGroupId());
103 JcrUtils
.updateLastModified(artifactVersionBase
);
106 if (artifact
.getExtension().equals("pom")) {
107 // TODO read to make it a distribution
110 Node artifactBase
= artifactVersionBase
.getParent();
111 if (!artifactBase
.isNodeType(SlcTypes
.SLC_ARTIFACT_BASE
)) {
112 artifactBase
.addMixin(SlcTypes
.SLC_ARTIFACT_BASE
);
113 artifactBase
.setProperty(SlcNames
.SLC_ARTIFACT_ID
, artifact
.getArtifactId());
114 artifactBase
.setProperty(SlcNames
.SLC_GROUP_ID
, artifact
.getGroupId());
116 JcrUtils
.updateLastModified(artifactBase
);
118 Node groupBase
= artifactBase
.getParent();
119 if (!groupBase
.isNodeType(SlcTypes
.SLC_GROUP_BASE
)) {
120 // if (groupBase.isNodeType(SlcTypes.SLC_ARTIFACT_BASE)) {
121 // log.warn("Group base " + groupBase.getPath()
122 // + " is also artifact base");
124 groupBase
.addMixin(SlcTypes
.SLC_GROUP_BASE
);
125 groupBase
.setProperty(SlcNames
.SLC_GROUP_BASE_ID
, artifact
.getGroupId());
127 JcrUtils
.updateLastModifiedAndParents(groupBase
, RepoConstants
.DEFAULT_ARTIFACTS_BASE_PATH
);
129 if (log
.isTraceEnabled())
130 log
.trace("Indexed artifact " + artifact
+ " on " + fileNode
);
131 } catch (Exception e
) {
132 throw new SlcException("Cannot index artifact " + artifact
+ " metadata on node " + fileNode
, e
);
136 private String
getRelativePath(String nodePath
) {
137 String basePath
= RepoConstants
.DEFAULT_ARTIFACTS_BASE_PATH
;
138 if (!nodePath
.startsWith(basePath
))
140 String relativePath
= nodePath
.substring(basePath
.length());
144 public void setForce(Boolean force
) {
148 private String
generatePomForBundle(Node n
) throws RepositoryException
{
149 StringBuffer p
= new StringBuffer();
150 p
.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
152 "<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n");
153 p
.append("<modelVersion>4.0.0</modelVersion>");
155 // Categorized name version
156 p
.append("<groupId>").append(JcrUtils
.get(n
, SLC_GROUP_ID
)).append("</groupId>\n");
157 p
.append("<artifactId>").append(JcrUtils
.get(n
, SLC_ARTIFACT_ID
)).append("</artifactId>\n");
158 p
.append("<version>").append(JcrUtils
.get(n
, SLC_ARTIFACT_VERSION
)).append("</version>\n");
159 // TODO make it more generic
160 p
.append("<packaging>jar</packaging>\n");
161 if (n
.hasProperty(SLC_
+ Constants
.BUNDLE_NAME
))
162 p
.append("<name>").append(JcrUtils
.get(n
, SLC_
+ Constants
.BUNDLE_NAME
)).append("</name>\n");
163 if (n
.hasProperty(SLC_
+ Constants
.BUNDLE_DESCRIPTION
))
164 p
.append("<description>").append(JcrUtils
.get(n
, SLC_
+ Constants
.BUNDLE_DESCRIPTION
))
165 .append("</description>\n");
167 // Dependencies in case of a distribution
168 if (n
.isNodeType(SlcTypes
.SLC_MODULAR_DISTRIBUTION
)) {
169 p
.append(getDependenciesSnippet(n
.getNode(SlcNames
.SLC_MODULES
).getNodes()));
170 p
.append(getDependencyManagementSnippet(n
.getNode(SlcNames
.SLC_MODULES
).getNodes()));
172 p
.append("</project>\n");
176 private String
getDependenciesSnippet(NodeIterator nit
) throws RepositoryException
{
177 StringBuilder b
= new StringBuilder();
178 b
.append("<dependencies>\n");
179 while (nit
.hasNext()) {
180 Node currModule
= nit
.nextNode();
181 if (currModule
.isNodeType(SlcTypes
.SLC_MODULE_COORDINATES
)) {
182 b
.append(getDependencySnippet(currModule
.getProperty(SlcNames
.SLC_CATEGORY
).getString(),
183 currModule
.getProperty(SlcNames
.SLC_NAME
).getString(), null));
186 b
.append("</dependencies>\n");
190 private String
getDependencyManagementSnippet(NodeIterator nit
) throws RepositoryException
{
191 StringBuilder b
= new StringBuilder();
192 b
.append("<dependencyManagement>\n");
193 b
.append("<dependencies>\n");
194 while (nit
.hasNext()) {
195 Node currModule
= nit
.nextNode();
196 if (currModule
.isNodeType(SlcTypes
.SLC_MODULE_COORDINATES
)) {
197 b
.append(getDependencySnippet(currModule
.getProperty(SlcNames
.SLC_CATEGORY
).getString(),
198 currModule
.getProperty(SlcNames
.SLC_NAME
).getString(),
199 currModule
.getProperty(SlcNames
.SLC_VERSION
).getString()));
202 b
.append("</dependencies>\n");
203 b
.append("</dependencyManagement>\n");
207 private String
getDependencySnippet(String category
, String name
, String version
) {
208 StringBuilder b
= new StringBuilder();
209 b
.append("<dependency>\n");
210 b
.append("\t<groupId>").append(category
).append("</groupId>\n");
211 b
.append("\t<artifactId>").append(name
).append("</artifactId>\n");
213 b
.append("\t<version>").append(version
).append("</version>\n");
214 b
.append("</dependency>\n");