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
.apache
.commons
.logging
.Log
;
9 import org
.apache
.commons
.logging
.LogFactory
;
10 import org
.argeo
.jcr
.JcrUtils
;
11 import org
.argeo
.slc
.SlcException
;
12 import org
.argeo
.slc
.SlcNames
;
13 import org
.argeo
.slc
.SlcTypes
;
14 import org
.argeo
.slc
.repo
.maven
.AetherUtils
;
15 import org
.eclipse
.aether
.artifact
.Artifact
;
16 import org
.osgi
.framework
.Constants
;
19 * Add {@link Artifact} properties to a {@link Node}. Does nothing if the node
20 * name doesn't start with the artifact id (in order to skip Maven metadata XML
21 * files and other non artifact files).
23 public class ArtifactIndexer
implements NodeIndexer
, SlcNames
{
24 private Log log
= LogFactory
.getLog(ArtifactIndexer
.class);
25 private Boolean force
= false;
27 public Boolean
support(String path
) {
28 String relativePath
= getRelativePath(path
);
29 if (relativePath
== null)
31 Artifact artifact
= null;
33 artifact
= AetherUtils
.convertPathToArtifact(relativePath
, null);
34 } catch (Exception e
) {
35 if (log
.isTraceEnabled())
36 log
.trace("Malformed path " + path
+ ", skipping silently", e
);
38 return artifact
!= null;
41 public void index(Node fileNode
) {
42 Artifact artifact
= null;
44 if (!support(fileNode
.getPath()))
48 if (!force
&& fileNode
.isNodeType(SlcTypes
.SLC_ARTIFACT
))
51 if (!fileNode
.isNodeType(NodeType
.NT_FILE
))
54 String relativePath
= getRelativePath(fileNode
.getPath());
55 if (relativePath
== null)
57 artifact
= AetherUtils
.convertPathToArtifact(relativePath
, null);
58 // support() guarantees that artifact won't be null, no NPE check
59 fileNode
.addMixin(SlcTypes
.SLC_ARTIFACT
);
60 fileNode
.setProperty(SlcNames
.SLC_ARTIFACT_ID
,
61 artifact
.getArtifactId());
62 fileNode
.setProperty(SlcNames
.SLC_GROUP_ID
, artifact
.getGroupId());
63 fileNode
.setProperty(SlcNames
.SLC_ARTIFACT_VERSION
,
64 artifact
.getVersion());
65 fileNode
.setProperty(SlcNames
.SLC_ARTIFACT_EXTENSION
,
66 artifact
.getExtension());
67 // can be null but ok for JCR API
68 fileNode
.setProperty(SlcNames
.SLC_ARTIFACT_CLASSIFIER
,
69 artifact
.getClassifier());
70 JcrUtils
.updateLastModified(fileNode
);
72 // make sure there are checksums
73 String shaNodeName
= fileNode
.getName() + ".sha1";
74 if (!fileNode
.getParent().hasNode(shaNodeName
)) {
75 String sha
= JcrUtils
.checksumFile(fileNode
, "SHA-1");
76 JcrUtils
.copyBytesAsFile(fileNode
.getParent(), shaNodeName
,
79 String md5NodeName
= fileNode
.getName() + ".md5";
80 if (!fileNode
.getParent().hasNode(md5NodeName
)) {
81 String md5
= JcrUtils
.checksumFile(fileNode
, "MD5");
82 JcrUtils
.copyBytesAsFile(fileNode
.getParent(), md5NodeName
,
86 // Create a default pom if none already exist
87 String fileNodeName
= fileNode
.getName();
88 String pomName
= null;
89 if (fileNodeName
.endsWith(".jar"))
90 pomName
= fileNodeName
.substring(0, fileNodeName
.length()
94 if (pomName
!= null && !fileNode
.getParent().hasNode(pomName
)) {
95 String pom
= generatePomForBundle(fileNode
);
96 Node pomNode
= JcrUtils
.copyBytesAsFile(fileNode
.getParent(),
97 pomName
, pom
.getBytes());
98 // corresponding check sums
99 String sha
= JcrUtils
.checksumFile(pomNode
, "SHA-1");
100 JcrUtils
.copyBytesAsFile(fileNode
.getParent(), pomName
101 + ".sha1", sha
.getBytes());
102 String md5
= JcrUtils
.checksumFile(fileNode
, "MD5");
103 JcrUtils
.copyBytesAsFile(fileNode
.getParent(),
104 pomName
+ ".md5", md5
.getBytes());
108 Node artifactVersionBase
= fileNode
.getParent();
109 if (!artifactVersionBase
110 .isNodeType(SlcTypes
.SLC_ARTIFACT_VERSION_BASE
)) {
112 .addMixin(SlcTypes
.SLC_ARTIFACT_VERSION_BASE
);
113 artifactVersionBase
.setProperty(SlcNames
.SLC_ARTIFACT_VERSION
,
114 artifact
.getBaseVersion());
115 artifactVersionBase
.setProperty(SlcNames
.SLC_ARTIFACT_ID
,
116 artifact
.getArtifactId());
117 artifactVersionBase
.setProperty(SlcNames
.SLC_GROUP_ID
,
118 artifact
.getGroupId());
120 JcrUtils
.updateLastModified(artifactVersionBase
);
123 if (artifact
.getExtension().equals("pom")) {
124 // TODO read to make it a distribution
127 Node artifactBase
= artifactVersionBase
.getParent();
128 if (!artifactBase
.isNodeType(SlcTypes
.SLC_ARTIFACT_BASE
)) {
129 artifactBase
.addMixin(SlcTypes
.SLC_ARTIFACT_BASE
);
130 artifactBase
.setProperty(SlcNames
.SLC_ARTIFACT_ID
,
131 artifact
.getArtifactId());
132 artifactBase
.setProperty(SlcNames
.SLC_GROUP_ID
,
133 artifact
.getGroupId());
135 JcrUtils
.updateLastModified(artifactBase
);
137 Node groupBase
= artifactBase
.getParent();
138 if (!groupBase
.isNodeType(SlcTypes
.SLC_GROUP_BASE
)) {
139 // if (groupBase.isNodeType(SlcTypes.SLC_ARTIFACT_BASE)) {
140 // log.warn("Group base " + groupBase.getPath()
141 // + " is also artifact base");
143 groupBase
.addMixin(SlcTypes
.SLC_GROUP_BASE
);
144 groupBase
.setProperty(SlcNames
.SLC_GROUP_BASE_ID
,
145 artifact
.getGroupId());
147 JcrUtils
.updateLastModifiedAndParents(groupBase
,
148 RepoConstants
.DEFAULT_ARTIFACTS_BASE_PATH
);
150 if (log
.isTraceEnabled())
151 log
.trace("Indexed artifact " + artifact
+ " on " + fileNode
);
152 } catch (Exception e
) {
153 throw new SlcException("Cannot index artifact " + artifact
154 + " metadata on node " + fileNode
, e
);
158 private String
getRelativePath(String nodePath
) {
159 String basePath
= RepoConstants
.DEFAULT_ARTIFACTS_BASE_PATH
;
160 if (!nodePath
.startsWith(basePath
))
162 String relativePath
= nodePath
.substring(basePath
.length());
166 public void setForce(Boolean force
) {
170 private String
generatePomForBundle(Node n
) throws RepositoryException
{
171 StringBuffer p
= new StringBuffer();
172 p
.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
173 p
.append("<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");
174 p
.append("<modelVersion>4.0.0</modelVersion>");
176 // Categorized name version
177 p
.append("<groupId>").append(JcrUtils
.get(n
, SLC_GROUP_ID
))
178 .append("</groupId>\n");
179 p
.append("<artifactId>").append(JcrUtils
.get(n
, SLC_ARTIFACT_ID
))
180 .append("</artifactId>\n");
181 p
.append("<version>").append(JcrUtils
.get(n
, SLC_ARTIFACT_VERSION
))
182 .append("</version>\n");
183 // TODO make it more generic
184 p
.append("<packaging>jar</packaging>\n");
185 if (n
.hasProperty(SLC_
+ Constants
.BUNDLE_NAME
))
187 .append(JcrUtils
.get(n
, SLC_
+ Constants
.BUNDLE_NAME
))
188 .append("</name>\n");
189 if (n
.hasProperty(SLC_
+ Constants
.BUNDLE_DESCRIPTION
))
190 p
.append("<description>")
192 .get(n
, SLC_
+ Constants
.BUNDLE_DESCRIPTION
))
193 .append("</description>\n");
195 // Dependencies in case of a distribution
196 if (n
.isNodeType(SlcTypes
.SLC_MODULAR_DISTRIBUTION
)) {
197 p
.append(getDependenciesSnippet(n
.getNode(SlcNames
.SLC_MODULES
)
199 p
.append(getDependencyManagementSnippet(n
.getNode(
200 SlcNames
.SLC_MODULES
).getNodes()));
202 p
.append("</project>\n");
206 private String
getDependenciesSnippet(NodeIterator nit
)
207 throws RepositoryException
{
208 StringBuilder b
= new StringBuilder();
209 b
.append("<dependencies>\n");
210 while (nit
.hasNext()) {
211 Node currModule
= nit
.nextNode();
212 if (currModule
.isNodeType(SlcTypes
.SLC_MODULE_COORDINATES
)) {
213 b
.append(getDependencySnippet(
214 currModule
.getProperty(SlcNames
.SLC_CATEGORY
)
216 currModule
.getProperty(SlcNames
.SLC_NAME
).getString(),
220 b
.append("</dependencies>\n");
224 private String
getDependencyManagementSnippet(NodeIterator nit
)
225 throws RepositoryException
{
226 StringBuilder b
= new StringBuilder();
227 b
.append("<dependencyManagement>\n");
228 b
.append("<dependencies>\n");
229 while (nit
.hasNext()) {
230 Node currModule
= nit
.nextNode();
231 if (currModule
.isNodeType(SlcTypes
.SLC_MODULE_COORDINATES
)) {
232 b
.append(getDependencySnippet(
233 currModule
.getProperty(SlcNames
.SLC_CATEGORY
)
235 currModule
.getProperty(SlcNames
.SLC_NAME
).getString(),
236 currModule
.getProperty(SlcNames
.SLC_VERSION
)
240 b
.append("</dependencies>\n");
241 b
.append("</dependencyManagement>\n");
245 private String
getDependencySnippet(String category
, String name
,
247 StringBuilder b
= new StringBuilder();
248 b
.append("<dependency>\n");
249 b
.append("\t<groupId>").append(category
).append("</groupId>\n");
250 b
.append("\t<artifactId>").append(name
).append("</artifactId>\n");
252 b
.append("\t<version>").append(version
).append("</version>\n");
253 b
.append("</dependency>\n");