KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > equinox > internal > app > EclipseAppContainer


1 /*******************************************************************************
2  * Copyright (c) 2005, 2007 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  *******************************************************************************/

11
12 package org.eclipse.equinox.internal.app;
13
14 import java.lang.reflect.InvocationTargetException JavaDoc;
15 import java.lang.reflect.Method JavaDoc;
16 import java.security.AccessController JavaDoc;
17 import java.security.PrivilegedAction JavaDoc;
18 import java.util.*;
19 import org.eclipse.core.runtime.*;
20 import org.eclipse.equinox.app.IApplicationContext;
21 import org.eclipse.osgi.framework.log.FrameworkLogEntry;
22 import org.eclipse.osgi.service.runnable.ApplicationLauncher;
23 import org.eclipse.osgi.service.runnable.ParameterizedRunnable;
24 import org.eclipse.osgi.util.NLS;
25 import org.osgi.framework.*;
26 import org.osgi.service.application.*;
27 import org.osgi.util.tracker.ServiceTracker;
28 import org.osgi.util.tracker.ServiceTrackerCustomizer;
29
30 /*
31  * A MEG application container that understands eclipse applications. This
32  * container will discover installed eclipse applications and register the
33  * appropriate ApplicatoinDescriptor service with the service registry.
34  */

