1 package org
.argeo
.slc
.repo
;
3 import java
.io
.BufferedReader
;
4 import java
.io
.IOException
;
5 import java
.io
.InputStream
;
6 import java
.io
.InputStreamReader
;
7 import java
.util
.ArrayList
;
9 import java
.util
.StringTokenizer
;
10 import java
.util
.jar
.JarEntry
;
11 import java
.util
.jar
.JarInputStream
;
12 import java
.util
.jar
.Manifest
;
14 import javax
.jcr
.Binary
;
15 import javax
.jcr
.Node
;
16 import javax
.jcr
.Property
;
17 import javax
.jcr
.Session
;
18 import javax
.jcr
.nodetype
.NodeType
;
20 import org
.apache
.commons
.io
.FilenameUtils
;
21 import org
.apache
.commons
.logging
.Log
;
22 import org
.apache
.commons
.logging
.LogFactory
;
23 import org
.argeo
.jcr
.JcrUtils
;
24 import org
.argeo
.slc
.SlcException
;
25 import org
.argeo
.slc
.aether
.AetherUtils
;
26 import org
.argeo
.slc
.jcr
.SlcNames
;
27 import org
.argeo
.slc
.jcr
.SlcTypes
;
28 import org
.osgi
.framework
.Constants
;
29 import org
.sonatype
.aether
.artifact
.Artifact
;
32 * Index distribution bundles that is mainly dep artifacts that have generate a
33 * modular distribution csv index during maven build
35 public class DistributionBundleIndexer
implements NodeIndexer
{
36 private final static Log log
= LogFactory
37 .getLog(DistributionBundleIndexer
.class);
39 private final static String INDEX_FILE_NAME
= "modularDistribution.csv";
41 // private final String url;
43 private Manifest manifest
;
44 private String symbolicName
;
45 private String version
;
48 // private String baseUrl;
50 // private String relativeUrl;
52 private List
<Artifact
> artifacts
;
54 private String separator
= ",";
56 // public DistributionBundleIndexer(String url) {
60 // public DistributionBundleIndexer(String baseUrl, String relativeUrl) {
61 // if (baseUrl == null || !baseUrl.endsWith("/"))
62 // throw new SlcException("Base url " + baseUrl + " badly formatted");
63 // if (relativeUrl.startsWith("http") || relativeUrl.startsWith("file:"))
64 // throw new SlcException("Relative URL " + relativeUrl
65 // + " badly formatted");
66 // this.url = baseUrl + relativeUrl;
67 // this.baseUrl = baseUrl;
68 // this.relativeUrl = relativeUrl;
71 public Boolean
support(String path
) {
72 return FilenameUtils
.getExtension(path
).equals("jar");
75 public void index(Node fileNode
) {
76 JarInputStream jarIn
= null;
77 Binary fileBinary
= null;
79 if (!support(fileNode
.getPath()))
82 if (!fileNode
.isNodeType(NodeType
.NT_FILE
))
85 Session jcrSession
= fileNode
.getSession();
86 Node contentNode
= fileNode
.getNode(Node
.JCR_CONTENT
);
87 fileBinary
= contentNode
.getProperty(Property
.JCR_DATA
).getBinary();
88 jarIn
= new JarInputStream(fileBinary
.getStream());
91 manifest
= jarIn
.getManifest();
92 if (manifest
== null) {
93 log
.error(fileNode
+ " has no MANIFEST");
96 symbolicName
= manifest
.getMainAttributes().getValue(
97 Constants
.BUNDLE_SYMBOLICNAME
);
98 version
= manifest
.getMainAttributes().getValue(
99 Constants
.BUNDLE_VERSION
);
102 while ((indexEntry
= jarIn
.getNextJarEntry()) != null) {
103 String entryName
= indexEntry
.getName();
104 if (entryName
.equals(INDEX_FILE_NAME
)) {
111 if (indexEntry
== null)
112 return; // Not a modular definition artifact
114 // throw new SlcException("No index " + INDEX_FILE_NAME + " in "
115 // + fileNode.getPath());
118 artifacts
= listArtifacts(jarIn
);
120 if (artifacts
== null || artifacts
.isEmpty())
121 return; // no modules found
124 if (fileNode
.isNodeType(SlcTypes
.SLC_MODULAR_DISTRIBUTION
)) {
125 modules
= fileNode
.getNode(SlcNames
.SLC_MODULES
);
127 fileNode
.addMixin(SlcTypes
.SLC_MODULAR_DISTRIBUTION
);
128 modules
= JcrUtils
.mkdirs(fileNode
, SlcNames
.SLC_MODULES
,
129 NodeType
.NT_UNSTRUCTURED
);
132 for (Artifact artifact
: artifacts
) {
133 // TODO clean this once an overwrite policy has been
135 if (!modules
.hasNode(artifact
.getArtifactId())) {
136 Node moduleCoord
= modules
.addNode(
137 artifact
.getArtifactId(),
138 SlcTypes
.SLC_MODULE_COORDINATES
);
139 moduleCoord
.setProperty(SlcNames
.SLC_MODULE_NAME
,
140 artifact
.getArtifactId());
141 moduleCoord
.setProperty(SlcNames
.SLC_MODULE_VERSION
,
142 artifact
.getVersion());
143 String groupId
= artifact
.getGroupId();
144 if (groupId
!= null && !"".equals(groupId
.trim()))
145 moduleCoord
.setProperty(
146 SlcNames
.SLC_MODULE_CATEGORY
,
147 artifact
.getGroupId());
156 // won't work if distribution artifact is not listed
157 // for (int i = 0; i < artifacts.size(); i++) {
158 // OsgiArtifact osgiArtifact = artifacts.get(i);
159 // if (osgiArtifact.getSymbolicName().equals(symbolicName)
160 // && osgiArtifact.getVersion().equals(version)) {
161 // String relativeUrl = osgiArtifact.getRelativeUrl();
162 // if (url.endsWith(relativeUrl)) {
163 // baseUrl = url.substring(0, url.length()
164 // - osgiArtifact.getRelativeUrl().length());
169 } catch (Exception e
) {
170 throw new SlcException("Cannot list dependencies from " + fileNode
,
176 } catch (IOException e
) {
182 protected List
<Artifact
> listArtifacts(InputStream in
) {
183 List
<Artifact
> artifacts
= new ArrayList
<Artifact
>();
184 BufferedReader reader
= null;
186 reader
= new BufferedReader(new InputStreamReader(in
));
188 while ((line
= reader
.readLine()) != null) {
190 StringTokenizer st
= new StringTokenizer(line
, separator
);
191 String moduleName
= st
.nextToken();
192 String moduleVersion
= st
.nextToken();
193 String relativeUrl
= st
.nextToken();
196 // String Category = getCategoryFromRelativeUrl(relativeUrl,
199 artifacts
.add(AetherUtils
.convertPathToArtifact(relativeUrl
,
202 if (log
.isTraceEnabled())
203 log
.debug("Processed dependency: " + line
);
205 } catch (Exception e
) {
206 throw new SlcException("Cannot list artifacts", e
);
211 /** Relative path to the directories where the files will be stored */
212 private String
getCategoryFromRelativeUrl(String relativeUrl
,
214 int index
= relativeUrl
.indexOf("moduleName");
216 throw new SlcException("Unvalid relative URL: " + relativeUrl
217 + " for module " + moduleName
);
219 String result
= relativeUrl
.substring(0, index
- 1);
220 return result
.replace('/', '.');
224 * List full URLs of the bundles, based on base URL, usable directly for
227 // public List/* <String> */listUrls() {
228 // if (baseUrl == null)
229 // throw new SlcException("Base URL is not set");
231 // if (artifacts == null)
232 // throw new SlcException("Artifact list not initialized");
234 // List/* <String> */urls = new ArrayList();
235 // for (int i = 0; i < artifacts.size(); i++) {
236 // OsgiArtifact osgiArtifact = (OsgiArtifact) artifacts.get(i);
237 // urls.add(baseUrl + osgiArtifact.getRelativeUrl());
242 // public void setBaseUrl(String baseUrl) {
243 // this.baseUrl = baseUrl;
246 /** Separator used to parse the tabular file, default is "," */
247 public void setSeparator(String modulesUrlSeparator
) {
248 this.separator
= modulesUrlSeparator
;
251 // public String getRelativeUrl() {
252 // return relativeUrl;
255 /** One of the listed artifact */
256 protected static class OsgiArtifact
{
257 private final String category
;
258 private final String symbolicName
;
259 private final String version
;
260 private final String relativeUrl
;
262 public OsgiArtifact(String category
, String symbolicName
,
263 String version
, String relativeUrl
) {
265 this.category
= category
;
266 this.symbolicName
= symbolicName
;
267 this.version
= version
;
268 this.relativeUrl
= relativeUrl
;
271 public String
getCategory() {
275 public String
getSymbolicName() {
279 public String
getVersion() {
283 public String
getRelativeUrl() {