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
.RepositoryException
;
20 import javax
.jcr
.nodetype
.NodeType
;
22 import org
.apache
.commons
.logging
.Log
;
23 import org
.apache
.commons
.logging
.LogFactory
;
24 import org
.argeo
.jcr
.JcrUtils
;
25 import org
.argeo
.slc
.SlcException
;
26 import org
.argeo
.slc
.aether
.AetherUtils
;
27 import org
.argeo
.slc
.jcr
.SlcNames
;
28 import org
.argeo
.slc
.jcr
.SlcTypes
;
29 import org
.osgi
.framework
.Constants
;
30 import org
.sonatype
.aether
.artifact
.Artifact
;
33 * Add {@link Artifact} properties to a {@link Node}. Does nothing if the node
34 * name doesn't start with the artifact id (in order to skip Maven metadata XML
35 * files and other non artifact files).
37 public class ArtifactIndexer
implements NodeIndexer
, SlcNames
{
38 private Log log
= LogFactory
.getLog(ArtifactIndexer
.class);
39 private Boolean force
= false;
41 public Boolean
support(String path
) {
42 String relativePath
= getRelativePath(path
);
43 if (relativePath
== null)
45 Artifact artifact
= null;
47 artifact
= AetherUtils
.convertPathToArtifact(relativePath
, null);
48 } catch (Exception e
) {
49 if (log
.isTraceEnabled())
50 log
.trace("Malformed path " + path
+ ", skipping silently", e
);
52 return artifact
!= null;
55 public void index(Node fileNode
) {
56 Artifact artifact
= null;
58 if (!support(fileNode
.getPath()))
62 if (!force
&& fileNode
.isNodeType(SlcTypes
.SLC_ARTIFACT
))
65 if (!fileNode
.isNodeType(NodeType
.NT_FILE
))
68 String relativePath
= getRelativePath(fileNode
.getPath());
69 if (relativePath
== null)
71 artifact
= AetherUtils
.convertPathToArtifact(relativePath
, null);
72 // support() guarantees that artifact won't be null, no NPE check
73 fileNode
.addMixin(SlcTypes
.SLC_ARTIFACT
);
74 fileNode
.setProperty(SlcNames
.SLC_ARTIFACT_ID
,
75 artifact
.getArtifactId());
76 fileNode
.setProperty(SlcNames
.SLC_GROUP_ID
, artifact
.getGroupId());
77 fileNode
.setProperty(SlcNames
.SLC_ARTIFACT_VERSION
,
78 artifact
.getVersion());
79 fileNode
.setProperty(SlcNames
.SLC_ARTIFACT_EXTENSION
,
80 artifact
.getExtension());
81 // can be null but ok for JCR API
82 fileNode
.setProperty(SlcNames
.SLC_ARTIFACT_CLASSIFIER
,
83 artifact
.getClassifier());
84 JcrUtils
.updateLastModified(fileNode
);
86 // make sure there are checksums
87 String shaNodeName
= fileNode
.getName() + ".sha1";
88 if (!fileNode
.getParent().hasNode(shaNodeName
)) {
89 String sha
= JcrUtils
.checksumFile(fileNode
, "SHA-1");
90 JcrUtils
.copyBytesAsFile(fileNode
.getParent(), shaNodeName
,
93 String md5NodeName
= fileNode
.getName() + ".md5";
94 if (!fileNode
.getParent().hasNode(md5NodeName
)) {
95 String md5
= JcrUtils
.checksumFile(fileNode
, "MD5");
96 JcrUtils
.copyBytesAsFile(fileNode
.getParent(), md5NodeName
,
100 // Create a default pom only with artifact coordinates if none
102 String fileNodeName
= fileNode
.getName();
103 String pomName
= null;
104 if (fileNodeName
.endsWith(".jar"))
105 pomName
= fileNodeName
.substring(0, fileNodeName
.length()-".jar".length()) + ".pom";
107 if (pomName
!= null && !fileNode
.getParent().hasNode(pomName
)) {
108 String pom
= generatePomForBundle(fileNode
);
109 Node pomNode
= JcrUtils
.copyBytesAsFile(fileNode
.getParent(),
110 pomName
, pom
.getBytes());
111 // corresponding check sums
112 String sha
= JcrUtils
.checksumFile(pomNode
, "SHA-1");
113 JcrUtils
.copyBytesAsFile(fileNode
.getParent(), pomName
+ ".sha1",
115 String md5
= JcrUtils
.checksumFile(fileNode
, "MD5");
116 JcrUtils
.copyBytesAsFile(fileNode
.getParent(), pomName
+".md5",
121 Node artifactVersionBase
= fileNode
.getParent();
122 if (!artifactVersionBase
123 .isNodeType(SlcTypes
.SLC_ARTIFACT_VERSION_BASE
)) {
125 .addMixin(SlcTypes
.SLC_ARTIFACT_VERSION_BASE
);
126 artifactVersionBase
.setProperty(SlcNames
.SLC_ARTIFACT_VERSION
,
127 artifact
.getBaseVersion());
128 artifactVersionBase
.setProperty(SlcNames
.SLC_ARTIFACT_ID
,
129 artifact
.getArtifactId());
130 artifactVersionBase
.setProperty(SlcNames
.SLC_GROUP_ID
,
131 artifact
.getGroupId());
133 JcrUtils
.updateLastModified(artifactVersionBase
);
136 if (artifact
.getExtension().equals("pom")) {
137 // TODO read to make it a distribution
140 Node artifactBase
= artifactVersionBase
.getParent();
141 if (!artifactBase
.isNodeType(SlcTypes
.SLC_ARTIFACT_BASE
)) {
142 artifactBase
.addMixin(SlcTypes
.SLC_ARTIFACT_BASE
);
143 artifactBase
.setProperty(SlcNames
.SLC_ARTIFACT_ID
,
144 artifact
.getArtifactId());
145 artifactBase
.setProperty(SlcNames
.SLC_GROUP_ID
,
146 artifact
.getGroupId());
148 JcrUtils
.updateLastModified(artifactBase
);
150 Node groupBase
= artifactBase
.getParent();
151 if (!groupBase
.isNodeType(SlcTypes
.SLC_GROUP_BASE
)) {
152 // if (groupBase.isNodeType(SlcTypes.SLC_ARTIFACT_BASE)) {
153 // log.warn("Group base " + groupBase.getPath()
154 // + " is also artifact base");
156 groupBase
.addMixin(SlcTypes
.SLC_GROUP_BASE
);
157 groupBase
.setProperty(SlcNames
.SLC_GROUP_BASE_ID
,
158 artifact
.getGroupId());
160 JcrUtils
.updateLastModifiedAndParents(groupBase
,
161 RepoConstants
.DEFAULT_ARTIFACTS_BASE_PATH
);
163 if (log
.isTraceEnabled())
164 log
.trace("Indexed artifact " + artifact
+ " on " + fileNode
);
165 } catch (Exception e
) {
166 throw new SlcException("Cannot index artifact " + artifact
167 + " metadata on node " + fileNode
, e
);
171 private String
getRelativePath(String nodePath
) {
172 String basePath
= RepoConstants
.DEFAULT_ARTIFACTS_BASE_PATH
;
173 if (!nodePath
.startsWith(basePath
))
175 String relativePath
= nodePath
.substring(basePath
.length());
179 public void setForce(Boolean force
) {
183 private String
generatePomForBundle(Node n
) throws RepositoryException
{
184 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>");
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 p
.append("<packaging>pom</packaging>\n");
199 if (n
.hasProperty(SLC_
+ Constants
.BUNDLE_NAME
))
201 .append(JcrUtils
.get(n
, SLC_
+ Constants
.BUNDLE_NAME
))
202 .append("</name>\n");
203 if (n
.hasProperty(SLC_
+ Constants
.BUNDLE_DESCRIPTION
))
204 p
.append("<description>")
206 .get(n
, SLC_
+ Constants
.BUNDLE_DESCRIPTION
))
207 .append("</description>\n");
208 p
.append("</project>\n");