package org.eclipse.equinox.internal.app;
import org.eclipse.osgi.framework.log.FrameworkLogEntry;
import org.eclipse.osgi.service.runnable.ApplicationRunnable;
import org.eclipse.osgi.util.NLS;
import org.osgi.framework.ServiceReference;
import org.osgi.service.application.ApplicationHandle;
import org.osgi.util.tracker.ServiceTracker;
import org.osgi.util.tracker.ServiceTrackerCustomizer;
public class DefaultApplicationListener implements ApplicationRunnable, ServiceTrackerCustomizer {
private boolean running = true;
private EclipseAppHandle launchMainApp;
private final ServiceTracker handleTracker;
private Object result;
public DefaultApplicationListener(EclipseAppHandle defaultApp) {
ServiceReference defaultRef = defaultApp.getServiceReference();
if (defaultRef == null) {
result = defaultApp.waitForResult(100);
handleTracker = null;
return;
}
ServiceTracker defaultAppTracker = new ServiceTracker(Activator.getContext(), defaultRef, this);
defaultAppTracker.open();
EclipseAppHandle trackedApp = (EclipseAppHandle) defaultAppTracker.getService();
if (trackedApp == null) {
defaultAppTracker.close();
result = defaultApp.waitForResult(100);
handleTracker = null;
} else {
handleTracker = defaultAppTracker;
}
}
@Override
public Object run(Object context) {
if (handleTracker == null)
return getResult();
EclipseAppHandle anyThreadedDefaultApp = (EclipseAppHandle) handleTracker.getService();
if (anyThreadedDefaultApp != null)
AnyThreadAppLauncher.launchEclipseApplication(anyThreadedDefaultApp);
try {
while (waitOnRunning()) {
EclipseAppHandle mainHandle = getMainHandle();
if (mainHandle != null) {
try {
mainHandle.run(null);
} catch (Throwable e) {
String message = NLS.bind(Messages.application_error_starting, mainHandle.getInstanceId());
Activator.log(new FrameworkLogEntry(Activator.PI_APP, FrameworkLogEntry.WARNING, 0, message, 0, e, null));
}
unsetMainHandle(mainHandle);
}
}
} finally {
handleTracker.close();
}
return getResult();
}
private synchronized EclipseAppHandle getMainHandle() {
return launchMainApp;
}
private synchronized void unsetMainHandle(EclipseAppHandle mainHandle) {
if (launchMainApp == mainHandle)
launchMainApp = null;
}
private synchronized boolean waitOnRunning() {
if (!running)
return false;
try {
wait(100);
} catch (InterruptedException e) {
}
return running;
}
@Override
public void stop() {
if (handleTracker == null)
return;
ApplicationHandle handle = (ApplicationHandle) handleTracker.getService();
if (handle != null) {
try {
handle.destroy();
} catch (Throwable t) {
String message = NLS.bind(Messages.application_error_stopping, handle.getInstanceId());
Activator.log(new FrameworkLogEntry(Activator.PI_APP, FrameworkLogEntry.WARNING, 0, message, 0, t, null));
}
}
}
@Override
public Object addingService(ServiceReference reference) {
return Activator.getContext().getService(reference);
}
@Override
public void modifiedService(ServiceReference reference, Object service) {
}
@Override
synchronized public void removedService(ServiceReference reference, Object service) {
running = false;
result = ((EclipseAppHandle) service).waitForResult(5000);
EclipseAppHandle mainHandle = getMainHandle();
if (mainHandle != null)
try {
mainHandle.destroy();
} catch (Throwable t) {
String message = NLS.bind(Messages.application_error_stopping, mainHandle.getInstanceId());
Activator.log(new FrameworkLogEntry(Activator.PI_APP, FrameworkLogEntry.WARNING, 0, message, 0, t, null));
}
this.notify();
}
synchronized void launch(EclipseAppHandle app) {
launchMainApp = app;
this.notify();
}
private synchronized Object getResult() {
return result;
}
}