blob: d201e7de46bf8cfce5e0f7b62fe8862827b845c4 [file] [log] [blame]
Richard S. Hall930fecc2005-08-16 18:33:34 +00001/*
2 * Copyright 2005 The Apache Software Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17package org.apache.osgi.framework;
18
19import java.io.InputStream;
20import java.security.AccessController;
21import java.security.PrivilegedAction;
22import java.util.*;
23
24import org.apache.osgi.framework.searchpolicy.*;
25import org.apache.osgi.framework.util.CaseInsensitiveMap;
26import org.apache.osgi.framework.util.FelixConstants;
27import org.apache.osgi.moduleloader.LibrarySource;
28import org.apache.osgi.moduleloader.ResourceSource;
29import org.osgi.framework.*;
30
31
32class SystemBundle extends BundleImpl
33{
34 private List m_activatorList = null;
35 private BundleActivator m_activator = null;
36 private Thread m_shutdownThread = null;
37 private Object[][] m_attributes = null;
38 private ResourceSource[] m_resSources = null;
39 private LibrarySource[] m_libSources = null;
40
41 protected SystemBundle(Felix felix, BundleInfo info, List activatorList)
42 throws BundleException
43 {
44 super(felix, info);
45
46 // Create an activator list if necessary.
47 if (activatorList == null)
48 {
49 activatorList = new ArrayList();
50 }
51
52 // Add the bundle activator for the package admin service.
53 activatorList.add(new PackageAdminActivator(felix));
54
55 // Add the bundle activator for the start level service.
56 activatorList.add(new StartLevelActivator(felix));
57
58 m_activatorList = activatorList;
59
60 // The system bundle exports framework packages as well as
61 // arbitrary user-defined packages from the system class path.
62 // We must construct the system bundle's export metadata.
63
64 // Get system property that specifies which class path
65 // packages should be exported by the system bundle.
66 R4Package[] classPathPkgs = null;
67 try
68 {
69 classPathPkgs = R4Package.parseImportOrExportHeader(
70 getFelix().getConfig().get(FelixConstants.FRAMEWORK_SYSTEMPACKAGES));
71 }
72 catch (Exception ex)
73 {
74 getFelix().getLogger().log(
75 LogWrapper.LOG_ERROR,
76 "Error parsing system bundle export statement.", ex);
77 }
78
79 // Now, create the list of standard framework exports for
80 // the system bundle.
81 R4Package[] exports = new R4Package[classPathPkgs.length + 3];
82
83 exports[0] = new R4Package(
84 "org.osgi.framework",
85 new R4Directive[0],
86 new R4Attribute[] { new R4Attribute("version", "1.2.0", false) });
87
88 exports[1] = new R4Package(
89 "org.osgi.service.packageadmin",
90 new R4Directive[0],
91 new R4Attribute[] { new R4Attribute("version", "1.2.0", false) });
92
93 exports[2] = new R4Package(
94 "org.osgi.service.startlevel",
95 new R4Directive[0],
96 new R4Attribute[] { new R4Attribute("version", "1.0.0", false) });
97
98 // Copy the class path exported packages.
99 System.arraycopy(classPathPkgs, 0, exports, 3, classPathPkgs.length);
100
101 m_attributes = new Object[][] {
102 new Object[] { R4SearchPolicy.EXPORTS_ATTR, exports },
103 new Object[] { R4SearchPolicy.IMPORTS_ATTR, new R4Package[0] }
104 };
105
106 m_resSources = new ResourceSource[0];
107
108 m_libSources = null;
109
110 String exportString = "";
111 for (int i = 0; i < exports.length; i++)
112 {
113 exportString = exportString +
114 exports[i].getId()
115 + "; specification-version=\""
116 + exports[i].getVersionLow().toString() + "\"";
117
118 if (i < (exports.length - 1))
119 {
120 exportString = exportString + ", ";
121 exportString = exportString +
122 exports[i].getId()
123 + "; specification-version=\""
124 + exports[i].getVersionLow().toString() + "\", ";
125 }
126 }
127
128 // Initialize header map as a case insensitive map.
129 Map map = new CaseInsensitiveMap();
130 map.put(FelixConstants.BUNDLE_VERSION, FelixConstants.FELIX_VERSION_VALUE);
131 map.put(FelixConstants.BUNDLE_NAME, "System Bundle");
132 map.put(FelixConstants.BUNDLE_DESCRIPTION,
133 "This bundle is system specific; it implements various system services.");
134 map.put(FelixConstants.EXPORT_PACKAGE, exportString);
135 ((SystemBundleArchive) getInfo().getArchive()).setManifestHeader(map);
136 }
137
138 public Object[][] getAttributes()
139 {
140 return m_attributes;
141 }
142
143 public ResourceSource[] getResourceSources()
144 {
145 return m_resSources;
146 }
147
148 public LibrarySource[] getLibrarySources()
149 {
150 return m_libSources;
151 }
152
153 public synchronized void start() throws BundleException
154 {
155 // The system bundle is only started once and it
156 // is started by the framework.
157 if (getState() == Bundle.ACTIVE)
158 {
159 throw new BundleException("Cannot start the system bundle.");
160 }
161
162 getInfo().setState(Bundle.STARTING);
163
164 try {
165 getInfo().setContext(new BundleContextImpl(getFelix(), this));
166 getActivator().start(getInfo().getContext());
167 } catch (Throwable throwable) {
168throwable.printStackTrace();
169 throw new BundleException(
170 "Unable to start system bundle.", throwable);
171 }
172
173 // Do NOT set the system bundle state to active yet, this
174 // must be done after all other bundles have been restarted.
175 // This will be done after the framework is initialized.
176 }
177
178 public synchronized void stop() throws BundleException
179 {
180 if (System.getSecurityManager() != null)
181 {
182 AccessController.checkPermission(new AdminPermission());
183 }
184
185 // Spec says stop() on SystemBundle should return immediately and
186 // shutdown framework on another thread.
187 if (getFelix().getStatus() == Felix.RUNNING_STATUS)
188 {
189 // Initial call of stop, so kick off shutdown.
190 m_shutdownThread = new Thread("FelixShutdown") {
191 public void run()
192 {
193 try
194 {
195 getFelix().shutdown();
196 }
197 catch (Exception ex)
198 {
199 getFelix().getLogger().log(
200 LogWrapper.LOG_ERROR,
201 "SystemBundle: Error while shutting down.", ex);
202 }
203
204 // Only shutdown the JVM if the framework is running stand-alone.
205 String embedded = getFelix().getConfig()
206 .get(FelixConstants.EMBEDDED_EXECUTION_PROP);
207 boolean isEmbedded = (embedded == null)
208 ? false : embedded.equals("true");
209 if (!isEmbedded)
210 {
211 if (System.getSecurityManager() != null)
212 {
213 AccessController.doPrivileged(new PrivilegedAction() {
214 public Object run()
215 {
216 System.exit(0);
217 return null;
218 }
219 });
220 }
221 else
222 {
223 System.exit(0);
224 }
225 }
226 }
227 };
228 getInfo().setState(Bundle.STOPPING);
229 m_shutdownThread.start();
230 }
231 else if ((getFelix().getStatus() == Felix.STOPPING_STATUS) &&
232 (Thread.currentThread() == m_shutdownThread))
233 {
234 // Callback from shutdown thread, so do our own stop.
235 try
236 {
237 getActivator().stop(getInfo().getContext());
238 }
239 catch (Throwable throwable)
240 {
241 throw new BundleException(
242 "Unable to stop system bundle.", throwable);
243 }
244 }
245 }
246
247 public synchronized void uninstall() throws BundleException
248 {
249 throw new BundleException("Cannot uninstall the system bundle.");
250 }
251
252 public synchronized void update() throws BundleException
253 {
254 update(null);
255 }
256
257 public synchronized void update(InputStream is) throws BundleException
258 {
259 if (System.getSecurityManager() != null)
260 {
261 AccessController.checkPermission(new AdminPermission());
262 }
263
264 // TODO: This is supposed to stop and then restart the framework.
265 throw new BundleException("System bundle update not implemented yet.");
266 }
267
268 protected BundleActivator getActivator()
269 throws Exception
270 {
271 if (m_activator == null)
272 {
273 m_activator = new SystemBundleActivator(getFelix(), m_activatorList);
274 }
275 return m_activator;
276 }
277}