]> git.argeo.org Git - gpl/argeo-slc.git/blob - org.argeo.slc.repo/src/org/argeo/slc/repo/ArtifactIndexer.java
Adapt to changes in Argeo Commons
[gpl/argeo-slc.git] / org.argeo.slc.repo / src / org / argeo / slc / repo / ArtifactIndexer.java
1 package org.argeo.slc.repo;
2
3 import javax.jcr.Node;
4 import javax.jcr.NodeIterator;
5 import javax.jcr.RepositoryException;
6 import javax.jcr.nodetype.NodeType;
7
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;
17
18 /**
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).
22 */
23 public class ArtifactIndexer implements NodeIndexer, SlcNames {
24 private Log log = LogFactory.getLog(ArtifactIndexer.class);
25 private Boolean force = false;
26
27 public Boolean support(String path) {
28 String relativePath = getRelativePath(path);
29 if (relativePath == null)
30 return false;
31 Artifact artifact = null;
32 try {
33 artifact = AetherUtils.convertPathToArtifact(relativePath, null);
34 } catch (Exception e) {
35 if (log.isTraceEnabled())
36 log.trace("Malformed path " + path + ", skipping silently", e);
37 }
38 return artifact != null;
39 }
40
41 public void index(Node fileNode) {
42 Artifact artifact = null;
43 try {
44 if (!support(fileNode.getPath()))
45 return;
46
47 // Already indexed
48 if (!force && fileNode.isNodeType(SlcTypes.SLC_ARTIFACT))
49 return;
50
51 if (!fileNode.isNodeType(NodeType.NT_FILE))
52 return;
53
54 String relativePath = getRelativePath(fileNode.getPath());
55 if (relativePath == null)
56 return;
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);
71
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,
77 sha.getBytes());
78 }
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,
83 md5.getBytes());
84 }
85
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()
91 - ".jar".length())
92 + ".pom";
93
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());
105 }
106
107 // set higher levels
108 Node artifactVersionBase = fileNode.getParent();
109 if (!artifactVersionBase
110 .isNodeType(SlcTypes.SLC_ARTIFACT_VERSION_BASE)) {
111 artifactVersionBase
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());
119 }
120 JcrUtils.updateLastModified(artifactVersionBase);
121
122 // pom
123 if (artifact.getExtension().equals("pom")) {
124 // TODO read to make it a distribution
125 }
126
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());
134 }
135 JcrUtils.updateLastModified(artifactBase);
136
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");
142 // }
143 groupBase.addMixin(SlcTypes.SLC_GROUP_BASE);
144 groupBase.setProperty(SlcNames.SLC_GROUP_BASE_ID,
145 artifact.getGroupId());
146 }
147 JcrUtils.updateLastModifiedAndParents(groupBase,
148 RepoConstants.DEFAULT_ARTIFACTS_BASE_PATH);
149
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);
155 }
156 }
157
158 private String getRelativePath(String nodePath) {
159 String basePath = RepoConstants.DEFAULT_ARTIFACTS_BASE_PATH;
160 if (!nodePath.startsWith(basePath))
161 return null;
162 String relativePath = nodePath.substring(basePath.length());
163 return relativePath;
164 }
165
166 public void setForce(Boolean force) {
167 this.force = force;
168 }
169
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>");
175
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))
186 p.append("<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>")
191 .append(JcrUtils
192 .get(n, SLC_ + Constants.BUNDLE_DESCRIPTION))
193 .append("</description>\n");
194
195 // Dependencies in case of a distribution
196 if (n.isNodeType(SlcTypes.SLC_MODULAR_DISTRIBUTION)) {
197 p.append(getDependenciesSnippet(n.getNode(SlcNames.SLC_MODULES)
198 .getNodes()));
199 p.append(getDependencyManagementSnippet(n.getNode(
200 SlcNames.SLC_MODULES).getNodes()));
201 }
202 p.append("</project>\n");
203 return p.toString();
204 }
205
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)
215 .getString(),
216 currModule.getProperty(SlcNames.SLC_NAME).getString(),
217 null));
218 }
219 }
220 b.append("</dependencies>\n");
221 return b.toString();
222 }
223
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)
234 .getString(),
235 currModule.getProperty(SlcNames.SLC_NAME).getString(),
236 currModule.getProperty(SlcNames.SLC_VERSION)
237 .getString()));
238 }
239 }
240 b.append("</dependencies>\n");
241 b.append("</dependencyManagement>\n");
242 return b.toString();
243 }
244
245 private String getDependencySnippet(String category, String name,
246 String version) {
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");
251 if (version != null)
252 b.append("\t<version>").append(version).append("</version>\n");
253 b.append("</dependency>\n");
254 return b.toString();
255 }
256 }