Develop and register service,
lookup and use service!
Android Design on service's publish-find-bind model.
- What is OSGi(Open Service Gateway Initiative)?: http://www.osgi.org/Technology/WhatIsOSGi
- http://dz.prosyst.com/pdoc/mBS_R5_SDK_7.3.0_beta/getting_started/introduction.html
One simple example:
Service:
1 package org.serc.helloworld; 2 public interface Hello 3 { 4 void sayHello(); 5 } 6 7 package org.serc.helloworld.impl; 8 public class HelloImpl implements Hello 9 { 10 final String helloString; 11 public HelloImpl(String helloString){ 12 this.helloString= helloString; 13 } 14 public void sayHello(){ 15 System.out.println(this.helloString); 16 } 17 } 18 19 package org.serc.helloworld.activator; 20 public class Activator implements BundleActivator { 21 private List<ServiceRegistration> registrations = new ArrayList<ServiceRegistration>(); 22 public void start(BundleContext ctx) {//only register one service just now 23 registrations.add(ctx.registerService(Hello.class.getName(),new HelloImpl("Hello, OSGi"), null)); 24 } 25 public void stop(BundleContext ctx) { 26 for(ServiceRegistration registration : registrations) { 27 System.out.println("unregistering:"+ registration); 28 registration.unregister(); 29 } 30 } 31 } 32 //MANIFEST 33 Bundle-ManifestVersion:2 34 Bundle-SymbolicName:org.serc.helloworld 35 Bundle-Version:1.0 36 Bundle-Activator:org.serc.helloworld.activator.Activator 37 Import-Package:org.osgi.framework 38 Export-Package:org.serc.helloworld;version="1.0" //the package which will be used by other bundle
Client:
1 package org.serc.helloworld.client; 2 public class HelloUser implements BundleActivator { 3 public void start(BundleContext ctx) { //ctx is created by runtime kernel, framwork entity 4 ServiceReference ref = ctx.getServiceReference(Hello.class.getName());//now get a service reference which implement Hello 5 if(ref != null) { 6 Hello hello = null; 7 try{ 8 hello= (Hello) ctx.getService(ref);//get reference 9 if(hello != null) 10 hello.sayHello(); 11 else 12 System.out.println("Service:Hello---objectnull"); 13 } 14 catch (RuntimeException e) { 15 e.printStackTrace(); 16 } 17 finally{ 18 ctx.ungetService(ref); 19 hello= null; 20 } 21 } 22 else { 23 System.out.println("Service:Hello---notexists"); 24 } 25 } 26 public void stop(BundleContext ctx) throws Exception { 27 } 28 } 29 // 30 Bundle-ManifestVersion:2 31 Bundle-SymbolicName:org.serc.helloworld.client 32 Bundle-Version:1.0 33 Bundle-Activator:org.serc.helloworld.client.HelloUser //Bundle luncher 34 Import-Package:org.serc.helloworld;version="[1.0,2.0)",org.osgi.framework //the package which is used by this bundle
-
Bundle
- Words with same meaning:parcel,package,bunch,plug-in;A collection of things wrapped or boxed together;a collection of things wrapped or boxed together
- The mechanics for supporting plug-ins are implemented using the OSGi framework. From this standpoint, a plug-in is the same thing as an OSGi bundle. The bundle and its associated classes specify and implement the process for Java class-loading, prequisite management, and the bundle's life-cycle. For the rest of this discussion, we use the terms plug-in and bundle interchangeably, unless discussing a particular class in the framework.
-
Underneath every plug-in lies an OSGi bundle managed by the framework. The Bundle is the OSGi unit of modularity. Fundamentally, a bundle is just a collection of files (resources and code) installed in the platform. Each bundle has its own Java class loader, and includes protocol for starting, stopping, and uninstalling itself. From the Eclipse platform point of view, Bundle is merely an implementation class. Plug-in developers do not extend the bundle class, but use Plugin or other BundleActivator implementations to represent the plug-in.
-
Plugin:
The Plugin class represents a plug-in that is running in the platform. It is a convenient place to centralize the life-cycle aspects and overall semantics of a plug-in. A plug-in can implement specialized functionality for the start and stop aspects of its life-cycle. Each life-cycle method includes a reference to a BundleContext which can supply additional information.
The start portion of the life-cycle is worth particular discussion. We've seen already that information about a plug-in can be obtained from the plug-in's manifest file without ever running any of the plug-in's code. Typically, some user action in the workbench causes a chain of events that requires the starting of a plug-in. From an implementation point of view, a plug-in is never started until a class contained in the plug-in needs to be loaded.
The start method has been a convenient place to implement initialization and registration behavior for a plug-in. However, it is important to realize that your plug-in can be started in many different circumstances. Something as simple as obtaining an icon to decorate an object can cause one of your plug-in's classes to be loaded, thus starting your plug-in. Over-eager initialization can cause your plug-in's code and data to be loaded long before it is necessary. Therefore, it's important to look closely at your plug-in's initialization tasks and consider alternatives to performing initialization at start-up.
-
- Registration activities such as registering listeners or starting background threads are appropriate during plug-in start-up if they can be performed quickly. However, it is advisable to trigger these actions as part of accessing the plug-in's data if the registration activities have side-effects such as initializing large data structures or performing unrelated operations.
-
- Initialization of data is best done lazily, when the data is first accessed, rather than automatically in the start-up code. This ensures that large data structures are not built until they are truly necessary.
-
-
Bundle Context:Life-cycle management is where the OSGi "bundle" terminology and the platform's "plug-in" terminology meet. When your plug-in is started, it is given a reference to a BundleContext from which it can obtain information related to the plug-in. The BundleContext can also be used to find out about other bundles/plug-ins in the system.
BundleContext.getBundles() can be used to obtain an array of all bundles in the system. Listeners for BundleEvent can be registered so that your plug-in is aware when another bundle has a change in its life-cycle status. See the javadoc for BundleContext and BundleEvent for more information.Prior to 3.0, a plug-in registry (IPluginRegistry) was provided to supply similar information. For example, it could be queried for the plug-in descriptors of all plug-ins in the system. This registry is now deprecated and BundleContext should be used for this purpose. The platform registry is now used exclusively for information about extensions and extension points.TheBundleContextobject is only valid during the execution of its context bundle; that is, during the period from when the context bundle is in theSTARTING,STOPPING, andACTIVEbundle states. If theBundleContextobject is used subsequently, anIllegalStateExceptionmust be thrown. -
The
BundleContextobject must never be reused after its context bundle is stopped.TwoBundleContextobjects are equal if they both refer to the same execution context of a bundle. -
The Framework is the only entity that can create
BundleContextobjects and they are only valid within the Framework that created them.
-
1 public interface Comparable<T> { //generic in Java 2 public int compareTo(T o); 3 }
1 package org.osgi.framework; 2 public interface Bundle extends Comparable<Bundle> { 3 int UNINSTALLED = 0x00000001; 4 int INSTALLED = 0x00000002; 5 int RESOLVED = 0x00000004; 6 int STARTING = 0x00000008; 7 int STOPPING = 0x00000010; 8 int ACTIVE = 0x00000020; 9 int START_TRANSIENT = 0x00000001; 10 int START_ACTIVATION_POLICY = 0x00000002; 11 int STOP_TRANSIENT = 0x00000001; 12 int SIGNERS_ALL = 1; 13 int SIGNERS_TRUSTED = 2; 14 int getState(); 15 void start(int options) throws BundleException; 16 void start() throws BundleException; 17 void stop(int options) throws BundleException; 18 void stop() throws BundleException; 19 void update(InputStream input) throws BundleException; 20 void update() throws BundleException; 21 void uninstall() throws BundleException; 22 Dictionary<String, String> getHeaders(); 23 long getBundleId(); 24 String getLocation(); 25 ServiceReference<?>[] getRegisteredServices(); 26 ServiceReference<?>[] getServicesInUse(); 27 boolean hasPermission(Object permission); 28 URL getResource(String name); 29 Enumeration<String> getEntryPaths(String path); 30 URL getEntry(String path); 31 long getLastModified(); 32 Enumeration<URL> findEntries(String path, String filePattern, boolean recurse); 33 BundleContext getBundleContext(); 34 Map<X509Certificate, List<X509Certificate>> getSignerCertificates(int signersType); 35 Version getVersion(); 36 <A> A adapt(Class<A> type); 37 File getDataFile(String filename); 38 }
-
1 public interface BundleReference { 2 public Bundle getBundle(); 3 }
-
1 package org.osgi.framework; 2 public interface BundleContext extends BundleReference { 3 String getProperty(String key); 4 Bundle getBundle(); 5 Bundle installBundle(String location, InputStream input) throws BundleException; 6 Bundle installBundle(String location) throws BundleException; 7 Bundle getBundle(long id); 8 Bundle[] getBundles(); 9 void addServiceListener(ServiceListener listener, String filter) throws InvalidSyntaxException; 10 void addServiceListener(ServiceListener listener); 11 void removeServiceListener(ServiceListener listener); 12 void addBundleListener(BundleListener listener); 13 void removeBundleListener(BundleListener listener); 14 void addFrameworkListener(FrameworkListener listener); 15 void removeFrameworkListener(FrameworkListener listener); 16 ServiceRegistration<?> registerService(String clazz, Object service, Dictionary<String, ?> properties); 17 <S> ServiceRegistration<S> registerService(Class<S> clazz, S service, Dictionary<String, ?> properties); 18 ServiceReference<?>[] getServiceReferences(String clazz, String filter) throws InvalidSyntaxException; 19 ServiceReference<?>[] getAllServiceReferences(String clazz, String filter) throws InvalidSyntaxException; 20 ServiceReference<?> getServiceReference(String clazz); 21 <S> ServiceReference<S> getServiceReference(Class<S> clazz); 22 <S> Collection<ServiceReference<S>> getServiceReferences(Class<S> clazz, String filter) throws InvalidSyntaxException; 23 <S> S getService(ServiceReference<S> reference); 24 boolean ungetService(ServiceReference<?> reference); 25 File getDataFile(String filename); 26 Filter createFilter(String filter) throws InvalidSyntaxException; 27 Bundle getBundle(String location); 28 }
-
BundleActivator
- The BundleActivator interface defines the start and stop behavior implemented in Plugin. Although the Plugin class is a convenient place to implement this function, a plug-in developer has complete freedom to implement the interface for BundleActivator in any class appropriate for the plug-in's design. In fact, your plug-in need not implement this interface at all if it does not have specific life-cycle management needs.
-
1 public interface BundleActivator { 2 public void start(BundleContext context) throws Exception; 3 public void stop(BundleContext context) throws Exception; 4 }
- Plugin
1 /******************************************************************************* 2 * Copyright (c) 2000, 2012 IBM Corporation and others. 3 * All rights reserved. This program and the accompanying materials 4 * are made available under the terms of the Eclipse Public License v1.0 5 * which accompanies this distribution, and is available at 6 * http://www.eclipse.org/legal/epl-v10.html 7 * 8 * Contributors: 9 * IBM Corporation - initial API and implementation 10 * Julian Chen - fix for bug #92572, jclRM 11 * Benjamin Cabe <benjamin.cabe@anyware-tech.com> - fix for bug 265532 12 *******************************************************************************/ 13 package org.eclipse.core.internal.runtime; 14 15 import java.io.*; 16 import java.net.MalformedURLException; 17 import java.net.URL; 18 import java.util.*; 19 import org.eclipse.core.internal.preferences.exchange.ILegacyPreferences; 20 import org.eclipse.core.internal.preferences.exchange.IProductPreferencesService; 21 import org.eclipse.core.internal.preferences.legacy.InitLegacyPreferences; 22 import org.eclipse.core.internal.preferences.legacy.ProductPreferencesService; 23 import org.eclipse.core.runtime.*; 24 import org.eclipse.core.runtime.content.IContentTypeManager; 25 import org.eclipse.core.runtime.preferences.IPreferencesService; 26 import org.eclipse.equinox.app.IApplicationContext; 27 import org.eclipse.equinox.internal.app.*; 28 import org.eclipse.equinox.internal.app.Activator; 29 import org.eclipse.equinox.log.*; 30 import org.eclipse.osgi.framework.log.FrameworkLog; 31 import org.eclipse.osgi.service.datalocation.Location; 32 import org.eclipse.osgi.service.debug.DebugOptions; 33 import org.eclipse.osgi.service.environment.EnvironmentInfo; 34 import org.eclipse.osgi.service.resolver.PlatformAdmin; 35 import org.osgi.framework.*; 36 import org.osgi.service.packageadmin.PackageAdmin; 37 import org.osgi.util.tracker.ServiceTracker; 38 39 /** 40 * Bootstrap class for the platform. It is responsible for setting up the 41 * platform class loader and passing control to the actual application class 42 */ 43 public final class InternalPlatform { 44 45 private static final String[] ARCH_LIST = {Platform.ARCH_PA_RISC, // 46 Platform.ARCH_PPC, // 47 Platform.ARCH_SPARC, // 48 Platform.ARCH_X86, // 49 Platform.ARCH_AMD64, // 50 Platform.ARCH_IA64, // 51 Platform.ARCH_IA64_32}; 52 53 // debug support: set in loadOptions() 54 public static boolean DEBUG = false; 55 public static boolean DEBUG_PLUGIN_PREFERENCES = false; 56 57 static boolean splashEnded = false; 58 private static boolean initialized; 59 private static final String KEYRING = "-keyring"; //$NON-NLS-1$ 60 private static String keyringFile; 61 62 //XXX This is not synchronized 63 private static Map logs = new HashMap(5); 64 65 private static final String[] OS_LIST = {Platform.OS_AIX, Platform.OS_HPUX, Platform.OS_LINUX, Platform.OS_MACOSX, Platform.OS_QNX, Platform.OS_SOLARIS, Platform.OS_WIN32}; 66 private static String password = ""; //$NON-NLS-1$ 67 private static final String PASSWORD = "-password"; //$NON-NLS-1$ 68 69 private static final String PLUGIN_PATH = ".plugin-path"; //$NON-NLS-1$ 70 71 public static final String PROP_APPLICATION = "eclipse.application"; //$NON-NLS-1$ 72 public static final String PROP_ARCH = "osgi.arch"; //$NON-NLS-1$ 73 public static final String PROP_CONFIG_AREA = "osgi.configuration.area"; //$NON-NLS-1$ 74 public static final String PROP_CONSOLE_LOG = "eclipse.consoleLog"; //$NON-NLS-1$ 75 public static final String PROP_DEBUG = "osgi.debug"; //$NON-NLS-1$ 76 public static final String PROP_DEV = "osgi.dev"; //$NON-NLS-1$ 77 78 // OSGI system properties. Copied from EclipseStarter 79 public static final String PROP_INSTALL_AREA = "osgi.install.area"; //$NON-NLS-1$ 80 public static final String PROP_NL = "osgi.nl"; //$NON-NLS-1$ 81 public static final String PROP_OS = "osgi.os"; //$NON-NLS-1$ 82 83 // Eclipse System Properties 84 public static final String PROP_PRODUCT = "eclipse.product"; //$NON-NLS-1$ 85 public static final String PROP_WS = "osgi.ws"; //$NON-NLS-1$ 86 public static final String PROP_ACTIVATE_PLUGINS = "eclipse.activateRuntimePlugins"; //$NON-NLS-1$ 87 88 private static final InternalPlatform singleton = new InternalPlatform(); 89 90 private static final String[] WS_LIST = {Platform.WS_CARBON, Platform.WS_COCOA, Platform.WS_GTK, Platform.WS_MOTIF, Platform.WS_PHOTON, Platform.WS_WIN32, Platform.WS_WPF}; 91 private Path cachedInstanceLocation; // Cache the path of the instance location 92 private ServiceTracker configurationLocation = null; 93 private BundleContext context; 94 95 private Map groupProviders = new HashMap(3); 96 private ServiceTracker installLocation = null; 97 private ServiceTracker instanceLocation = null; 98 99 private Plugin runtimeInstance; // Keep track of the plugin object for runtime in case the backward compatibility is run. 100 101 private ServiceRegistration legacyPreferencesService = null; 102 private ServiceRegistration customPreferencesService = null; 103 104 private ServiceTracker environmentTracker = null; 105 private ServiceTracker logTracker = null; 106 private ServiceTracker bundleTracker = null; 107 private ServiceTracker debugTracker = null; 108 private ServiceTracker contentTracker = null; 109 private ServiceTracker preferencesTracker = null; 110 private ServiceTracker userLocation = null; 111 private ServiceTracker groupProviderTracker = null; 112 private ServiceTracker logReaderTracker = null; 113 private ServiceTracker extendedLogTracker = null; 114 115 private IProduct product; 116 117 public static InternalPlatform getDefault() { 118 return singleton; 119 } 120 121 /** 122 * Private constructor to block instance creation. 123 */ 124 private InternalPlatform() { 125 super(); 126 } 127 128 /** 129 * @see Platform#addLogListener(ILogListener) 130 */ 131 public void addLogListener(ILogListener listener) { 132 assertInitialized(); 133 RuntimeLog.addLogListener(listener); 134 } 135 136 private void assertInitialized() { 137 //avoid the Policy.bind if assertion is true 138 if (!initialized) 139 Assert.isTrue(false, Messages.meta_appNotInit); 140 } 141 142 /** 143 * @see Platform#endSplash() 144 */ 145 public void endSplash() { 146 synchronized (this) { 147 if (splashEnded) 148 return; // do not do this more than once 149 splashEnded = true; 150 } 151 IApplicationContext applicationContext = getApplicationContext(); 152 if (applicationContext != null) 153 applicationContext.applicationRunning(); 154 } 155 156 /** 157 * @see Platform#getAdapterManager() 158 */ 159 public IAdapterManager getAdapterManager() { 160 assertInitialized(); 161 return AdapterManager.getDefault(); 162 } 163 164 /** 165 * XXX Use the Environment info service. Need to see how to set the value of the app args. 166 */ 167 public String[] getApplicationArgs() { 168 return CommandLineArgs.getApplicationArgs(); 169 } 170 171 public boolean getBooleanOption(String option, boolean defaultValue) { 172 String value = getOption(option); 173 if (value == null) 174 return defaultValue; 175 return value.equalsIgnoreCase("true"); //$NON-NLS-1$ 176 } 177 178 public Bundle getBundle(String symbolicName) { 179 PackageAdmin packageAdmin = getBundleAdmin(); 180 if (packageAdmin == null) 181 return null; 182 Bundle[] bundles = packageAdmin.getBundles(symbolicName, null); 183 if (bundles == null) 184 return null; 185 //Return the first bundle that is not installed or uninstalled 186 for (int i = 0; i < bundles.length; i++) { 187 if ((bundles[i].getState() & (Bundle.INSTALLED | Bundle.UNINSTALLED)) == 0) { 188 return bundles[i]; 189 } 190 } 191 return null; 192 } 193 194 public BundleContext getBundleContext() { 195 return context; 196 } 197 198 /** 199 * Returns the bundle id of the bundle that contains the provided object, or 200 * <code>null</code> if the bundle could not be determined. 201 */ 202 public String getBundleId(Object object) { 203 if (object == null) 204 return null; 205 PackageAdmin packageAdmin = getBundleAdmin(); 206 if (packageAdmin == null) 207 return null; 208 Bundle source = packageAdmin.getBundle(object.getClass()); 209 if (source != null && source.getSymbolicName() != null) 210 return source.getSymbolicName(); 211 return null; 212 } 213 214 public IBundleGroupProvider[] getBundleGroupProviders() { 215 Object[] objectArray = groupProviderTracker.getServices(); 216 if (objectArray == null) // getServices may return null; but we can not. 217 return new IBundleGroupProvider[0]; 218 IBundleGroupProvider[] result = new IBundleGroupProvider[objectArray.length]; 219 System.arraycopy(objectArray, 0, result, 0, objectArray.length); 220 return result; 221 } 222 223 public void registerBundleGroupProvider(IBundleGroupProvider provider) { 224 // get the bundle context and register the provider as a service 225 ServiceRegistration registration = getBundleContext().registerService(IBundleGroupProvider.class.getName(), provider, null); 226 // store the service registration (map provider -> registration) 227 synchronized (groupProviders) { 228 groupProviders.put(provider, registration); 229 } 230 } 231 232 public void unregisterBundleGroupProvider(IBundleGroupProvider provider) { 233 // get the service reference (map provider -> reference) 234 ServiceRegistration registration; 235 synchronized (groupProviders) { 236 registration = (ServiceRegistration) groupProviders.remove(provider); 237 } 238 if (registration == null) 239 return; 240 // unregister the provider 241 registration.unregister(); 242 } 243 244 public Bundle[] getBundles(String symbolicName, String version) { 245 PackageAdmin packageAdmin = getBundleAdmin(); 246 if (packageAdmin == null) 247 return null; 248 Bundle[] bundles = packageAdmin.getBundles(symbolicName, version); 249 if (bundles == null) 250 return null; 251 // optimize for common case; length==1 252 if (bundles.length == 1 && (bundles[0].getState() & (Bundle.INSTALLED | Bundle.UNINSTALLED)) == 0) 253 return bundles; 254 //Remove all the bundles that are installed or uninstalled 255 Bundle[] selectedBundles = new Bundle[bundles.length]; 256 int added = 0; 257 for (int i = 0; i < bundles.length; i++) { 258 if ((bundles[i].getState() & (Bundle.INSTALLED | Bundle.UNINSTALLED)) == 0) { 259 selectedBundles[added++] = bundles[i]; 260 } 261 } 262 if (added == 0) 263 return null; 264 265 //return an array of the correct size 266 Bundle[] results = new Bundle[added]; 267 System.arraycopy(selectedBundles, 0, results, 0, added); 268 return results; 269 } 270 271 public String[] getCommandLineArgs() { 272 return CommandLineArgs.getAllArgs(); 273 } 274 275 public Location getConfigurationLocation() { 276 assertInitialized(); 277 return (Location) configurationLocation.getService(); 278 } 279 280 /** 281 * Lazy initialize ContentTypeManager - it can only be used after the registry is up and running 282 */ 283 public IContentTypeManager getContentTypeManager() { 284 return contentTracker == null ? null : (IContentTypeManager) contentTracker.getService(); 285 } 286 287 public EnvironmentInfo getEnvironmentInfoService() { 288 return environmentTracker == null ? null : (EnvironmentInfo) environmentTracker.getService(); 289 } 290 291 public Bundle[] getFragments(Bundle bundle) { 292 PackageAdmin packageAdmin = getBundleAdmin(); 293 if (packageAdmin == null) 294 return null; 295 return packageAdmin.getFragments(bundle); 296 } 297 298 public FrameworkLog getFrameworkLog() { 299 return logTracker == null ? null : (FrameworkLog) logTracker.getService(); 300 } 301 302 public Bundle[] getHosts(Bundle bundle) { 303 PackageAdmin packageAdmin = getBundleAdmin(); 304 if (packageAdmin == null) 305 return null; 306 return packageAdmin.getHosts(bundle); 307 } 308 309 public Location getInstallLocation() { 310 assertInitialized(); 311 return (Location) installLocation.getService(); 312 } 313 314 public URL getInstallURL() { 315 Location location = getInstallLocation(); 316 // it is pretty much impossible for the install location to be null. If it is, the 317 // system is in a bad way so throw and exception and get the heck outta here. 318 if (location == null) 319 throw new IllegalStateException("The installation location must not be null"); //$NON-NLS-1$ 320 return location.getURL(); 321 } 322 323 public Location getInstanceLocation() { 324 assertInitialized(); 325 return (Location) instanceLocation.getService(); 326 } 327 328 /** 329 * @see Platform#getLocation() 330 */ 331 public IPath getLocation() throws IllegalStateException { 332 if (cachedInstanceLocation == null) { 333 Location location = getInstanceLocation(); 334 if (location == null) 335 return null; 336 // This makes the assumption that the instance location is a file: URL 337 File file = new File(location.getURL().getFile()); 338 cachedInstanceLocation = new Path(file.toString()); 339 } 340 return cachedInstanceLocation; 341 } 342 343 /** 344 * Returns a log for the given plugin. Creates a new one if needed. 345 * XXX change this into a LogMgr service that would keep track of the map. See if it can be a service factory. 346 * It would contain all the logging methods that are here. 347 * Relate to RuntimeLog if appropriate. 348 * The system log listener needs to be optional: turned on or off. What about a system property? :-) 349 */ 350 public ILog getLog(Bundle bundle) { 351 Log result = (Log) logs.get(bundle); 352 if (result != null) 353 return result; 354 ExtendedLogService logService = (ExtendedLogService) extendedLogTracker.getService(); 355 Logger logger = logService == null ? null : logService.getLogger(bundle, PlatformLogWriter.EQUINOX_LOGGER_NAME); 356 result = new Log(bundle, logger); 357 ExtendedLogReaderService logReader = (ExtendedLogReaderService) logReaderTracker.getService(); 358 logReader.addLogListener(result, result); 359 logs.put(bundle, result); 360 return result; 361 } 362 363 /** 364 * Returns the object which defines the location and organization 365 * of the platform's meta area. 366 */ 367 public DataArea getMetaArea() { 368 // TODO: deprecate? 369 return MetaDataKeeper.getMetaArea(); 370 } 371 372 public String getNL() { 373 return getBundleContext().getProperty(PROP_NL); 374 } 375 376 /** 377 * Unicode locale extensions are defined using command line parameter -nlExtensions, 378 * or the system property "osgi.nl.extensions". 379 */ 380 public String getNLExtensions() { 381 String nlExtensions = PlatformActivator.getContext().getProperty("osgi.nl.extensions"); //$NON-NLS-1$ 382 if (nlExtensions == null) 383 return ""; //$NON-NLS-1$ 384 if (!nlExtensions.startsWith("@")) //$NON-NLS-1$ 385 nlExtensions = '@' + nlExtensions; 386 return nlExtensions; 387 } 388 389 /** 390 * @see Platform 391 */ 392 public String getOption(String option) { 393 DebugOptions options = getDebugOptions(); 394 if (options != null) 395 return options.getOption(option); 396 return null; 397 } 398 399 public String getOS() { 400 return getBundleContext().getProperty(PROP_OS); 401 } 402 403 public String getOSArch() { 404 return getBundleContext().getProperty(PROP_ARCH); 405 } 406 407 public PlatformAdmin getPlatformAdmin() { 408 if (context == null) 409 return null; 410 ServiceReference platformAdminReference = context.getServiceReference(PlatformAdmin.class.getName()); 411 if (platformAdminReference == null) 412 return null; 413 return (PlatformAdmin) context.getService(platformAdminReference); 414 } 415 416 //TODO I guess it is now time to get rid of that 417 /* 418 * This method is retained for R1.0 compatibility because it is defined as API. 419 * Its function matches the API description (returns <code>null</code> when 420 * argument URL is <code>null</code> or cannot be read). 421 */ 422 public URL[] getPluginPath(URL pluginPathLocation /*R1.0 compatibility*/ 423 ) { 424 InputStream input = null; 425 // first try and see if the given plugin path location exists. 426 if (pluginPathLocation == null) 427 return null; 428 try { 429 input = pluginPathLocation.openStream(); 430 } catch (IOException e) { 431 //fall through 432 } 433 434 // if the given path was null or did not exist, look for a plugin path 435 // definition in the install location. 436 if (input == null) 437 try { 438 URL url = new URL("platform:/base/" + PLUGIN_PATH); //$NON-NLS-1$ 439 input = url.openStream(); 440 } catch (MalformedURLException e) { 441 //fall through 442 } catch (IOException e) { 443 //fall through 444 } 445 446 // nothing was found at the supplied location or in the install location 447 if (input == null) 448 return null; 449 // if we found a plugin path definition somewhere so read it and close the location. 450 URL[] result = null; 451 try { 452 try { 453 result = readPluginPath(input); 454 } finally { 455 input.close(); 456 } 457 } catch (IOException e) { 458 //let it return null on failure to read 459 } 460 return result; 461 } 462 463 /** 464 * 465 */ 466 public IPreferencesService getPreferencesService() { 467 return preferencesTracker == null ? null : (IPreferencesService) preferencesTracker.getService(); 468 } 469 470 /* 471 * XXX move this into the app model. 472 */ 473 public IProduct getProduct() { 474 if (product != null) 475 return product; 476 EclipseAppContainer container = Activator.getContainer(); 477 IBranding branding = container == null ? null : container.getBranding(); 478 if (branding == null) 479 return null; 480 Object brandingProduct = branding.getProduct(); 481 if (!(brandingProduct instanceof IProduct)) 482 brandingProduct = new Product(branding); 483 product = (IProduct) brandingProduct; 484 return product; 485 } 486 487 public IExtensionRegistry getRegistry() { 488 return RegistryFactory.getRegistry(); 489 } 490 491 /** 492 * XXX deprecate and use NLS or BundleFinder.find() 493 */ 494 public ResourceBundle getResourceBundle(Bundle bundle) { 495 return ResourceTranslator.getResourceBundle(bundle); 496 } 497 498 /** 499 * XXX deprecate and use NLS or BundleFinder.find() 500 */ 501 public String getResourceString(Bundle bundle, String value) { 502 return ResourceTranslator.getResourceString(bundle, value); 503 } 504 505 /** 506 * XXX deprecate and use NLS or BundleFinder.find() 507 */ 508 public String getResourceString(Bundle bundle, String value, ResourceBundle resourceBundle) { 509 return ResourceTranslator.getResourceString(bundle, value, resourceBundle); 510 } 511 512 /** 513 * This method is only used to register runtime once compatibility has been started. 514 */ 515 public Plugin getRuntimeInstance() { 516 return runtimeInstance; 517 } 518 519 private IApplicationContext getApplicationContext() { 520 ServiceReference[] ref; 521 try { 522 ref = context.getServiceReferences(IApplicationContext.class.getName(), "(eclipse.application.type=main.thread)"); //$NON-NLS-1$ 523 } catch (InvalidSyntaxException e) { 524 return null; 525 } 526 if (ref == null || ref.length == 0) 527 return null; 528 // assumes the application context is available as a service 529 IApplicationContext result = (IApplicationContext) context.getService(ref[0]); 530 if (result != null) { 531 context.ungetService(ref[0]); 532 return result; 533 } 534 return null; 535 } 536 537 /** 538 * XXX Investigate the usage of a service factory 539 */ 540 public IPath getStateLocation(Bundle bundle) { 541 return getStateLocation(bundle, true); 542 } 543 544 public IPath getStateLocation(Bundle bundle, boolean create) throws IllegalStateException { 545 assertInitialized(); 546 IPath result = getMetaArea().getStateLocation(bundle); 547 if (create) 548 result.toFile().mkdirs(); 549 return result; 550 } 551 552 public long getStateTimeStamp() { 553 PlatformAdmin admin = getPlatformAdmin(); 554 return admin == null ? -1 : admin.getState(false).getTimeStamp(); 555 } 556 557 public Location getUserLocation() { 558 assertInitialized(); 559 return (Location) userLocation.getService(); 560 } 561 562 public String getWS() { 563 return getBundleContext().getProperty(PROP_WS); 564 } 565 566 private void initializeAuthorizationHandler() { 567 try { 568 AuthorizationHandler.setKeyringFile(keyringFile); 569 AuthorizationHandler.setPassword(password); 570 } catch (NoClassDefFoundError e) { 571 // The authorization fragment is not available. If someone tries to use that API, an error will be logged 572 } 573 } 574 575 /* 576 * Finds and loads the options file 577 */ 578 void initializeDebugFlags() { 579 // load runtime options 580 DEBUG = getBooleanOption(Platform.PI_RUNTIME + "/debug", false); //$NON-NLS-1$ 581 if (DEBUG) { 582 DEBUG_PLUGIN_PREFERENCES = getBooleanOption(Platform.PI_RUNTIME + "/preferences/plugin", false); //$NON-NLS-1$ 583 } 584 } 585 586 public boolean isFragment(Bundle bundle) { 587 PackageAdmin packageAdmin = getBundleAdmin(); 588 if (packageAdmin == null) 589 return false; 590 return (packageAdmin.getBundleType(bundle) & PackageAdmin.BUNDLE_TYPE_FRAGMENT) > 0; 591 } 592 593 /* 594 *XXX do what you want to do. track osgi, track runtime, or whatever. 595 */ 596 public boolean isRunning() { 597 try { 598 return initialized && context != null && context.getBundle().getState() == Bundle.ACTIVE; 599 } catch (IllegalStateException e) { 600 return false; 601 } 602 } 603 604 /** 605 * Returns a list of known system architectures. 606 * 607 * @return the list of system architectures known to the system 608 * XXX This is useless 609 */ 610 public String[] knownOSArchValues() { 611 return ARCH_LIST; 612 } 613 614 /** 615 * Returns a list of known operating system names. 616 * 617 * @return the list of operating systems known to the system 618 * XXX This is useless 619 */ 620 public String[] knownOSValues() { 621 return OS_LIST; 622 } 623 624 /** 625 * Returns a list of known windowing system names. 626 * 627 * @return the list of window systems known to the system 628 * XXX This is useless 629 */ 630 public String[] knownWSValues() { 631 return WS_LIST; 632 } 633 634 /** 635 * Notifies all listeners of the platform log. This includes the console log, if 636 * used, and the platform log file. All Plugin log messages get funnelled 637 * through here as well. 638 */ 639 public void log(final IStatus status) { 640 // TODO: deprecate? 641 RuntimeLog.log(status); 642 } 643 644 private void processCommandLine(String[] args) { 645 if (args == null || args.length == 0) 646 return; 647 648 for (int i = 0; i < args.length; i++) { 649 // check for args with parameters 650 if (i == args.length - 1 || args[i + 1].startsWith("-")) //$NON-NLS-1$ 651 continue; 652 String arg = args[++i]; 653 654 // look for the keyring file 655 if (args[i - 1].equalsIgnoreCase(KEYRING)) 656 keyringFile = arg; 657 // look for the user password. 658 if (args[i - 1].equalsIgnoreCase(PASSWORD)) 659 password = arg; 660 } 661 } 662 663 private URL[] readPluginPath(InputStream input) { 664 Properties ini = new Properties(); 665 try { 666 ini.load(input); 667 } catch (IOException e) { 668 return null; 669 } 670 Vector result = new Vector(5); 671 for (Enumeration groups = ini.propertyNames(); groups.hasMoreElements();) { 672 String group = (String) groups.nextElement(); 673 for (StringTokenizer entries = new StringTokenizer(ini.getProperty(group), ";"); entries.hasMoreElements();) { //$NON-NLS-1$ 674 String entry = (String) entries.nextElement(); 675 if (!entry.equals("")) //$NON-NLS-1$ 676 try { 677 result.addElement(new URL(entry)); 678 } catch (MalformedURLException e) { 679 //intentionally ignore bad URLs 680 System.err.println("Ignoring plugin: " + entry); //$NON-NLS-1$ 681 } 682 } 683 } 684 return (URL[]) result.toArray(new URL[result.size()]); 685 } 686 687 /** 688 * @see Platform#removeLogListener(ILogListener) 689 */ 690 public void removeLogListener(ILogListener listener) { 691 assertInitialized(); 692 RuntimeLog.removeLogListener(listener); 693 } 694 695 /** 696 * This method is only used to register runtime once compatibility has been started. 697 */ 698 public void setRuntimeInstance(Plugin runtime) { 699 runtimeInstance = runtime; 700 } 701 702 /** 703 * Internal method for starting up the platform. The platform is not started with any location 704 * and should not try to access the instance data area. 705 * 706 * Note: the content type manager must be initialized only after the registry has been created 707 */ 708 public void start(BundleContext runtimeContext) { 709 this.context = runtimeContext; 710 openOSGiTrackers(); 711 splashEnded = false; 712 processCommandLine(getEnvironmentInfoService().getNonFrameworkArgs()); 713 initializeDebugFlags(); 714 initialized = true; 715 getMetaArea(); 716 initializeAuthorizationHandler(); 717 startServices(); 718 719 // See if need to activate rest of the runtime plugins. Plugins are "gently" activated by touching 720 // a class from the corresponding plugin(s). 721 boolean shouldActivate = !"false".equalsIgnoreCase(context.getProperty(PROP_ACTIVATE_PLUGIN