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_NAME
,
140 artifact
.getArtifactId());
141 moduleCoord
.setProperty(SlcNames
.SLC_VERSION
,
142 artifact
.getVersion());
143 String groupId
= artifact
.getGroupId();
144 if (groupId
!= null && !"".equals(groupId
.trim()))
145 moduleCoord
.setProperty(SlcNames
.SLC_CATEGORY
,
146 artifact
.getGroupId());
155 // won't work if distribution artifact is not listed
156 // for (int i = 0; i < artifacts.size(); i++) {
157 // OsgiArtifact osgiArtifact = artifacts.get(i);
158 // if (osgiArtifact.getSymbolicName().equals(symbolicName)
159 // && osgiArtifact.getVersion().equals(version)) {
160 // String relativeUrl = osgiArtifact.getRelativeUrl();
161 // if (url.endsWith(relativeUrl)) {
162 // baseUrl = url.substring(0, url.length()
163 // - osgiArtifact.getRelativeUrl().length());
168 } catch (Exception e
) {
169 throw new SlcException("Cannot list dependencies from " + fileNode
,
175 } catch (IOException e
) {
181 protected List
<Artifact
> listArtifacts(InputStream in
) {
182 List
<Artifact
> artifacts
= new ArrayList
<Artifact
>();
183 BufferedReader reader
= null;
185 reader
= new BufferedReader(new InputStreamReader(in
));
187 while ((line
= reader
.readLine()) != null) {
189 StringTokenizer st
= new StringTokenizer(line
, separator
);
190 // String moduleName =
192 // String moduleVersion =
194 String relativeUrl
= st
.nextToken();
197 // String Category = getCategoryFromRelativeUrl(relativeUrl,
200 artifacts
.add(AetherUtils
.convertPathToArtifact(relativeUrl
,
203 if (log
.isTraceEnabled())
204 log
.debug("Processed dependency: " + line
);
206 } catch (Exception e
) {
207 throw new SlcException("Cannot list artifacts", e
);
212 // /** Relative path to the directories where the files will be stored */
213 // private String getCategoryFromRelativeUrl(String relativeUrl,
214 // String moduleName) {
215 // int index = relativeUrl.indexOf("moduleName");
217 // throw new SlcException("Unvalid relative URL: " + relativeUrl
218 // + " for module " + moduleName);
219 // // Remove trailing /
220 // String result = relativeUrl.substring(0, index - 1);
221 // return result.replace('/', '.');
225 * List full URLs of the bundles, based on base URL, usable directly for
228 // public List/* <String> */listUrls() {
229 // if (baseUrl == null)
230 // throw new SlcException("Base URL is not set");
232 // if (artifacts == null)
233 // throw new SlcException("Artifact list not initialized");
235 // List/* <String> */urls = new ArrayList();
236 // for (int i = 0; i < artifacts.size(); i++) {
237 // OsgiArtifact osgiArtifact = (OsgiArtifact) artifacts.get(i);
238 // urls.add(baseUrl + osgiArtifact.getRelativeUrl());
243 // public void setBaseUrl(String baseUrl) {
244 // this.baseUrl = baseUrl;
247 /** Separator used to parse the tabular file, default is "," */
248 public void setSeparator(String modulesUrlSeparator
) {
249 this.separator
= modulesUrlSeparator
;
252 // public String getRelativeUrl() {
253 // return relativeUrl;
256 /** One of the listed artifact */
257 protected static class OsgiArtifact
{
258 private final String category
;
259 private final String symbolicName
;
260 private final String version
;
261 private final String relativeUrl
;
263 public OsgiArtifact(String category
, String symbolicName
,
264 String version
, String relativeUrl
) {
266 this.category
= category
;
267 this.symbolicName
= symbolicName
;
268 this.version
= version
;
269 this.relativeUrl
= relativeUrl
;
272 public String
getCategory() {
276 public String
getSymbolicName() {
280 public String
getVersion() {
284 public String
getRelativeUrl() {