Importing the XDebugProxy code in the HEAD. The repo was tagged with T_BEFORE_XDEBUGP...
[phpeclipse.git] / net.sourceforge.phpeclipse.xdebug.core / src / net / sourceforge / phpeclipse / xdebug / core / XDebugProxy.java
diff --git a/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/core/XDebugProxy.java b/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/core/XDebugProxy.java
new file mode 100644 (file)
index 0000000..3d6396a
--- /dev/null
@@ -0,0 +1,281 @@
+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,"<init idekey \""+fIdeKey+"\">");
+                                       
+                                               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 <code>IProxyEventListeners</code>
+        */
+       /*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;
+       }
+}
\ No newline at end of file