package net.sourceforge.phpeclipse.xdebug.core; import java.io.DataInputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.UnsupportedEncodingException; import java.net.ServerSocket; import java.net.Socket; import java.net.UnknownHostException; import net.sourceforge.phpeclipse.xdebug.core.xdebug.XDebugConnection; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.ISafeRunnable; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.IDebugEventFilter; import org.eclipse.debug.core.IDebugEventSetListener; import net.sourceforge.phpeclipse.xdebug.php.model.XDebugTarget; public class XDebugProxy { private XDebugTarget fTarget; protected String fInitString; protected String fIdeKey; protected AbstractDebugConnection fConnection; class ProxyListenerJob extends Job { public ProxyListenerJob() { super("XDebug Proxy Connection Dispatch"); setSystem(true); } /* (non-Javadoc) * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor) */ protected IStatus run(IProgressMonitor monitor) { boolean timeout; boolean error; Socket socket=null; DataInputStream reader=null; OutputStreamWriter writer=null; while (!fTerminate) { timeout = false; error = false; socket=null; reader=null; writer=null; if (monitor.isCanceled()) return Status.CANCEL_STATUS; try { socket = fProxyServerSocket.accept(); } catch (java.net.SocketTimeoutException e) { timeout=true; } catch (IOException e) { error=true; // e.printStackTrace(); } if (!(timeout || error)) { XDebugCorePlugin.log(IStatus.INFO,"Proxy: someone tries to connect"); try { writer = new OutputStreamWriter(socket.getOutputStream(), "UTF8"); reader = new DataInputStream(socket.getInputStream()); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } fConnection=(AbstractDebugConnection) new XDebugConnection(socket,reader,writer); if (fConnection.isInitialized()) { fIdeKey=fConnection.getSessionID(); XDebugCorePlugin.log(IStatus.INFO,""); fireProxyEvent(); } } } return Status.OK_STATUS; } } /** * Filters and dispatches events in a safe runnable to handle any * exceptions. */ class EventNotifier implements ISafeRunnable { private IProxyEventListener fListener; /** * @see org.eclipse.core.runtime.ISafeRunnable#handleException(java.lang.Throwable) */ public void handleException(Throwable exception) { IStatus status = new Status(IStatus.ERROR, XDebugCorePlugin.getUniqueIdentifier(), IStatus.ERROR, "An exception occurred while dispatching proxy", exception); //$NON-NLS-1$ XDebugCorePlugin.log(status); } /** * @see org.eclipse.core.runtime.ISafeRunnable#run() */ public void run() throws Exception { fListener.handleProxyEvent(fIdeKey, fInitString, fConnection); } /** * Filter and dispatch the given events. If an exception occurs in one * listener, events are still fired to subsequent listeners. * * @param events debug events */ public void dispatch() { fListener = (IProxyEventListener) getEventListener(fIdeKey); if (fListener==null) { // no listener is found so start the script try { fConnection.run(); } catch (DebugException e) { // TODO Auto-generated catch block e.printStackTrace(); } } else Platform.run(this); fListener = null; } } private ServerSocket fProxyServerSocket; private ProxyListenerJob fProxyListener; private boolean fTerminate; private int fProxyPort; private ListenerMap fEventListeners; private boolean fIsRunning; public XDebugProxy (int port) { fProxyPort=port; } public void setTarget( XDebugTarget Target ) { fTarget = Target; } public XDebugTarget getTarget() { return fTarget; } public void start() { if (fIsRunning) return; try { fProxyServerSocket = new ServerSocket(fProxyPort); // set 5sek as timeout fProxyServerSocket.setSoTimeout(5000); XDebugCorePlugin.log(IStatus.INFO,"Proxy listens on port "+fProxyPort); // fDebugReader = new BufferedReader(new InputStreamReader(fDebugSocket.getInputStream())); } catch (UnknownHostException e) { e.printStackTrace(); // abort("Unable to connect to PHP Debuger", e); } catch (IOException e) { e.printStackTrace(); // abort("Unable to connect to PHP Debuger", e); } fTerminate=false; fProxyListener = new ProxyListenerJob(); fProxyListener.schedule(); fIsRunning=true; } /* public void stop() { if (!fIsRunning) return; fTerminate=true; fProxyListener.cancel(); try { fProxyServerSocket.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } fIsRunning = false; XDebugCorePlugin.log(IStatus.INFO,"Proxy stopped"); }*/ public void stop() { if (fIsRunning) { fProxyListener.cancel(); fTerminate = true; try { fProxyServerSocket.close(); } catch (IOException e) { e.printStackTrace(); } fIsRunning = false; XDebugCorePlugin.log(IStatus.INFO,"Proxy stopped"); } } /** * Adds the given listener to the collection of registered proxy * event listeners. Has no effect if an identical listener is already * registered. * * @param listener the listener to add */ public void addProxyEventListener(IProxyEventListener listener, String key) { if (fEventListeners == null) { fEventListeners = new ListenerMap(5); } fEventListeners.add(listener, key); } /** * Removes the given listener from the collection of registered proxy * event listeners. Has no effect if an identical listener is not already * registered. * * @param listener the listener to remove */ public void removeProxyEventListener(IProxyEventListener listener,String key) { if (fEventListeners != null) { fEventListeners.remove(listener,key); } } /** * Notifies all registered proxy event set listeners of the given * proxy events. Events which are filtered by a registered debug event * filter are not fired. * * @param events array of debug events to fire * @see IDebugEventFilter * @see IDebugEventSetListener * @since 2.0 */ public void fireProxyEvent() { EventNotifier fNotifier = new EventNotifier(); fNotifier.dispatch(); } /** * Returns the collection of registered proxy event listeners * * @return list of registered proxy event listeners, instances * of IProxyEventListeners */ /*private Map getEventListeners() { return fEventListeners.getListeners(); }*/ private Object getEventListener(String ideKey) { return fEventListeners.getListener(ideKey); } /** * @return Returns the fProxyPort. */ public int getProxyPort() { return fProxyPort; } public boolean isRunning() { return fIsRunning; } }