1 package org
.argeo
.slc
.osgi
.build
;
4 import java
.util
.ArrayList
;
5 import java
.util
.Enumeration
;
6 import java
.util
.HashSet
;
9 import java
.util
.SortedMap
;
10 import java
.util
.StringTokenizer
;
11 import java
.util
.TreeMap
;
12 import java
.util
.jar
.JarInputStream
;
13 import java
.util
.jar
.Manifest
;
15 import org
.apache
.commons
.io
.IOUtils
;
16 import org
.apache
.commons
.logging
.Log
;
17 import org
.apache
.commons
.logging
.LogFactory
;
18 import org
.argeo
.slc
.SlcException
;
19 import org
.argeo
.slc
.UnsupportedException
;
20 import org
.argeo
.slc
.build
.BasicNameVersion
;
21 import org
.argeo
.slc
.build
.Distribution
;
22 import org
.argeo
.slc
.build
.ModularDistribution
;
23 import org
.argeo
.slc
.build
.NameVersion
;
24 import org
.argeo
.slc
.core
.build
.VersionedResourceDistribution
;
25 import org
.osgi
.framework
.BundleContext
;
26 import org
.osgi
.framework
.Constants
;
27 import org
.springframework
.beans
.factory
.InitializingBean
;
28 import org
.springframework
.context
.ResourceLoaderAware
;
29 import org
.springframework
.core
.io
.ResourceLoader
;
30 import org
.springframework
.osgi
.context
.BundleContextAware
;
32 public class BundleModularDistribution
implements ModularDistribution
,
33 BundleContextAware
, InitializingBean
, ResourceLoaderAware
{
34 private final static Log log
= LogFactory
35 .getLog(BundleModularDistribution
.class);
37 private BundleContext bundleContext
;
38 private ResourceLoader resourceLoader
;
40 private String libDirectory
= "/lib";
41 private EclipseUpdateSite eclipseUpdateSite
;
43 /** Initialized by the object itself. */
44 private SortedMap
<NameVersion
, VersionedResourceDistribution
> distributions
= new TreeMap
<NameVersion
, VersionedResourceDistribution
>();
46 public Distribution
getModuleDistribution(String moduleName
,
47 String moduleVersion
) {
49 .get(new BasicNameVersion(moduleName
, moduleVersion
));
50 // URL url = findModule(moduleName, moduleVersion);
51 // return new ResourceDistribution(new UrlResource(url));
54 @SuppressWarnings(value
= { "unchecked" })
55 protected URL
findModule(String moduleName
, String version
) {
56 Enumeration
<URL
> urls
= (Enumeration
<URL
>) bundleContext
.getBundle()
57 .findEntries(libDirectory
, moduleName
+ "*", false);
59 if (!urls
.hasMoreElements())
60 throw new SlcException("Cannot find module " + moduleName
);
62 URL url
= urls
.nextElement();
64 // TODO: check version as well
65 if (urls
.hasMoreElements())
66 throw new SlcException("More than one module with name "
71 public String
getDistributionId() {
72 return bundleContext
.getBundle().getSymbolicName()
74 + bundleContext
.getBundle().getHeaders().get(
75 Constants
.BUNDLE_VERSION
);
78 public Set
<NameVersion
> listModulesNameVersions() {
79 return distributions
.keySet();
82 public void setBundleContext(BundleContext bundleContext
) {
83 this.bundleContext
= bundleContext
;
86 @SuppressWarnings(value
= { "unchecked" })
87 public void afterPropertiesSet() throws Exception
{
88 Enumeration
<URL
> urls
= (Enumeration
<URL
>) bundleContext
.getBundle()
89 .findEntries(libDirectory
, "*.jar", false);
90 while (urls
.hasMoreElements()) {
91 URL url
= urls
.nextElement();
92 JarInputStream in
= null;
94 in
= new JarInputStream(url
.openStream());
95 Manifest mf
= in
.getManifest();
96 String name
= mf
.getMainAttributes().getValue(
97 Constants
.BUNDLE_SYMBOLICNAME
);
98 // Skip additional specs such as
100 if (name
.indexOf(';') > -1) {
101 name
= new StringTokenizer(name
, " ;").nextToken();
104 String version
= mf
.getMainAttributes().getValue(
105 Constants
.BUNDLE_VERSION
);
106 BasicNameVersion nameVersion
= new BasicNameVersion(name
,
108 distributions
.put(nameVersion
,
109 new VersionedResourceDistribution(name
, version
,
110 resourceLoader
.getResource(url
.toString())));
112 IOUtils
.closeQuietly(in
);
115 if (log
.isDebugEnabled())
116 log
.debug("Distribution " + getName() + ":" + getVersion()
117 + " loaded (" + distributions
.size() + " modules)");
121 protected String
findVersion(String name
) {
122 Set
<String
> versions
= new HashSet
<String
>();
123 for (NameVersion key
: distributions
.keySet()) {
124 if (key
.getName().equals(name
))
125 versions
.add(key
.getVersion());
128 if (versions
.size() == 0)
129 throw new SlcException("Cannot find version for name " + name
);
130 else if (versions
.size() > 1)
131 throw new SlcException("Found more than one version for name "
132 + name
+ ": " + versions
);
134 return versions
.iterator().next();
138 public void setLibDirectory(String libDirectory
) {
139 this.libDirectory
= libDirectory
;
142 public Object
getDescriptor(String descriptorType
) {
143 if (descriptorType
.equals("eclipse"))
144 return writeEclipseUpdateSite();
146 throw new UnsupportedException("descriptorType", descriptorType
);
149 protected Set
<NameVersion
> writePlainUrlList() {
150 return distributions
.keySet();
153 protected String
writeEclipseUpdateSite() {
154 if (eclipseUpdateSite
== null)
155 throw new SlcException("No eclipse update site declared.");
157 StringBuffer buf
= new StringBuffer("");
158 buf
.append("<site>");
160 List
<EclipseUpdateSiteCategory
> usedCategories
= new ArrayList
<EclipseUpdateSiteCategory
>();
161 for (EclipseUpdateSiteFeature feature
: eclipseUpdateSite
.getFeatures()) {
163 String featureId
= feature
.getName();
164 String featureVersion
= findVersion(featureId
);
165 buf
.append("<feature");
166 buf
.append(" url=\"features/").append(featureId
).append('_')
167 .append(featureVersion
).append(".jar\"");
168 buf
.append(" id=\"").append(featureId
).append("\"");
169 buf
.append(" version=\"").append(featureVersion
).append("\"");
172 for (EclipseUpdateSiteCategory category
: feature
.getCategories()) {
173 usedCategories
.add(category
);
174 buf
.append(" <category name=\"").append(category
.getName())
177 buf
.append("</feature>\n\n");
180 for (EclipseUpdateSiteCategory category
: usedCategories
) {
181 buf
.append("<category-def");
182 buf
.append(" name=\"").append(category
.getName()).append("\"");
183 buf
.append(" label=\"").append(category
.getLabel()).append("\"");
185 buf
.append(" <description>").append(category
.getDescription())
186 .append("</description>\n");
187 buf
.append("</category-def>\n\n");
190 buf
.append("</site>");
191 return buf
.toString();
194 public void setResourceLoader(ResourceLoader resourceLoader
) {
195 this.resourceLoader
= resourceLoader
;
198 public String
getName() {
199 return bundleContext
.getBundle().getSymbolicName();
202 public String
getVersion() {
203 return bundleContext
.getBundle().getHeaders().get(
204 Constants
.BUNDLE_VERSION
).toString();
208 public String
toString() {
209 return new BasicNameVersion(this).toString();
212 public void setEclipseUpdateSite(EclipseUpdateSite eclipseUpdateSite
) {
213 this.eclipseUpdateSite
= eclipseUpdateSite
;