35 public class EclipseAppContainer implements IRegistryChangeListener, SynchronousBundleListener, ServiceTrackerCustomizer {
36     private static final String JavaDoc PI_RUNTIME = "org.eclipse.core.runtime"; //$NON-NLS-1$
37
private static final String JavaDoc PT_APPLICATIONS = "applications"; //$NON-NLS-1$
38
private static final String JavaDoc PT_APP_VISIBLE = "visible"; //$NON-NLS-1$
39
private static final String JavaDoc PT_APP_THREAD = "thread"; //$NON-NLS-1$
40
private static final String JavaDoc PT_APP_THREAD_ANY = "any"; //$NON-NLS-1$
41
private static final String JavaDoc PT_APP_CARDINALITY = "cardinality"; //$NON-NLS-1$
42
private static final String JavaDoc PT_APP_CARDINALITY_SINGLETON_GLOBAL = "singleton-global"; //$NON-NLS-1$
43
private static final String JavaDoc PT_APP_CARDINALITY_SINGLETON_SCOPED = "singleton-scoped"; //$NON-NLS-1$
44
private static final String JavaDoc PT_APP_CARDINALITY_UNLIMITED = "*"; //$NON-NLS-1$
45
private static final String JavaDoc PT_PRODUCTS = "products"; //$NON-NLS-1$
46
private static final String JavaDoc EXT_ERROR_APP = "org.eclipse.equinox.app.error"; //$NON-NLS-1$
47

48     private static final String JavaDoc PROP_PRODUCT = "eclipse.product"; //$NON-NLS-1$
49
private static final String JavaDoc PROP_ECLIPSE_APPLICATION = "eclipse.application"; //$NON-NLS-1$
50
private static final String JavaDoc PROP_ECLIPSE_APPLICATION_LAUNCH_DEFAULT = "eclipse.application.launchDefault"; //$NON-NLS-1$
51
private static final String JavaDoc PROP_ECLIPSE_REGISTER_APP_DESC = "eclipse.application.registerDescriptors"; //$NON-NLS-1$
52

53     static final int NOT_LOCKED = 0;
54     static final int LOCKED_SINGLETON_GLOBAL_RUNNING = 1;
55     static final int LOCKED_SINGLETON_GLOBAL_APPS_RUNNING = 2;
56     static final int LOCKED_SINGLETON_SCOPED_RUNNING = 3;
57     static final int LOCKED_SINGLETON_LIMITED_RUNNING = 4;
58     static final int LOCKED_MAIN_THREAD_RUNNING = 5;
59
60     final BundleContext context;
61     // A map of ApplicationDescriptors keyed by eclipse application ID
62
final private HashMap apps = new HashMap();
63
64     final private IExtensionRegistry extensionRegistry;
65     final private ServiceTracker launcherTracker;
66     private IBranding branding;
67     private boolean missingProductReported;
68
69     // the currently active application handles
70
final private Collection activeHandles = new ArrayList();
71     private EclipseAppHandle activeMain;
72     private EclipseAppHandle activeGlobalSingleton;
73     private EclipseAppHandle activeScopedSingleton;
74     private HashMap activeLimited;
75     private String JavaDoc defaultAppId;
76     private DefaultApplicationListener defaultAppListener;
77     private ParameterizedRunnable defaultMainThreadAppHandle; // holds the default app handle to be run on the main thread
78

79     public EclipseAppContainer(BundleContext context, IExtensionRegistry extensionRegistry) {
80         this.context = context;
81         this.extensionRegistry = extensionRegistry;
82         launcherTracker = new ServiceTracker(context, ApplicationLauncher.class.getName(), this);
83     }
84
85     void start() {
86         launcherTracker.open();
87         extensionRegistry.addRegistryChangeListener(this);
88         // need to listen for system bundle stopping
89
context.addBundleListener(this);
90         String JavaDoc startDefaultProp = context.getProperty(EclipseAppContainer.PROP_ECLIPSE_APPLICATION_LAUNCH_DEFAULT);
91         if (startDefaultProp == null || "true".equalsIgnoreCase(startDefaultProp)) { //$NON-NLS-1$
92
boolean registerDescs = "true".equalsIgnoreCase(context.getProperty(EclipseAppContainer.PROP_ECLIPSE_REGISTER_APP_DESC)); //$NON-NLS-1$
93
// register all the descriptors if requested to
94
if (registerDescs)
95                 registerAppDescriptors();
96             // Start the default application
97
try {
98                 startDefaultApp();
99             } catch (ApplicationException e) {
100                 Activator.log(new FrameworkLogEntry(Activator.PI_APP, FrameworkLogEntry.ERROR, 0, Messages.application_errorStartDefault, 0, e, null));
101                 if (!registerDescs)
102                     // if an error occurred then register all desciptors if they were not registered already.
103
registerAppDescriptors();
104             }
105         } else {
106             // we are not running the default application; we should register all applications
107
registerAppDescriptors();
108         }
109     }
110
111     void stop() {
112         // stop all applications
113
stopAllApps();
114         context.removeBundleListener(this);
115         extensionRegistry.removeRegistryChangeListener(this);
116         // flush the apps
117
apps.clear();
118         branding = null;
119         missingProductReported = false;
120         launcherTracker.close();
121     }
122
123     /*
124      * Only used to find the default application
125      */

126     private EclipseAppDescriptor getAppDescriptor(String JavaDoc applicationId) {
127         EclipseAppDescriptor result = null;
128         synchronized (apps) {
129             result = (EclipseAppDescriptor) apps.get(applicationId);
130         }
131         if (result == null) {
132             registerAppDescriptor(applicationId); // try again just in case we are waiting for an event
133
synchronized (apps) {
134                 result = (EclipseAppDescriptor) apps.get(applicationId);
135             }
136         }
137         return result;
138     }
139
140     private EclipseAppDescriptor createAppDescriptor(IExtension appExtension) {
141         synchronized (apps) {
142             EclipseAppDescriptor appDescriptor = (EclipseAppDescriptor) apps.get(appExtension.getUniqueIdentifier());
143             if (appDescriptor != null)
144                 return appDescriptor;
145             // the appDescriptor does not exist for the app ID; create it
146
IConfigurationElement[] configs = appExtension.getConfigurationElements();
147             int flags = EclipseAppDescriptor.FLAG_CARD_SINGLETON_GLOGAL | EclipseAppDescriptor.FLAG_VISIBLE | EclipseAppDescriptor.FLAG_TYPE_MAIN_THREAD;
148             int cardinality = 0;
149             if (configs.length > 0) {
150                 String JavaDoc sVisible = configs[0].getAttribute(PT_APP_VISIBLE);
151                 if (sVisible != null && !Boolean.valueOf(sVisible).booleanValue())
152                     flags &= ~(EclipseAppDescriptor.FLAG_VISIBLE);
153                 String JavaDoc sThread = configs[0].getAttribute(PT_APP_THREAD);
154                 if (PT_APP_THREAD_ANY.equals(sThread)) {
155                     flags |= EclipseAppDescriptor.FLAG_TYPE_ANY_THREAD;
156                     flags &= ~(EclipseAppDescriptor.FLAG_TYPE_MAIN_THREAD);
157                 }
158                 String JavaDoc sCardinality = configs[0].getAttribute(PT_APP_CARDINALITY);
159                 if (sCardinality != null) {
160                     flags &= ~(EclipseAppDescriptor.FLAG_CARD_SINGLETON_GLOGAL); // clear the global bit
161
if (PT_APP_CARDINALITY_SINGLETON_SCOPED.equals(sCardinality))
162                         flags |= EclipseAppDescriptor.FLAG_CARD_SINGLETON_SCOPED;
163                     else if (PT_APP_CARDINALITY_UNLIMITED.equals(sCardinality))
164                         flags |= EclipseAppDescriptor.FLAG_CARD_UNLIMITED;
165                     else if (PT_APP_CARDINALITY_SINGLETON_GLOBAL.equals(sCardinality))
166                         flags |= EclipseAppDescriptor.FLAG_CARD_SINGLETON_GLOGAL;
167                     else {
168                         try {
169                             cardinality = Integer.parseInt(sCardinality);
170                             flags |= EclipseAppDescriptor.FLAG_CARD_LIMITED;
171                         } catch (NumberFormatException JavaDoc e) {
172                             // TODO should we log this?
173
// just fall back to the default
174
flags |= EclipseAppDescriptor.FLAG_CARD_SINGLETON_GLOGAL;
175                         }
176                     }
177                 }
178                 String JavaDoc defaultApp = getDefaultAppId();
179                 if (defaultApp != null && defaultApp.equals(appExtension.getUniqueIdentifier()))
180                     flags |= EclipseAppDescriptor.FLAG_DEFAULT_APP;
181             }
182             appDescriptor = new EclipseAppDescriptor(Activator.getBundle(appExtension.getContributor()), appExtension.getUniqueIdentifier(), appExtension.getLabel(), flags, cardinality, this);
183             // register the appDescriptor as a service
184
ServiceRegistration sr = (ServiceRegistration) AccessController.doPrivileged(new RegisterService(new String JavaDoc[] {ApplicationDescriptor.class.getName()}, appDescriptor, appDescriptor.getServiceProperties()));
185             appDescriptor.setServiceRegistration(sr);
186             // save the app descriptor in the cache
187
apps.put(appExtension.getUniqueIdentifier(), appDescriptor);
188             return appDescriptor;
189         }
190     }
191
192     private EclipseAppDescriptor removeAppDescriptor(String JavaDoc applicationId) {
193         synchronized (apps) {
194             EclipseAppDescriptor appDescriptor = (EclipseAppDescriptor) apps.remove(applicationId);
195             if (appDescriptor == null)
196                 return null;
197             appDescriptor.unregister();
198             return appDescriptor;
199         }
200     }
201
202     /*
203      * Gives access to the RegisterService privileged action.
204      */

205     PrivilegedAction JavaDoc getRegServiceAction(String JavaDoc[] serviceClasses, Object JavaDoc serviceObject, Dictionary serviceProps) {
206         return new RegisterService(serviceClasses, serviceObject, serviceProps);
207     }
208
209     /*
210      * PrivilegedAction used to register ApplicationDescriptor and ApplicationHandle services
211      */

212     private class RegisterService implements PrivilegedAction JavaDoc {
213         String JavaDoc[] serviceClasses;
214         Object JavaDoc serviceObject;
215         Dictionary serviceProps;
216
217         RegisterService(String JavaDoc[] serviceClasses, Object JavaDoc serviceObject, Dictionary serviceProps) {
218             this.serviceClasses = serviceClasses;
219             this.serviceObject = serviceObject;
220             this.serviceProps = serviceProps;
221         }
222
223         public Object JavaDoc run() {
224             return context.registerService(serviceClasses, serviceObject, serviceProps);
225         }
226     }
227
228     private void startDefaultApp() throws ApplicationException {
229         // find the default application
230
String JavaDoc applicationId = getDefaultAppId();
231         EclipseAppDescriptor defaultDesc = null;
232         Map args = new HashMap(2);
233         args.put(EclipseAppDescriptor.APP_DEFAULT, Boolean.TRUE);
234         if (applicationId == null) {
235             // the application id is not set; use a descriptor that will throw an exception
236
args.put(ErrorApplication.ERROR_EXCEPTION, new RuntimeException JavaDoc(Messages.application_noIdFound));
237             defaultDesc = getAppDescriptor(EXT_ERROR_APP);
238         } else {
239             defaultDesc = getAppDescriptor(applicationId);
240             if (defaultDesc == null) {
241                 // the application id is not available in the registry; use a descriptor that will throw an exception
242
args.put(ErrorApplication.ERROR_EXCEPTION, new RuntimeException JavaDoc(NLS.bind(Messages.application_notFound, applicationId, getAvailableAppsMsg())));
243                 defaultDesc = getAppDescriptor(EXT_ERROR_APP);
244             }
245         }
246         if (defaultDesc != null)
247             defaultDesc.launch(args);
248         else
249             throw new ApplicationException(ApplicationException.APPLICATION_INTERNAL_ERROR, Messages.application_noIdFound);
250     }
251
252     /*
253      * Registers an ApplicationDescriptor service for each eclipse application
254      * available in the extension registry.
255      */

256     private void registerAppDescriptors() {
257         IExtension[] availableApps = getAvailableAppExtensions();
258         for (int i = 0; i < availableApps.length; i++)
259             createAppDescriptor(availableApps[i]);
260     }
261
262     private void registerAppDescriptor(String JavaDoc applicationId) {
263         IExtension appExtension = getAppExtension(applicationId);
264         if (appExtension != null)
265             createAppDescriptor(appExtension);
266     }
267
268     /*
269      * Returns a list of all the available application IDs which are available
270      * in the extension registry.
271      */

272     private IExtension[] getAvailableAppExtensions() {
273         IExtensionPoint point = extensionRegistry.getExtensionPoint(PI_RUNTIME + '.' + PT_APPLICATIONS);
274         if (point == null)
275             return new IExtension[0];
276         return point.getExtensions();
277     }
278
279     String JavaDoc getAvailableAppsMsg() {
280         IExtension[] availableApps = getAvailableAppExtensions();
281         String JavaDoc availableAppsMsg = "<NONE>"; //$NON-NLS-1$
282
if (availableApps.length != 0) {
283             availableAppsMsg = availableApps[0].getUniqueIdentifier();
284             for (int i = 1; i < availableApps.length; i++)
285                 availableAppsMsg = availableAppsMsg + ", " + availableApps[i].getUniqueIdentifier(); //$NON-NLS-1$
286
}
287         return availableAppsMsg;
288     }
289
290     /*
291      * Returns the application extension for the specified applicaiton ID.
292      * A RuntimeException is thrown if the extension does not exist for the
293      * given application ID.
294      */

295     IExtension getAppExtension(String JavaDoc applicationId) {
296         return extensionRegistry.getExtension(PI_RUNTIME, PT_APPLICATIONS, applicationId);
297     }
298
299     void launch(EclipseAppHandle appHandle) throws Exception JavaDoc {
300         lock(appHandle);
301         boolean isDefault = appHandle.isDefault();
302         if (((EclipseAppDescriptor) appHandle.getApplicationDescriptor()).getThreadType() == EclipseAppDescriptor.FLAG_TYPE_MAIN_THREAD) {
303             // use the ApplicationLauncher provided by the framework to ensure it is launched on the main thread
304
DefaultApplicationListener curDefaultApplicationListener = null;
305             ApplicationLauncher appLauncher = null;
306             synchronized (this) {
307                 appLauncher = (ApplicationLauncher) launcherTracker.getService();
308                 if (appLauncher == null) {
309                     if (isDefault) {
310                         // we need to wait to allow the ApplicationLauncher to get registered;
311
// save the handle to be launched as soon as the ApplicationLauncher is available
312
defaultMainThreadAppHandle = appHandle;
313                         return;
314                     }
315                     throw new ApplicationException(ApplicationException.APPLICATION_INTERNAL_ERROR);
316                 }
317                 curDefaultApplicationListener = defaultAppListener;
318             }
319             if (curDefaultApplicationListener != null)
320                 curDefaultApplicationListener.launch(appHandle);
321             else
322                 appLauncher.launch(appHandle, appHandle.getArguments().get(IApplicationContext.APPLICATION_ARGS));
323         } else {
324             AnyThreadAppLauncher.launchEclipseApplication(appHandle);
325             DefaultApplicationListener curDefaultApplicationListener = null;
326             if (isDefault) {
327                 ApplicationLauncher appLauncher = null;
328                 synchronized (this) {
329                     appLauncher = (ApplicationLauncher) launcherTracker.getService();
330                     if (defaultAppListener == null)
331                         defaultAppListener = new DefaultApplicationListener(appHandle);
332                     curDefaultApplicationListener = defaultAppListener;
333                     if (appLauncher == null) {
334                         // we need to wait to allow the ApplicationLauncher to get registered;
335
// save the default app listener to be launched as soon as the ApplicationLauncher is available
336
defaultMainThreadAppHandle = curDefaultApplicationListener;
337                         return;
338                     }
339                 }
340                 appLauncher.launch(curDefaultApplicationListener, null);
341             }
342         }
343     }
344
345     public void registryChanged(IRegistryChangeEvent event) {
346         processAppDeltas(event.getExtensionDeltas(PI_RUNTIME, PT_APPLICATIONS));
347         processAppDeltas(event.getExtensionDeltas(Activator.PI_APP, PT_APPLICATIONS));
348     }
349
350     private void processAppDeltas(IExtensionDelta[] deltas) {
351         for (int i = 0; i < deltas.length; i++) {
352             switch (deltas[i].getKind()) {
353                 case IExtensionDelta.ADDED :
354                     createAppDescriptor(deltas[i].getExtension());
355                     break;
356                 case IExtensionDelta.REMOVED :
357                     removeAppDescriptor(deltas[i].getExtension().getUniqueIdentifier());
358                     break;
359             }
360         }
361     }
362
363     public void bundleChanged(BundleEvent event) {
364         // if this is not the system bundle stopping then ignore the event
365
if ((BundleEvent.STOPPING & event.getType()) == 0 || event.getBundle().getBundleId() != 0)
366             return;
367         // The system bundle is stopping; better stop all applications and containers now
368
stopAllApps();
369     }
370
371     private void stopAllApps() {
372         // get a stapshot of running applications
373
try {
374             ServiceReference[] runningRefs = context.getServiceReferences(ApplicationHandle.class.getName(), "(!(application.state=STOPPING))"); //$NON-NLS-1$
375
if (runningRefs != null)
376                 for (int i = 0; i < runningRefs.length; i++) {
377                     ApplicationHandle handle = (ApplicationHandle) context.getService(runningRefs[i]);
378                     try {
379                         if (handle != null)
380                             handle.destroy();
381                     } catch (Throwable JavaDoc t) {
382                         String JavaDoc message = NLS.bind(Messages.application_error_stopping, handle.getInstanceId());
383                         Activator.log(new FrameworkLogEntry(Activator.PI_APP, FrameworkLogEntry.WARNING, 0, message, 0, t, null));
384                     } finally {
385                         if (handle != null)
386                             context.ungetService(runningRefs[i]);
387                     }
388                 }
389         } catch (InvalidSyntaxException e) {
390             // do nothing; we already tested the filter string above
391
}
392     }
393
394     private String JavaDoc getDefaultAppId() {
395         if (defaultAppId != null)
396             return defaultAppId;
397         // try commandLineProperties
398
defaultAppId = CommandLineArgs.getApplication();
399         if (defaultAppId != null)
400             return defaultAppId;
401
402         // try bundleContext properties
403
defaultAppId = context.getProperty(EclipseAppContainer.PROP_ECLIPSE_APPLICATION);
404         if (defaultAppId != null)
405             return defaultAppId;
406
407         //Derive the application from the product information
408
defaultAppId = getBranding() == null ? null : getBranding().getApplication();
409         return defaultAppId;
410     }
411
412     public IBranding getBranding() {
413         if (branding != null)
414             return branding;
415         // try commandLineProperties
416
String JavaDoc productId = CommandLineArgs.getProduct();
417         if (productId == null) {
418             // try bundleContext properties
419
if (context == null)
420                 return null;
421             productId = context.getProperty(PROP_PRODUCT);
422             if (productId == null)
423                 return null;
424         }
425         IConfigurationElement[] entries = extensionRegistry.getConfigurationElementsFor(PI_RUNTIME, PT_PRODUCTS, productId);
426         if (entries.length > 0) {
427             // There should only be one product with the given id so just take the first element
428
branding = new ProductExtensionBranding(productId, entries[0]);
429             return branding;
430         }
431         IConfigurationElement[] elements = extensionRegistry.getConfigurationElementsFor(PI_RUNTIME, PT_PRODUCTS);
432         List logEntries = null;
433         for (int i = 0; i < elements.length; i++) {
434             IConfigurationElement element = elements[i];
435             if (element.getName().equalsIgnoreCase("provider")) { //$NON-NLS-1$
436
try {
437                     Object JavaDoc provider = element.createExecutableExtension("run"); //$NON-NLS-1$
438
Object JavaDoc[] products = (Object JavaDoc[]) EclipseAppContainer.callMethod(provider, "getProducts", null, null); //$NON-NLS-1$
439
for (int j = 0; j < products.length; j++) {
440                         if (productId.equalsIgnoreCase((String JavaDoc) EclipseAppContainer.callMethod(products[j], "getId", null, null))) {
441                             branding = new ProviderExtensionBranding(products[j]);
442                             return branding;
443                         }
444                     }
445                 } catch (CoreException e) {
446                     if (logEntries == null)
447                         logEntries = new ArrayList(3);
448                     logEntries.add(new FrameworkLogEntry(Activator.PI_APP, NLS.bind(Messages.provider_invalid, element.getParent().toString()), 0, e, null));
449                 }
450             }
451         }
452         if (logEntries != null)
453             Activator.log(new FrameworkLogEntry(Activator.PI_APP, Messages.provider_invalid_general, 0, null, (FrameworkLogEntry[]) logEntries.toArray(new FrameworkLogEntry[logEntries.size()])));
454
455         if (!missingProductReported) {
456             Activator.log(new FrameworkLogEntry(Activator.PI_APP, NLS.bind(Messages.product_notFound, productId), 0, null, null));
457             missingProductReported = true;
458         }
459         return null;
460     }
461
462     private void refreshAppDescriptors() {
463         synchronized (apps) {
464             for (Iterator allApps = apps.values().iterator(); allApps.hasNext();)
465                 ((EclipseAppDescriptor) allApps.next()).refreshProperties();
466         }
467     }
468
469     synchronized void lock(EclipseAppHandle appHandle) throws ApplicationException {
470         EclipseAppDescriptor eclipseApp = (EclipseAppDescriptor) appHandle.getApplicationDescriptor();
471         switch (isLocked(eclipseApp)) {
472             case NOT_LOCKED :
473                 break;
474             case LOCKED_SINGLETON_GLOBAL_RUNNING :
475                 throw new ApplicationException(ApplicationException.APPLICATION_INTERNAL_ERROR, NLS.bind(Messages.singleton_running, activeGlobalSingleton.getInstanceId()));
476             case LOCKED_SINGLETON_GLOBAL_APPS_RUNNING :
477                 throw new ApplicationException(ApplicationException.APPLICATION_INTERNAL_ERROR, Messages.apps_running);
478             case LOCKED_SINGLETON_SCOPED_RUNNING :
479                 throw new ApplicationException(ApplicationException.APPLICATION_INTERNAL_ERROR, NLS.bind(Messages.singleton_running, activeScopedSingleton.getInstanceId()));
480             case LOCKED_SINGLETON_LIMITED_RUNNING :
481                 throw new ApplicationException(ApplicationException.APPLICATION_INTERNAL_ERROR, NLS.bind(Messages.max_running, eclipseApp.getApplicationId()));
482             case LOCKED_MAIN_THREAD_RUNNING :
483                 throw new ApplicationException(ApplicationException.APPLICATION_INTERNAL_ERROR, NLS.bind(Messages.main_running, activeMain.getInstanceId()));
484             default :
485                 break;
486         }
487
488         if (eclipseApp.getThreadType() == EclipseAppDescriptor.FLAG_TYPE_MAIN_THREAD) {
489             if (activeMain != null)
490                 throw new IllegalStateException JavaDoc(Messages.main_running + activeMain.getInstanceId());
491         }
492         // ok we can now successfully lock the container
493
switch (eclipseApp.getCardinalityType()) {
494             case EclipseAppDescriptor.FLAG_CARD_SINGLETON_GLOGAL :
495                 activeGlobalSingleton = appHandle;
496                 break;
497             case EclipseAppDescriptor.FLAG_CARD_SINGLETON_SCOPED :
498                 activeScopedSingleton = appHandle;
499                 break;
500             case EclipseAppDescriptor.FLAG_CARD_LIMITED :
501                 if (activeLimited == null)
502                     activeLimited = new HashMap(3);
503                 ArrayList limited = (ArrayList) activeLimited.get(eclipseApp.getApplicationId());
504                 if (limited == null) {
505                     limited = new ArrayList(eclipseApp.getCardinality());
506                     activeLimited.put(eclipseApp.getApplicationId(), limited);
507                 }
508                 limited.add(appHandle);
509                 break;
510             case EclipseAppDescriptor.FLAG_CARD_UNLIMITED :
511                 break;
512             default :
513                 break;
514         }
515         if (eclipseApp.getThreadType() == EclipseAppDescriptor.FLAG_TYPE_MAIN_THREAD)
516             activeMain = appHandle;
517         activeHandles.add(appHandle);
518         refreshAppDescriptors();
519     }
520
521     synchronized void unlock(EclipseAppHandle appHandle) {
522         if (activeGlobalSingleton == appHandle)
523             activeGlobalSingleton = null;
524         else if (activeScopedSingleton == appHandle)
525             activeScopedSingleton = null;
526         else if (((EclipseAppDescriptor) appHandle.getApplicationDescriptor()).getCardinalityType() == EclipseAppDescriptor.FLAG_CARD_LIMITED) {
527             if (activeLimited != null) {
528                 ArrayList limited = (ArrayList) activeLimited.get(((EclipseAppDescriptor) appHandle.getApplicationDescriptor()).getApplicationId());
529                 if (limited != null)
530                     limited.remove(appHandle);
531             }
532         }
533         if (activeMain == appHandle)
534             activeMain = null;
535         if (activeHandles.remove(appHandle))
536             refreshAppDescriptors(); // only refresh descriptors if we really unlocked something
537
}
538
539     synchronized int isLocked(EclipseAppDescriptor eclipseApp) {
540         if (activeGlobalSingleton != null)
541             return LOCKED_SINGLETON_GLOBAL_RUNNING;
542         switch (eclipseApp.getCardinalityType()) {
543             case EclipseAppDescriptor.FLAG_CARD_SINGLETON_GLOGAL :
544                 if (activeHandles.size() > 0)
545                     return LOCKED_SINGLETON_GLOBAL_APPS_RUNNING;
546                 break;
547             case EclipseAppDescriptor.FLAG_CARD_SINGLETON_SCOPED :
548                 if (activeScopedSingleton != null)
549                     return LOCKED_SINGLETON_SCOPED_RUNNING;
550                 break;
551             case EclipseAppDescriptor.FLAG_CARD_LIMITED :
552                 if (activeLimited != null) {
553                     ArrayList limited = (ArrayList) activeLimited.get(eclipseApp.getApplicationId());
554                     if (limited != null && limited.size() >= eclipseApp.getCardinality())
555                         return LOCKED_SINGLETON_LIMITED_RUNNING;
556                 }
557                 break;
558             case EclipseAppDescriptor.FLAG_CARD_UNLIMITED :
559                 break;
560             default :
561                 break;
562         }
563         if (eclipseApp.getThreadType() == EclipseAppDescriptor.FLAG_TYPE_MAIN_THREAD && activeMain != null)
564             return LOCKED_MAIN_THREAD_RUNNING;
565         return NOT_LOCKED;
566     }
567
568     static Object JavaDoc callMethod(Object JavaDoc obj, String JavaDoc methodName, Class JavaDoc[] argTypes, Object JavaDoc[] args) {
569         Throwable JavaDoc error = null;
570         try {
571             Method JavaDoc method = obj.getClass().getMethod(methodName, argTypes);
572             return method.invoke(obj, args);
573         } catch (SecurityException JavaDoc e) {
574             error = e;
575         } catch (NoSuchMethodException JavaDoc e) {
576             error = e;
577         } catch (IllegalArgumentException JavaDoc e) {
578             error = e;
579         } catch (IllegalAccessException JavaDoc e) {
580             error = e;
581         } catch (InvocationTargetException JavaDoc e) {
582             error = e.getTargetException();
583         }
584         if (error != null) {
585             Activator.log(new FrameworkLogEntry(Activator.PI_APP, FrameworkLogEntry.ERROR, 0, "Error in invoking method.", 0, error, null));
586         }
587         return null;
588     }
589
590     public Object JavaDoc addingService(ServiceReference reference) {
591         ApplicationLauncher appLauncher;
592         ParameterizedRunnable appRunnable;
593         synchronized (this) {
594             appLauncher = (ApplicationLauncher) context.getService(reference);
595             // see if there is a default main threaded application waiting to run
596
appRunnable = defaultMainThreadAppHandle;
597             // null out so we do not attempt to start this handle again
598
defaultMainThreadAppHandle = null;
599         }
600         if (appRunnable != null)
601             // found a main threaded app; start it now that the app launcher is available
602
appLauncher.launch(appRunnable, appRunnable instanceof EclipseAppHandle ? ((EclipseAppHandle) appRunnable).getArguments().get(IApplicationContext.APPLICATION_ARGS) : null);
603         return appLauncher;
604     }
605
606     public void modifiedService(ServiceReference reference, Object JavaDoc service) {
607         // Do nothing
608
}
609
610     public void removedService(ServiceReference reference, Object JavaDoc service) {
611         // Do nothing
612
}
613 }
614
Popular Tags