package org.eclipse.ecf.examples.remoteservices.quotes.consumer; import java.lang.reflect.Method; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.ecf.services.quotes.QuoteService; import org.eclipse.ecf.services.quotes.QuoteServiceAsync; import org.eclipse.equinox.app.IApplication; import org.eclipse.equinox.app.IApplicationContext; import org.eclipse.equinox.concurrent.future.IFuture; import org.eclipse.swt.widgets.Display; import org.osgi.framework.ServiceEvent; import org.osgi.framework.ServiceException; import org.osgi.framework.ServiceListener; import org.osgi.framework.ServiceReference; @SuppressWarnings("restriction") public class Application implements IApplication { private ConsumerUI ui; @Override public Object start(IApplicationContext context) throws Exception { System.out.println("Started"); ui = new ConsumerUI(null); addListener(); ui.main(null); return null; } @Override public void stop() { System.out.println("Stopped"); } private void addListener() { Activator.getContext().addServiceListener(new ServiceListener() { @Override public void serviceChanged(final ServiceEvent event) { /* * Do only for registrations */ if (event.getType() == ServiceEvent.REGISTERED) { Object obj = Activator.getContext().getService(event.getServiceReference()); fillInfo(event.getServiceReference(), obj); /* * If we know this service * * Only call expensive getAllQuotes() on async proxy */ boolean useAsync = true; if (obj instanceof QuoteServiceAsync && useAsync) { final QuoteServiceAsync service = (QuoteServiceAsync) Activator.getContext().getService( event.getServiceReference()); /* * Decide which invocation style to use */ boolean useCallback = false; if(useCallback) { useCallbackInvocation(service); } else { useFutureInvocation(service); } } else if (obj instanceof QuoteService) { try { // this is bad because called inside a framework // thread we should no block for long final QuoteService service = (QuoteService) Activator.getContext().getService( event.getServiceReference()); // update ui updateUI(service.getServiceDescription(), service.getRandomQuote(), 1); } catch (final Exception e) { // catch all possible exceptions if (e instanceof ServiceException) { ServiceException se = (ServiceException) e; if (se.getType() == ServiceException.REMOTE) { System.err.println("Remote ServiceException caught: "); e.printStackTrace(); } } // update ui updateUI(e.getLocalizedMessage(), "", -1); } } } } private void useFutureInvocation(final QuoteServiceAsync service) { String text = ""; final IFuture future = service.getAllQuotesAsync(); // burn some CPU cycles to show async invocation int i = 0; while (!future.isDone()) { final int cycle = i++; final String serviceDesc = getServiceDesc(service); Display.getDefault().asyncExec(new Runnable() { @Override public void run() { ui.getLabel().setText( "waiting for " + serviceDesc + "... since: " + cycle); ui.redraw(); } }); // give the client some rest try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } final IStatus status = future.getStatus(); if (status.isOK()) { try { StringBuffer buf = new StringBuffer(); String[] values = (String[]) future.get(); for (int j = 0; j < values.length; j++) { String string = values[j]; buf.append(string); buf.append("\n"); } text = buf.toString(); } catch (OperationCanceledException e) { updateUI("Future invocation failed on " + getServiceDesc(service), e.getMessage(), -1); } catch (InterruptedException e) { updateUI("Future invocation failed on " + getServiceDesc(service), e.getMessage(), -1); } updateUI("Future invocation succeeded on " + getServiceDesc(service), text, 1); } else { updateUI("Future invocation failed on " + getServiceDesc(service), status.getException().getMessage(), -1); } } // get the name synchronously private String getServiceDesc(QuoteServiceAsync service) { QuoteService qs = (QuoteService) service; return qs.getServiceDescription(); } private void updateUI(String label, String text, int value) { if(value != 0) { final String fLabel = label; final String fText = text; final int fValue = value; Display.getDefault().asyncExec(new Runnable() { @Override public void run() { ui.getLabel().setText(fLabel == null ? "" : fLabel); ui.getStyledText().setText(fText == null ? "" : fText); ui.getDispatcher().setValue(fValue); ui.redraw(); } }); } } private void useCallbackInvocation(final QuoteServiceAsync service) { // create a callback to handle the async invocation MyAsyncCallback<String[]> callback = new MyAsyncCallback<String[]>(ui); service.getAllQuotesAsync(callback); } private void fillInfo(ServiceReference s, Object obj) { final StringBuffer infoBuf = new StringBuffer(); infoBuf.append("ServiceReference Info\n\t"); infoBuf.append("Bundle:\t").append(s.getBundle().getSymbolicName()).append("\n\n\t"); for (String key : s.getPropertyKeys()) if (s.getProperty(key) instanceof Object[]) for (int i = 0; i < ((Object[]) s.getProperty(key)).length; i++) if (i == 0) infoBuf.append("Property:\t").append(key).append("=") .append(((Object[]) s.getProperty(key))[i].toString()).append("\n\t"); else infoBuf.append("\t\t\t").append(key).append("=") .append(((Object[]) s.getProperty(key))[i]).append("\n\t"); else infoBuf.append("Property:\t").append(key).append("=").append(s.getProperty(key)).append("\n\t"); infoBuf.append("\nService Info\n\t"); infoBuf.append("Class:\t").append(obj.getClass().getName()).append("\n\t"); infoBuf.append("\nImplements").append("\n\t"); for (Class<?> i : obj.getClass().getInterfaces()) infoBuf.append("Class:\t").append(i.getName()).append("\n\t"); infoBuf.append("\nSupers").append("\n\t"); Class<?> sc = obj.getClass().getSuperclass(); while (sc != null && sc != Object.class) { infoBuf.append("Class:\t").append(sc.getName()).append("\n\t"); sc = sc.getClass().getSuperclass(); } infoBuf.append("\nMethods").append("\n\t"); for (Method m : obj.getClass().getMethods()) { infoBuf.append("Method:\t").append("(").append(m.getReturnType()).append(") ").append(m.getName()) .append("("); for (Class<?> c : m.getParameterTypes()) infoBuf.append(c.getSimpleName()).append(" "); infoBuf.append(")\n\t"); } Display.getDefault().asyncExec(new Runnable() { @Override public void run() { ui.getInfo().setText(infoBuf.toString()); } }); } }); } }