2 * Copyright (C) 2007-2012 Argeo GmbH
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package org
.argeo
.slc
.repo
;
18 import javax
.jcr
.Node
;
19 import javax
.jcr
.NodeIterator
;
20 import javax
.jcr
.RepositoryException
;
21 import javax
.jcr
.nodetype
.NodeType
;
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
;
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).
38 public class ArtifactIndexer
implements NodeIndexer
, SlcNames
{
39 private Log log
= LogFactory
.getLog(ArtifactIndexer
.class);
40 private Boolean force
= false;
42 public Boolean
support(String path
) {
43 String relativePath
= getRelativePath(path
);
44 if (relativePath
== null)
46 Artifact artifact
= null;
48 artifact
= AetherUtils
.convertPathToArtifact(relativePath
, null);
49 } catch (Exception e
) {
50 if (log
.isTraceEnabled())
51 log
.trace("Malformed path " + path
+ ", skipping silently", e
);
53 return artifact
!= null;
56 public void index(Node fileNode
) {
57 Artifact artifact
= null;
59 if (!support(fileNode
.getPath()))
63 if (!force
&& fileNode
.isNodeType(SlcTypes
.SLC_ARTIFACT
))
66 if (!fileNode
.isNodeType(NodeType
.NT_FILE
))
69 String relativePath
= getRelativePath(fileNode
.getPath());
70 if (relativePath
== null)
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
);
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
,
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
,
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()
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());
123 Node artifactVersionBase
= fileNode
.getParent();
124 if (!artifactVersionBase
125 .isNodeType(SlcTypes
.SLC_ARTIFACT_VERSION_BASE
)) {
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());
135 JcrUtils
.updateLastModified(artifactVersionBase
);
138 if (artifact
.getExtension().equals("pom")) {
139 // TODO read to make it a distribution
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());
150 JcrUtils
.updateLastModified(artifactBase
);
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");
158 groupBase
.addMixin(SlcTypes
.SLC_GROUP_BASE
);
159 groupBase
.setProperty(SlcNames
.SLC_GROUP_BASE_ID
,
160 artifact
.getGroupId());
162 JcrUtils
.updateLastModifiedAndParents(groupBase
,
163 RepoConstants
.DEFAULT_ARTIFACTS_BASE_PATH
);
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
);
173 private String
getRelativePath(String nodePath
) {
174 String basePath
= RepoConstants
.DEFAULT_ARTIFACTS_BASE_PATH
;
175 if (!nodePath
.startsWith(basePath
))
177 String relativePath
= nodePath
.substring(basePath
.length());
181 public void setForce(Boolean force
) {
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>");
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
))
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>")
207 .get(n
, SLC_
+ Constants
.BUNDLE_DESCRIPTION
))
208 .append("</description>\n");
210 // Dependencies in case of a distribution
211 if (n
.isNodeType(SlcTypes
.SLC_MODULAR_DISTRIBUTION
)) {
212 p
.append(getDependenciesSnippet(n
.getNode(SlcNames
.SLC_MODULES
)
214 p
.append(getDependencyManagementSnippet(n
.getNode(
215 SlcNames
.SLC_MODULES
).getNodes()));
217 p
.append("</project>\n");
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
)
231 currModule
.getProperty(SlcNames
.SLC_NAME
).getString(),
235 b
.append("</dependencies>\n");
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
)
250 currModule
.getProperty(SlcNames
.SLC_NAME
).getString(),
251 currModule
.getProperty(SlcNames
.SLC_VERSION
)
255 b
.append("</dependencies>\n");
256 b
.append("</dependencyManagement>\n");
260 private String
getDependencySnippet(String category
, String name
,
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");
267 b
.append("\t<version>").append(version
).append("</version>\n");
268 b
.append("</dependency>\n");