KickJava   Java API By Example, From Geeks To Geeks.

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


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  * Josh Arnold - Bug 180080 Equinox Application Admin spec violations
11  *******************************************************************************/

12
13 package org.eclipse.equinox.internal.app;
14
15 import java.util.*;
16 import org.eclipse.core.runtime.*;
17 import org.eclipse.equinox.app.IApplication;
18 import org.eclipse.equinox.app.IApplicationContext;
19 import org.eclipse.osgi.service.runnable.ApplicationRunnable;
20 import org.eclipse.osgi.service.runnable.StartupMonitor;
21 import org.eclipse.osgi.util.NLS;
22 import org.osgi.framework.*;
23 import org.osgi.service.application.ApplicationHandle;
24
25 /*
26  * An ApplicationHandle that represents a single instance of a running eclipse application.
27  */

28 public class EclipseAppHandle extends ApplicationHandle implements ApplicationRunnable, IApplicationContext {
29     // Indicates the application is starting
30
private static final int FLAG_STARTING = 0x01;
31     // Indicates the application is active
32
private static final int FLAG_ACTIVE = 0x02;
33     // Indicates the application is stopping
34
private static final int FLAG_STOPPING = 0x04;
35     // Indicates the application is stopped
36
private static final int FLAG_STOPPED = 0x08;
37     private static final String JavaDoc STARTING = "org.eclipse.equinox.app.starting"; //$NON-NLS-1$
38
private static final String JavaDoc STOPPED = "org.eclipse.equinox.app.stopped"; //$NON-NLS-1$
39
private static final String JavaDoc PROP_ECLIPSE_EXITCODE = "eclipse.exitcode"; //$NON-NLS-1$
40

41     private volatile ServiceRegistration handleRegistration;
42     private int status = EclipseAppHandle.FLAG_STARTING;
43     private final Map arguments;
44     private Object JavaDoc application;
45     private final Boolean JavaDoc defaultAppInstance;
46     private Object JavaDoc result;
47     private boolean setResult = false;
48
49     /*
50      * Constructs a handle for a single running instance of a eclipse application.
51      */

52     EclipseAppHandle(String JavaDoc instanceId, Map arguments, EclipseAppDescriptor descriptor) {
53         super(instanceId, descriptor);
54         defaultAppInstance = arguments == null || arguments.get(EclipseAppDescriptor.APP_DEFAULT) == null ? Boolean.FALSE : (Boolean JavaDoc) arguments.remove(EclipseAppDescriptor.APP_DEFAULT);
55         if (arguments == null)
56             this.arguments = new HashMap(2);
57         else
58             this.arguments = new HashMap(arguments);
59     }
60
61     synchronized public String JavaDoc getState() {
62         switch (status) {
63             case FLAG_STARTING :
64                 return STARTING;
65             case FLAG_ACTIVE :
66                 return ApplicationHandle.RUNNING;
67             case FLAG_STOPPING :
68                 return ApplicationHandle.STOPPING;
69             case FLAG_STOPPED :
70             default :
71                 // must only check this if the status is STOPPED; otherwise we throw exceptions before we have set the registration.
72
if (handleRegistration == null)
73                     throw new IllegalStateException JavaDoc(NLS.bind(Messages.application_error_state_stopped, getInstanceId()));
74                 return STOPPED;
75         }
76     }
77
78     protected void destroySpecific() {
79         // when this method is called we must force the application to exit.
80
// first set the status to stopping
81
setAppStatus(EclipseAppHandle.FLAG_STOPPING);
82         // now force the appliction to stop
83
IApplication app = getApplication();
84         if (app != null)
85             app.stop();
86         // make sure the app status is stopped
87
setAppStatus(EclipseAppHandle.FLAG_STOPPED);
88     }
89
90     synchronized void setServiceRegistration(ServiceRegistration sr) {
91         this.handleRegistration = sr;
92     }
93
94     ServiceReference getServiceReference() {
95         ServiceRegistration reg = handleRegistration;
96         if (reg == null)
97             return null;
98         try {
99             return reg.getReference();
100         } catch (IllegalStateException JavaDoc e) {
101             return null; // this will happen if the service has been unregistered already
102
}
103     }
104     /*
105      * Gets a snapshot of the current service properties.
106      */

107     Dictionary getServiceProperties() {
108         Dictionary props = new Hashtable(6);
109         props.put(ApplicationHandle.APPLICATION_PID, getInstanceId());
110         props.put(ApplicationHandle.APPLICATION_STATE, getState());
111         props.put(ApplicationHandle.APPLICATION_DESCRIPTOR, getApplicationDescriptor().getApplicationId());
112         props.put(EclipseAppDescriptor.APP_TYPE, ((EclipseAppDescriptor) getApplicationDescriptor()).getThreadTypeString());
113         if (defaultAppInstance.booleanValue())
114             props.put(EclipseAppDescriptor.APP_DEFAULT, defaultAppInstance);
115         return props;
116     }
117
118     /*
119      * Changes the status of this handle. This method will properly transition
120      * the state of this handle and will update the service registration accordingly.
121      */

122     private synchronized void setAppStatus(int status) {
123         if (this.status == status)
124             return;
125         if ((status & EclipseAppHandle.FLAG_STARTING) != 0)
126             throw new IllegalArgumentException JavaDoc("Cannot set app status to ACTIVE"); //$NON-NLS-1$
127
// if status is stopping and the context is already stopping then return
128
if ((status & EclipseAppHandle.FLAG_STOPPING) != 0)
129             if ((this.status & (EclipseAppHandle.FLAG_STOPPING | EclipseAppHandle.FLAG_STOPPED)) != 0)
130                 return;
131         // change the service properties to reflect the state change.
132
this.status = status;
133         if (handleRegistration == null)
134             return;
135         handleRegistration.setProperties(getServiceProperties());
136         // if the status is stopped then unregister the service
137
if ((this.status & EclipseAppHandle.FLAG_STOPPED) != 0) {
138             ((EclipseAppDescriptor) getApplicationDescriptor()).getContainerManager().unlock(this);
139             handleRegistration.unregister();
140             handleRegistration = null;
141         }
142     }
143
144     public Map getArguments() {
145         return arguments;
146     }
147
148     public Object JavaDoc run(Object JavaDoc context) throws Exception JavaDoc {
149         if (context != null) {
150             // always force the use of the context if it is not null
151
arguments.put(IApplicationContext.APPLICATION_ARGS, context);
152         } else {
153             // get the context from the arguments
154
context = arguments.get(IApplicationContext.APPLICATION_ARGS);
155             if (context == null) {
156                 // if context is null then use the args from CommandLineArgs
157
context = CommandLineArgs.getApplicationArgs();
158                 arguments.put(IApplicationContext.APPLICATION_ARGS, context);
159             }
160         }
161         Object JavaDoc tempResult = null;
162         try {
163             Object JavaDoc app;
164             synchronized (this) {
165                 application = getConfiguration().createExecutableExtension("run"); //$NON-NLS-1$
166
app = application;
167             }
168             if (app instanceof IApplication)
169                 tempResult = ((IApplication) app).start(this);
170             else
171                 tempResult = EclipseAppContainer.callMethod(app, "run", new Class JavaDoc[] {Object JavaDoc.class}, new Object JavaDoc[] {context}); //$NON-NLS-1$
172
} finally {
173             synchronized (this) {
174                 result = tempResult;
175                 setResult = true;
176                 application = null;
177                 notify();
178                 // The application exited itself; notify the app context
179
setAppStatus(EclipseAppHandle.FLAG_STOPPED);
180             }
181         }
182         int exitCode = result instanceof Integer JavaDoc ? ((Integer JavaDoc) result).intValue() : 0;
183         // only set the exit code property if this is the default application
184
if (isDefault())
185             // use the long way to set the property to compile against eeminimum
186
// TODO strange that this is done here instead of by EclipseStarter
187
System.getProperties().setProperty(PROP_ECLIPSE_EXITCODE, Integer.toString(exitCode));
188         if (Activator.DEBUG)
189             System.out.println(NLS.bind(Messages.application_returned, (new String JavaDoc[] {getApplicationDescriptor().getApplicationId(), result == null ? "null" : result.toString()}))); //$NON-NLS-1$
190
return result;
191     }
192
193     public void stop() {
194         try {
195             destroy();
196         } catch (IllegalStateException JavaDoc e) {
197             // Do nothing; we don't care that the application was already stopped
198
// return with no error
199
}
200
201     }
202
203     public void applicationRunning() {
204         // first set the application handle status to running
205
setAppStatus(EclipseAppHandle.FLAG_ACTIVE);
206         // now run the splash handler
207
final ServiceReference[] monitors = getStartupMonitors();
208         if (monitors == null)
209             return;
210         SafeRunner.run(new ISafeRunnable() {
211             public void handleException(Throwable JavaDoc e) {
212                 // just continue ... the exception has already been logged by
213
// handleException(ISafeRunnable)
214
}
215
216             public void run() throws Exception JavaDoc {
217                 for (int i = 0; i < monitors.length; i++) {
218                     StartupMonitor monitor = (StartupMonitor) Activator.getContext().getService(monitors[i]);
219                     if (monitor != null) {
220                         monitor.applicationRunning();
221                         Activator.getContext().ungetService(monitors[i]);
222                     }
223                 }
224             }
225         });
226     }
227
228     private ServiceReference[] getStartupMonitors() {
229         // assumes theStartupMonitor is available as a service
230
// see EclipseStarter.publishSplashScreen
231
ServiceReference[] refs = null;
232         try {
233             refs = Activator.getContext().getServiceReferences(StartupMonitor.class.getName(), null);
234         } catch (InvalidSyntaxException e) {
235             // ignore; this cannot happen
236
}
237         if (refs == null || refs.length == 0)
238             return null;
239         // Implement our own Comparator to sort services
240
Arrays.sort(refs, new Comparator() {
241             public int compare(Object JavaDoc o1, Object JavaDoc o2) {
242                 // sort in descending order
243
// sort based on service ranking first; highest rank wins
244
ServiceReference ref1 = (ServiceReference) o1;
245                 ServiceReference ref2 = (ServiceReference) o2;
246                 Object JavaDoc property = ref1.getProperty(Constants.SERVICE_RANKING);
247                 int rank1 = (property instanceof Integer JavaDoc) ? ((Integer JavaDoc) property).intValue() : 0;
248                 property = ref2.getProperty(Constants.SERVICE_RANKING);
249                 int rank2 = (property instanceof Integer JavaDoc) ? ((Integer JavaDoc) property).intValue() : 0;
250                 if (rank1 != rank2)
251                     return rank1 > rank2 ? -1 : 1;
252                 // rankings are equal; sort by id, lowest id wins
253
long id1 = ((Long JavaDoc) (ref1.getProperty(Constants.SERVICE_ID))) .longValue();
254                 long id2 = ((Long JavaDoc) (ref2.getProperty(Constants.SERVICE_ID))) .longValue();
255                 return id2 > id1 ? -1 : 1;
256             }
257         });
258         return refs;
259     }
260
261     private synchronized IApplication getApplication() {
262         return (IApplication) ((application instanceof IApplication) ? application : null);
263     }
264
265     private IConfigurationElement getConfiguration() {
266         IExtension applicationExtension = ((EclipseAppDescriptor) getApplicationDescriptor()).getContainerManager().getAppExtension(getApplicationDescriptor().getApplicationId());
267         if (applicationExtension == null)
268             throw new RuntimeException JavaDoc(NLS.bind(Messages.application_notFound, getApplicationDescriptor().getApplicationId(), ((EclipseAppDescriptor) getApplicationDescriptor()).getContainerManager().getAvailableAppsMsg()));
269         IConfigurationElement[] configs = applicationExtension.getConfigurationElements();
270         if (configs.length == 0)
271             throw new RuntimeException JavaDoc(NLS.bind(Messages.application_invalidExtension, getApplicationDescriptor().getApplicationId()));
272         return configs[0];
273     }
274
275     public String JavaDoc getBrandingApplication() {
276         IBranding branding = ((EclipseAppDescriptor) getApplicationDescriptor()).getContainerManager().getBranding();
277         return branding == null ? null : branding.getApplication();
278     }
279
280     public Bundle getBrandingBundle() {
281         IBranding branding = ((EclipseAppDescriptor) getApplicationDescriptor()).getContainerManager().getBranding();
282         return branding == null ? null : branding.getDefiningBundle();
283
284     }
285
286     public String JavaDoc getBrandingDescription() {
287         IBranding branding = ((EclipseAppDescriptor) getApplicationDescriptor()).getContainerManager().getBranding();
288         return branding == null ? null : branding.getDescription();
289
290     }
291
292     public String JavaDoc getBrandingId() {
293         IBranding branding = ((EclipseAppDescriptor) getApplicationDescriptor()).getContainerManager().getBranding();
294         return branding == null ? null : branding.getId();
295     }
296
297     public String JavaDoc getBrandingName() {
298         IBranding branding = ((EclipseAppDescriptor) getApplicationDescriptor()).getContainerManager().getBranding();
299         return branding == null ? null : branding.getName();
300
301     }
302
303     public String JavaDoc getBrandingProperty(String JavaDoc key) {
304         IBranding branding = ((EclipseAppDescriptor) getApplicationDescriptor()).getContainerManager().getBranding();
305         return branding == null ? null : branding.getProperty(key);
306     }
307
308     boolean isDefault() {
309         return defaultAppInstance.booleanValue();
310     }
311
312     synchronized Object JavaDoc waitForResult(int timeout) {
313         if (!setResult)
314             try {
315                 wait(timeout); // only wait for the specified amount of time
316
} catch (InterruptedException JavaDoc e) {
317                 // Do nothing; return quickly
318
}
319         return result;
320     }
321 }
322
Popular Tags