/******************************************************************************* * Copyright (c) 2001, 2005 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.jem.internal.proxy.ide; /* */ import java.io.*; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.jem.internal.proxy.core.*; import org.eclipse.jem.internal.proxy.core.ExpressionProxy.ProxyEvent; public class IDECallbackRegistry implements ICallbackRegistry { IDEVMServer fVMServer; int fNextCallbackID; IDEProxyFactoryRegistry fProxyFactoryRegistry; Map fCallbackIDToCallback = new HashMap(25); Map fBeanProxyToCallbackID = new HashMap(25); Map fCallbackIDToStream = new HashMap(25); private IProxyMethod initializeCallbackMethodProxy; private IBeanProxy vmServerProxy; IDECallbackRegistry(IDEProxyFactoryRegistry aRegistry){ fProxyFactoryRegistry = aRegistry; fVMServer = new IDEVMServer(this); vmServerProxy = aRegistry.getBeanProxy(fVMServer.getClass(), fVMServer); try { Method initializeCallbackMethod = org.eclipse.jem.internal.proxy.common.ICallback.class.getMethod("initializeCallback", new Class[] {org.eclipse.jem.internal.proxy.common.IVMCallbackServer.class, Integer.TYPE}); //$NON-NLS-1$ initializeCallbackMethodProxy = (IProxyMethod) aRegistry.getBeanProxy(Method.class, initializeCallbackMethod); } catch (SecurityException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } } /** * Add a callback. aBeanProxy is running on the target VM and ICallback runs on our VM * aBeanProxy will implement ICallback on the target side */ public void registerCallback(IBeanProxy aBeanProxy, ICallback aCallback){ // Get a handle to the remote VM callback org.eclipse.jem.internal.proxy.common.ICallback vmCallback = (org.eclipse.jem.internal.proxy.common.ICallback) ((IIDEBeanProxy)aBeanProxy).getBean(); fNextCallbackID = fNextCallbackID + 1; int callbackID = fNextCallbackID; vmCallback.initializeCallback( fVMServer, callbackID); Integer callbackIntegerID = new Integer(callbackID); fCallbackIDToCallback.put(callbackIntegerID,aCallback); fBeanProxyToCallbackID.put(aBeanProxy,callbackIntegerID); } /* (non-Javadoc) * @see org.eclipse.jem.internal.proxy.core.ICallbackRegistry#registerCallback(org.eclipse.jem.internal.proxy.core.IProxy, org.eclipse.jem.internal.proxy.core.ICallback, org.eclipse.jem.internal.proxy.core.IExpression) */ public void registerCallback(IProxy callbackProxy, final ICallback cb, IExpression expression) { final Integer callbackID = new Integer(++fNextCallbackID); fCallbackIDToCallback.put(callbackID, cb); if (callbackProxy.isBeanProxy()) { fBeanProxyToCallbackID.put(callbackProxy, callbackID); } else { ((ExpressionProxy) callbackProxy).addProxyListener(new ExpressionProxy.ProxyAdapter() { public void proxyResolved(ProxyEvent event) { fBeanProxyToCallbackID.put(event.getProxy(), callbackID); } }); } expression.createSimpleMethodInvoke(initializeCallbackMethodProxy, callbackProxy, new IProxy[] {vmServerProxy, fProxyFactoryRegistry.getBeanProxyFactory().createBeanProxyWith(callbackID.intValue())}, false); } OutputStream requestStream(final int aCallbackID, final int aMsgID){ final PipedOutputStream result = new PipedOutputStream(); PipedInputStream tempStream = null; try { tempStream = new PipedInputStream(result); } catch ( IOException exc ) { ProxyPlugin.getPlugin().getLogger().log(new Status(IStatus.WARNING, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, "", exc)); //$NON-NLS-1$ return null; } final PipedInputStream inputStream = tempStream; Thread streamProcessor = new Thread(){ public void run(){ ICallback ideCallback = (ICallback)fCallbackIDToCallback.get(new Integer(aCallbackID)); if (ideCallback != null) { try { ideCallback.calledBackStream(aMsgID, inputStream); } finally { try { inputStream.close(); // Make sure it's closed. } catch ( IOException exc ){ ProxyPlugin.getPlugin().getLogger().log(new Status(IStatus.WARNING, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, "", exc)); //$NON-NLS-1$ } } } } }; streamProcessor.start(); return result; } Object vmCallback(int aCallbackID ,int aMsgID, Object[] parms){ // Find the bean proxy that registered with the ID ICallback ideCallback = (ICallback) fCallbackIDToCallback.get(new Integer(aCallbackID)); Object callbackResult = null; if ( parms.length == 1 ) { callbackResult = ideCallback.calledBack(aMsgID,(IBeanProxy)parms[0]); } else { callbackResult = ideCallback.calledBack(aMsgID,parms); } return callbackResult; } Object vmCallback(int aCallbackID ,int aMsgID, Object parm){ // Find the bean proxy that registered with the ID ICallback ideCallback = (ICallback) fCallbackIDToCallback.get(new Integer(aCallbackID)); return ideCallback.calledBack(aMsgID,parm); } public void deregisterCallback(IBeanProxy aBeanProxy){ // Remove the callback from both maps. The actual unregistering of the callback // on the target VM is done separately by the object that added the event handler on the target VM Integer callbackID = (Integer) fBeanProxyToCallbackID.remove(aBeanProxy); fCallbackIDToCallback.remove(callbackID); } }