1 package org
.argeo
.osgi
.a2
;
5 import java
.nio
.file
.Files
;
6 import java
.nio
.file
.Path
;
7 import java
.nio
.file
.Paths
;
8 import java
.util
.ArrayList
;
9 import java
.util
.Collection
;
10 import java
.util
.Collections
;
11 import java
.util
.HashMap
;
12 import java
.util
.HashSet
;
13 import java
.util
.List
;
17 import org
.argeo
.osgi
.boot
.OsgiBootUtils
;
18 import org
.eclipse
.osgi
.launch
.EquinoxFactory
;
19 import org
.osgi
.framework
.Bundle
;
20 import org
.osgi
.framework
.BundleContext
;
21 import org
.osgi
.framework
.Constants
;
22 import org
.osgi
.framework
.Version
;
23 import org
.osgi
.framework
.launch
.Framework
;
24 import org
.osgi
.framework
.wiring
.FrameworkWiring
;
26 /** Loads provisioning sources into an OSGi context. */
27 public class ProvisioningManager
{
29 OsgiContext osgiContext
;
30 List
<ProvisioningSource
> sources
= Collections
.synchronizedList(new ArrayList
<>());
32 public ProvisioningManager(BundleContext bc
) {
34 osgiContext
= new OsgiContext(bc
);
38 protected void addSource(ProvisioningSource source
) {
42 void installWholeSource(ProvisioningSource source
) {
43 Set
<Bundle
> updatedBundles
= new HashSet
<>();
44 for (A2Contribution contribution
: source
.listContributions(null)) {
45 for (A2Component component
: contribution
.components
.values()) {
46 A2Module module
= component
.last().last();
47 Bundle bundle
= installOrUpdate(module
);
49 updatedBundles
.add(bundle
);
52 FrameworkWiring frameworkWiring
= bc
.getBundle(0).adapt(FrameworkWiring
.class);
53 frameworkWiring
.refreshBundles(updatedBundles
);
56 public void registerSource(String uri
) {
59 if (A2Source
.SCHEME_A2
.equals(u
.getScheme())) {
60 if (u
.getHost() == null || "".equals(u
.getHost())) {
61 String baseStr
= u
.getPath();
62 if (File
.separatorChar
== '\\') {// MS Windows
63 baseStr
= baseStr
.substring(1).replace('/', File
.separatorChar
);
65 Path base
= Paths
.get(baseStr
);
66 if (Files
.exists(base
)) {
67 FsA2Source source
= new FsA2Source(base
);
70 OsgiBootUtils
.info("Registered " + uri
+ " as source");
74 } catch (Exception e
) {
75 throw new A2Exception("Cannot add source " + uri
, e
);
79 public boolean registerDefaultSource() {
80 String frameworkLocation
= bc
.getProperty("osgi.framework");
82 URI frameworkLocationUri
= new URI(frameworkLocation
);
83 if ("file".equals(frameworkLocationUri
.getScheme())) {
84 Path frameworkPath
= Paths
.get(frameworkLocationUri
);
85 if (frameworkPath
.getParent().getFileName().toString().equals(A2Contribution
.BOOT
)) {
86 Path base
= frameworkPath
.getParent().getParent();
87 String baseStr
= base
.toString();
88 if (File
.separatorChar
== '\\')// MS Windows
89 baseStr
= '/' + baseStr
.replace(File
.separatorChar
, '/');
90 URI baseUri
= new URI(A2Source
.SCHEME_A2
, null, null, 0, baseStr
, null, null);
91 registerSource(baseUri
.toString());
92 OsgiBootUtils
.debug("Default source from framework location " + frameworkLocation
);
96 } catch (Exception e
) {
97 OsgiBootUtils
.error("Cannot register default source based on framework location " + frameworkLocation
, e
);
102 public void install(String spec
) {
104 for (ProvisioningSource source
: sources
) {
105 installWholeSource(source
);
110 /** @return the new/updated bundle, or null if nothing was done. */
111 protected Bundle
installOrUpdate(A2Module module
) {
113 ProvisioningSource moduleSource
= module
.getBranch().getComponent().getContribution().getSource();
114 Version moduleVersion
= module
.getVersion();
115 A2Branch osgiBranch
= osgiContext
.findBranch(module
.getBranch().getComponent().getId(), moduleVersion
);
116 if (osgiBranch
== null) {
117 // Bundle bundle = bc.installBundle(module.getBranch().getCoordinates(),
118 // moduleSource.newInputStream(module.getLocator()));
119 Bundle bundle
= moduleSource
.install(bc
, module
);
120 if (OsgiBootUtils
.isDebug())
121 OsgiBootUtils
.debug("Installed bundle " + bundle
.getLocation() + " with version " + moduleVersion
);
124 A2Module lastOsgiModule
= osgiBranch
.last();
125 int compare
= moduleVersion
.compareTo(lastOsgiModule
.getVersion());
126 if (compare
> 0) {// update
127 Bundle bundle
= (Bundle
) lastOsgiModule
.getLocator();
128 // bundle.update(moduleSource.newInputStream(module.getLocator()));
129 moduleSource
.update(bundle
, module
);
130 OsgiBootUtils
.info("Updated bundle " + bundle
.getLocation() + " to version " + moduleVersion
);
134 } catch (Exception e
) {
135 OsgiBootUtils
.error("Could not install module " + module
+ ": " + e
.getMessage(), e
);
140 public Collection
<Bundle
> update() {
141 boolean fragmentsUpdated
= false;
142 Set
<Bundle
> updatedBundles
= new HashSet
<>();
143 bundles
: for (Bundle bundle
: bc
.getBundles()) {
144 for (ProvisioningSource source
: sources
) {
145 String componentId
= bundle
.getSymbolicName();
146 Version version
= bundle
.getVersion();
147 A2Branch branch
= source
.findBranch(componentId
, version
);
150 A2Module module
= branch
.last();
151 Version moduleVersion
= module
.getVersion();
152 int compare
= moduleVersion
.compareTo(version
);
153 if (compare
> 0) {// update
155 source
.update(bundle
, module
);
156 // bundle.update(in);
157 String fragmentHost
= bundle
.getHeaders().get(Constants
.FRAGMENT_HOST
);
158 if (fragmentHost
!= null)
159 fragmentsUpdated
= true;
160 OsgiBootUtils
.info("Updated bundle " + bundle
.getLocation() + " to version " + moduleVersion
);
161 updatedBundles
.add(bundle
);
162 } catch (Exception e
) {
163 OsgiBootUtils
.error("Cannot update with module " + module
, e
);
168 FrameworkWiring frameworkWiring
= bc
.getBundle(0).adapt(FrameworkWiring
.class);
169 if (fragmentsUpdated
)// refresh all
170 frameworkWiring
.refreshBundles(null);
172 frameworkWiring
.refreshBundles(updatedBundles
);
173 return updatedBundles
;
176 public static void main(String
[] args
) {
177 Map
<String
, String
> configuration
= new HashMap
<>();
178 configuration
.put("osgi.console", "2323");
179 Framework framework
= OsgiBootUtils
.launch(new EquinoxFactory(), configuration
);
181 ProvisioningManager pm
= new ProvisioningManager(framework
.getBundleContext());
182 FsA2Source context
= new FsA2Source(Paths
.get(
183 "/home/mbaudier/dev/git/apache2/argeo-commons/dist/argeo-node/target/argeo-node-2.1.74-SNAPSHOT/argeo-node/share/osgi"));
185 if (framework
.getBundleContext().getBundles().length
== 1) {// initial
190 } catch (Exception e
) {
195 } catch (Exception e
) {