]> git.argeo.org Git - gpl/argeo-slc.git/blob - runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/ArtifactIndexer.java
Improve licenses and sources
[gpl/argeo-slc.git] / runtime / org.argeo.slc.repo / src / main / java / org / argeo / slc / repo / ArtifactIndexer.java
1 /*
2 * Copyright (C) 2007-2012 Argeo GmbH
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.argeo.slc.repo;
17
18 import javax.jcr.Node;
19 import javax.jcr.NodeIterator;
20 import javax.jcr.RepositoryException;
21 import javax.jcr.nodetype.NodeType;
22
23 import org.apache.commons.logging.Log;
24 import org.apache.commons.logging.LogFactory;
25 import org.argeo.jcr.JcrUtils;
26 import org.argeo.slc.SlcException;
27 import org.argeo.slc.aether.AetherUtils;
28 import org.argeo.slc.jcr.SlcNames;
29 import org.argeo.slc.jcr.SlcTypes;
30 import org.osgi.framework.Constants;
31 import org.sonatype.aether.artifact.Artifact;
32
33 /**
34 * Add {@link Artifact} properties to a {@link Node}. Does nothing if the node
35 * name doesn't start with the artifact id (in order to skip Maven metadata XML
36 * files and other non artifact files).
37 */
38 public class ArtifactIndexer implements NodeIndexer, SlcNames {
39 private Log log = LogFactory.getLog(ArtifactIndexer.class);
40 private Boolean force = false;
41
42 public Boolean support(String path) {
43 String relativePath = getRelativePath(path);
44 if (relativePath == null)
45 return false;
46 Artifact artifact = null;
47 try {
48 artifact = AetherUtils.convertPathToArtifact(relativePath, null);
49 } catch (Exception e) {
50 if (log.isTraceEnabled())
51 log.trace("Malformed path " + path + ", skipping silently", e);
52 }
53 return artifact != null;
54 }
55
56 public void index(Node fileNode) {
57 Artifact artifact = null;
58 try {
59 if (!support(fileNode.getPath()))
60 return;
61
62 // Already indexed
63 if (!force && fileNode.isNodeType(SlcTypes.SLC_ARTIFACT))
64 return;
65
66 if (!fileNode.isNodeType(NodeType.NT_FILE))
67 return;
68
69 String relativePath = getRelativePath(fileNode.getPath());
70 if (relativePath == null)
71 return;
72 artifact = AetherUtils.convertPathToArtifact(relativePath, null);
73 // support() guarantees that artifact won't be null, no NPE check
74 fileNode.addMixin(SlcTypes.SLC_ARTIFACT);
75 fileNode.setProperty(SlcNames.SLC_ARTIFACT_ID,
76 artifact.getArtifactId());
77 fileNode.setProperty(SlcNames.SLC_GROUP_ID, artifact.getGroupId());
78 fileNode.setProperty(SlcNames.SLC_ARTIFACT_VERSION,
79 artifact.getVersion());
80 fileNode.setProperty(SlcNames.SLC_ARTIFACT_EXTENSION,
81 artifact.getExtension());
82 // can be null but ok for JCR API
83 fileNode.setProperty(SlcNames.SLC_ARTIFACT_CLASSIFIER,
84 artifact.getClassifier());
85 JcrUtils.updateLastModified(fileNode);
86
87 // make sure there are checksums
88 String shaNodeName = fileNode.getName() + ".sha1";
89 if (!fileNode.getParent().hasNode(shaNodeName)) {
90 String sha = JcrUtils.checksumFile(fileNode, "SHA-1");
91 JcrUtils.copyBytesAsFile(fileNode.getParent(), shaNodeName,
92 sha.getBytes());
93 }
94 String md5NodeName = fileNode.getName() + ".md5";
95 if (!fileNode.getParent().hasNode(md5NodeName)) {
96 String md5 = JcrUtils.checksumFile(fileNode, "MD5");
97 JcrUtils.copyBytesAsFile(fileNode.getParent(), md5NodeName,
98 md5.getBytes());
99 }
100
101 // Create a default pom if none already exist
102 String fileNodeName = fileNode.getName();
103 String pomName = null;
104 if (fileNodeName.endsWith(".jar"))
105 pomName = fileNodeName.substring(0, fileNodeName.length()
106 - ".jar".length())
107 + ".pom";
108
109 if (pomName != null && !fileNode.getParent().hasNode(pomName)) {
110 String pom = generatePomForBundle(fileNode);
111 Node pomNode = JcrUtils.copyBytesAsFile(fileNode.getParent(),
112 pomName, pom.getBytes());
113 // corresponding check sums
114 String sha = JcrUtils.checksumFile(pomNode, "SHA-1");
115 JcrUtils.copyBytesAsFile(fileNode.getParent(), pomName
116 + ".sha1", sha.getBytes());
117 String md5 = JcrUtils.checksumFile(fileNode, "MD5");
118 JcrUtils.copyBytesAsFile(fileNode.getParent(),
119 pomName + ".md5", md5.getBytes());
120 }
121
122 // set higher levels
123 Node artifactVersionBase = fileNode.getParent();
124 if (!artifactVersionBase
125 .isNodeType(SlcTypes.SLC_ARTIFACT_VERSION_BASE)) {
126 artifactVersionBase
127 .addMixin(SlcTypes.SLC_ARTIFACT_VERSION_BASE);
128 artifactVersionBase.setProperty(SlcNames.SLC_ARTIFACT_VERSION,
129 artifact.getBaseVersion());
130 artifactVersionBase.setProperty(SlcNames.SLC_ARTIFACT_ID,
131 artifact.getArtifactId());
132 artifactVersionBase.setProperty(SlcNames.SLC_GROUP_ID,
133 artifact.getGroupId());
134 }
135 JcrUtils.updateLastModified(artifactVersionBase);
136
137 // pom
138 if (artifact.getExtension().equals("pom")) {
139 // TODO read to make it a distribution
140 }
141
142 Node artifactBase = artifactVersionBase.getParent();
143 if (!artifactBase.isNodeType(SlcTypes.SLC_ARTIFACT_BASE)) {
144 artifactBase.addMixin(SlcTypes.SLC_ARTIFACT_BASE);
145 artifactBase.setProperty(SlcNames.SLC_ARTIFACT_ID,
146 artifact.getArtifactId());
147 artifactBase.setProperty(SlcNames.SLC_GROUP_ID,
148 artifact.getGroupId());
149 }
150 JcrUtils.updateLastModified(artifactBase);
151
152 Node groupBase = artifactBase.getParent();
153 if (!groupBase.isNodeType(SlcTypes.SLC_GROUP_BASE)) {
154 // if (groupBase.isNodeType(SlcTypes.SLC_ARTIFACT_BASE)) {
155 // log.warn("Group base " + groupBase.getPath()
156 // + " is also artifact base");
157 // }
158 groupBase.addMixin(SlcTypes.SLC_GROUP_BASE);
159 groupBase.setProperty(SlcNames.SLC_GROUP_BASE_ID,
160 artifact.getGroupId());
161 }
162 JcrUtils.updateLastModifiedAndParents(groupBase,
163 RepoConstants.DEFAULT_ARTIFACTS_BASE_PATH);
164
165 if (log.isTraceEnabled())
166 log.trace("Indexed artifact " + artifact + " on " + fileNode);
167 } catch (Exception e) {
168 throw new SlcException("Cannot index artifact " + artifact
169 + " metadata on node " + fileNode, e);
170 }
171 }
172
173 private String getRelativePath(String nodePath) {
174 String basePath = RepoConstants.DEFAULT_ARTIFACTS_BASE_PATH;
175 if (!nodePath.startsWith(basePath))
176 return null;
177 String relativePath = nodePath.substring(basePath.length());
178 return relativePath;
179 }
180
181 public void setForce(Boolean force) {
182 this.force = force;
183 }
184
185 private String generatePomForBundle(Node n) throws RepositoryException {
186 StringBuffer p = new StringBuffer();
187 p.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
188 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");
189 p.append("<modelVersion>4.0.0</modelVersion>");
190
191 // Categorized name version
192 p.append("<groupId>").append(JcrUtils.get(n, SLC_GROUP_ID))
193 .append("</groupId>\n");
194 p.append("<artifactId>").append(JcrUtils.get(n, SLC_ARTIFACT_ID))
195 .append("</artifactId>\n");
196 p.append("<version>").append(JcrUtils.get(n, SLC_ARTIFACT_VERSION))
197 .append("</version>\n");
198 // TODO make it more generic
199 p.append("<packaging>jar</packaging>\n");
200 if (n.hasProperty(SLC_ + Constants.BUNDLE_NAME))
201 p.append("<name>")
202 .append(JcrUtils.get(n, SLC_ + Constants.BUNDLE_NAME))
203 .append("</name>\n");
204 if (n.hasProperty(SLC_ + Constants.BUNDLE_DESCRIPTION))
205 p.append("<description>")
206 .append(JcrUtils
207 .get(n, SLC_ + Constants.BUNDLE_DESCRIPTION))
208 .append("</description>\n");
209
210 // Dependencies in case of a distribution
211 if (n.isNodeType(SlcTypes.SLC_MODULAR_DISTRIBUTION)) {
212 p.append(getDependenciesSnippet(n.getNode(SlcNames.SLC_MODULES)
213 .getNodes()));
214 p.append(getDependencyManagementSnippet(n.getNode(
215 SlcNames.SLC_MODULES).getNodes()));
216 }
217 p.append("</project>\n");
218 return p.toString();
219 }
220
221 private String getDependenciesSnippet(NodeIterator nit)
222 throws RepositoryException {
223 StringBuilder b = new StringBuilder();
224 b.append("<dependencies>\n");
225 while (nit.hasNext()) {
226 Node currModule = nit.nextNode();
227 if (currModule.isNodeType(SlcTypes.SLC_MODULE_COORDINATES)) {
228 b.append(getDependencySnippet(
229 currModule.getProperty(SlcNames.SLC_CATEGORY)
230 .getString(),
231 currModule.getProperty(SlcNames.SLC_NAME).getString(),
232 null));
233 }
234 }
235 b.append("</dependencies>\n");
236 return b.toString();
237 }
238
239 private String getDependencyManagementSnippet(NodeIterator nit)
240 throws RepositoryException {
241 StringBuilder b = new StringBuilder();
242 b.append("<dependencyManagement>\n");
243 b.append("<dependencies>\n");
244 while (nit.hasNext()) {
245 Node currModule = nit.nextNode();
246 if (currModule.isNodeType(SlcTypes.SLC_MODULE_COORDINATES)) {
247 b.append(getDependencySnippet(
248 currModule.getProperty(SlcNames.SLC_CATEGORY)
249 .getString(),
250 currModule.getProperty(SlcNames.SLC_NAME).getString(),
251 currModule.getProperty(SlcNames.SLC_VERSION)
252 .getString()));
253 }
254 }
255 b.append("</dependencies>\n");
256 b.append("</dependencyManagement>\n");
257 return b.toString();
258 }
259
260 private String getDependencySnippet(String category, String name,
261 String version) {
262 StringBuilder b = new StringBuilder();
263 b.append("<dependency>\n");
264 b.append("\t<groupId>").append(category).append("</groupId>\n");
265 b.append("\t<artifactId>").append(name).append("</artifactId>\n");
266 if (version != null)
267 b.append("\t<version>").append(version).append("</version>\n");
268 b.append("</dependency>\n");
269 return b.toString();
270 }
271 }