]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.osgi.boot/src/org/argeo/osgi/a2/ProvisioningManager.java
Remove reference to 'argeo' user.
[lgpl/argeo-commons.git] / org.argeo.osgi.boot / src / org / argeo / osgi / a2 / ProvisioningManager.java
1 package org.argeo.osgi.a2;
2
3 import java.io.File;
4 import java.net.URI;
5 import java.nio.file.Path;
6 import java.nio.file.Paths;
7 import java.util.ArrayList;
8 import java.util.Collection;
9 import java.util.Collections;
10 import java.util.HashMap;
11 import java.util.HashSet;
12 import java.util.List;
13 import java.util.Map;
14 import java.util.Set;
15
16 import org.argeo.osgi.boot.OsgiBootUtils;
17 import org.eclipse.osgi.launch.EquinoxFactory;
18 import org.osgi.framework.Bundle;
19 import org.osgi.framework.BundleContext;
20 import org.osgi.framework.Constants;
21 import org.osgi.framework.Version;
22 import org.osgi.framework.launch.Framework;
23 import org.osgi.framework.wiring.FrameworkWiring;
24
25 /** Loads provisioning sources into an OSGi context. */
26 public class ProvisioningManager {
27 BundleContext bc;
28 OsgiContext osgiContext;
29 List<ProvisioningSource> sources = Collections.synchronizedList(new ArrayList<>());
30
31 public ProvisioningManager(BundleContext bc) {
32 this.bc = bc;
33 osgiContext = new OsgiContext(bc);
34 osgiContext.load();
35 }
36
37 protected void addSource(ProvisioningSource source) {
38 sources.add(source);
39 }
40
41 void installWholeSource(ProvisioningSource source) {
42 Set<Bundle> updatedBundles = new HashSet<>();
43 for (A2Contribution contribution : source.listContributions(null)) {
44 for (A2Component component : contribution.components.values()) {
45 A2Module module = component.last().last();
46 Bundle bundle = installOrUpdate(module);
47 if (bundle != null)
48 updatedBundles.add(bundle);
49 }
50 }
51 FrameworkWiring frameworkWiring = bc.getBundle(0).adapt(FrameworkWiring.class);
52 frameworkWiring.refreshBundles(updatedBundles);
53 }
54
55 public void registerSource(String uri) {
56 try {
57 URI u = new URI(uri);
58 if (A2Source.SCHEME_A2.equals(u.getScheme())) {
59 if (u.getHost() == null || "".equals(u.getHost())) {
60 String baseStr = u.getPath();
61 if (File.separatorChar == '\\') {// MS Windows
62 baseStr = baseStr.substring(1).replace('/', File.separatorChar);
63 }
64 Path base = Paths.get(baseStr);
65 FsA2Source source = new FsA2Source(base);
66 source.load();
67 addSource(source);
68 }
69 }
70 } catch (Exception e) {
71 throw new A2Exception("Cannot add source " + uri, e);
72 }
73 }
74
75 public boolean registerDefaultSource() {
76 String frameworkLocation = bc.getProperty("osgi.framework");
77 try {
78 URI frameworkLocationUri = new URI(frameworkLocation);
79 if ("file".equals(frameworkLocationUri.getScheme())) {
80 Path frameworkPath = Paths.get(frameworkLocationUri);
81 if (frameworkPath.getParent().getFileName().toString().equals(A2Contribution.BOOT)) {
82 Path base = frameworkPath.getParent().getParent();
83 String baseStr = base.toString();
84 if (File.separatorChar == '\\')// MS Windows
85 baseStr = '/' + baseStr.replace(File.separatorChar, '/');
86 URI baseUri = new URI(A2Source.SCHEME_A2, null, null, 0, baseStr, null, null);
87 registerSource(baseUri.toString());
88 OsgiBootUtils.info("Registered " + baseUri + " as default source");
89 return true;
90 }
91 }
92 } catch (Exception e) {
93 OsgiBootUtils.error("Cannot register default source based on framework location " + frameworkLocation, e);
94 }
95 return false;
96 }
97
98 public void install(String spec) {
99 if (spec == null) {
100 for (ProvisioningSource source : sources) {
101 installWholeSource(source);
102 }
103 }
104 }
105
106 /** @return the new/updated bundle, or null if nothing was done. */
107 protected Bundle installOrUpdate(A2Module module) {
108 try {
109 ProvisioningSource moduleSource = module.getBranch().getComponent().getContribution().getSource();
110 Version moduleVersion = module.getVersion();
111 A2Branch osgiBranch = osgiContext.findBranch(module.getBranch().getComponent().getId(), moduleVersion);
112 if (osgiBranch == null) {
113 // Bundle bundle = bc.installBundle(module.getBranch().getCoordinates(),
114 // moduleSource.newInputStream(module.getLocator()));
115 Bundle bundle = moduleSource.install(bc, module);
116 if (OsgiBootUtils.isDebug())
117 OsgiBootUtils.debug("Installed bundle " + bundle.getLocation() + " with version " + moduleVersion);
118 return bundle;
119 } else {
120 A2Module lastOsgiModule = osgiBranch.last();
121 int compare = moduleVersion.compareTo(lastOsgiModule.getVersion());
122 if (compare > 0) {// update
123 Bundle bundle = (Bundle) lastOsgiModule.getLocator();
124 // bundle.update(moduleSource.newInputStream(module.getLocator()));
125 moduleSource.update(bundle, module);
126 OsgiBootUtils.info("Updated bundle " + bundle.getLocation() + " to version " + moduleVersion);
127 return bundle;
128 }
129 }
130 } catch (Exception e) {
131 OsgiBootUtils.error("Could not install module " + module + ": " + e.getMessage(), e);
132 }
133 return null;
134 }
135
136 public Collection<Bundle> update() {
137 boolean fragmentsUpdated = false;
138 Set<Bundle> updatedBundles = new HashSet<>();
139 bundles: for (Bundle bundle : bc.getBundles()) {
140 for (ProvisioningSource source : sources) {
141 String componentId = bundle.getSymbolicName();
142 Version version = bundle.getVersion();
143 A2Branch branch = source.findBranch(componentId, version);
144 if (branch == null)
145 continue bundles;
146 A2Module module = branch.last();
147 Version moduleVersion = module.getVersion();
148 int compare = moduleVersion.compareTo(version);
149 if (compare > 0) {// update
150 try {
151 source.update(bundle, module);
152 // bundle.update(in);
153 String fragmentHost = bundle.getHeaders().get(Constants.FRAGMENT_HOST);
154 if (fragmentHost != null)
155 fragmentsUpdated = true;
156 OsgiBootUtils.info("Updated bundle " + bundle.getLocation() + " to version " + moduleVersion);
157 updatedBundles.add(bundle);
158 } catch (Exception e) {
159 OsgiBootUtils.error("Cannot update with module " + module, e);
160 }
161 }
162 }
163 }
164 FrameworkWiring frameworkWiring = bc.getBundle(0).adapt(FrameworkWiring.class);
165 if (fragmentsUpdated)// refresh all
166 frameworkWiring.refreshBundles(null);
167 else
168 frameworkWiring.refreshBundles(updatedBundles);
169 return updatedBundles;
170 }
171
172 public static void main(String[] args) {
173 Map<String, String> configuration = new HashMap<>();
174 configuration.put("osgi.console", "2323");
175 Framework framework = OsgiBootUtils.launch(new EquinoxFactory(), configuration);
176 try {
177 ProvisioningManager pm = new ProvisioningManager(framework.getBundleContext());
178 FsA2Source context = new FsA2Source(Paths.get(
179 "/home/mbaudier/dev/git/apache2/argeo-commons/dist/argeo-node/target/argeo-node-2.1.74-SNAPSHOT/argeo-node/share/osgi"));
180 context.load();
181 if (framework.getBundleContext().getBundles().length == 1) {// initial
182 pm.install(null);
183 } else {
184 pm.update();
185 }
186 } catch (Exception e) {
187 e.printStackTrace();
188 } finally {
189 try {
190 // framework.stop();
191 } catch (Exception e) {
192 e.printStackTrace();
193 }
194 }
195 }
196
197 }