| /******************************************************************************* |
| * Copyright (c) 2000, 2008 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.wst.jsdt.core.tests.runtime; |
| |
| import java.io.DataInputStream; |
| import java.io.IOException; |
| import java.net.Socket; |
| import java.net.UnknownHostException; |
| /** |
| * This is the interface to the target VM. It connects to an IDEInterface on the target side |
| * using TCP/IO to send request for code snippet evaluation and to get the result back. |
| * |
| * @see org.eclipse.wst.jsdt.core.tests.eval.target.IDEInterface for details about the protocol. |
| */ |
| public class TargetInterface { |
| /** |
| * Whether class files should be written in d:\eval\ instead of sending them to the target |
| * NB: d:\eval should contain a batch file TestCodeSnippet.bat with the following contents: |
| * SET JDK=c:\jdk1.2.2 |
| * SET EVAL=d:\eval |
| * %JDK%\bin\java -Xbootclasspath:%JDK%\jre\lib\rt.jar;%EVAL%\javaClasses; -classpath c:\temp;%EVAL%\snippets;%EVAL%\classes;"d:\ide\project_resources\Eclipse Java Evaluation\CodeSnippetSupport.jar" CodeSnippetTester %1 |
| */ |
| static final boolean DEBUG = false; |
| String codeSnippetClassName; |
| |
| /** |
| * Whether timing info should be printed to stdout |
| */ |
| static final boolean TIMING = false; |
| long sentTime; |
| |
| /** |
| * The connection to the target's ide interface. |
| */ |
| Socket socket; |
| |
| public class Result { |
| public char[] displayString; |
| public char[] typeName; |
| } |
| |
| /** |
| * (PRIVATE API) |
| * Connects this interface to the target. |
| * Try as long as the given time (in ms) has not expired. |
| * Use isConnected() to find out if the connection was successful. |
| */ |
| public void connect(String targetAddress, int portNumber, int timeout) { |
| if (isConnected()) { |
| return; |
| } |
| if (portNumber > 0) { |
| long startTime = System.currentTimeMillis(); |
| do { |
| try { |
| this.socket = new Socket(targetAddress, portNumber); |
| this.socket.setTcpNoDelay(true); |
| break; |
| } catch (UnknownHostException e) { |
| } catch (IOException e) { |
| } |
| if (this.socket == null) { |
| try { |
| Thread.sleep(100); |
| } catch (InterruptedException e) { |
| } |
| } |
| } while (!isConnected() && (System.currentTimeMillis() - startTime) < timeout); |
| } |
| } |
| /** |
| * (PRIVATE API) |
| * Disconnects this interface from the target. |
| */ |
| public void disconnect() { |
| if (this.socket != null) { |
| try { |
| this.socket.close(); |
| } catch (IOException e) { |
| // Already closed. Nothing more to do |
| } |
| this.socket = null; |
| } |
| } |
| /** |
| * Returns the result of the evaluation sent previously to the target. |
| */ |
| public Result getResult() { |
| boolean hasValue = false; |
| String typeName = null; |
| String toString = null; |
| if (DEBUG) { |
| hasValue = true; |
| typeName = "TargetInterface in debug mode. Run d:\\eval\\TestCodeSnippet.bat d:\\eval\\snippets\\" + codeSnippetClassName; |
| toString = ""; |
| } else { |
| if (this.isConnected()) { |
| // TBD: Read type name and toString as a character array |
| try { |
| DataInputStream in = new DataInputStream(this.socket.getInputStream()); |
| hasValue = in.readBoolean(); |
| if (hasValue) { |
| typeName = in.readUTF(); |
| toString = in.readUTF(); |
| } else { |
| typeName = null; |
| toString = null; |
| } |
| } catch (IOException e) { |
| // The socket has likely been closed on the other end. So the code snippet runner has stopped. |
| hasValue = true; |
| typeName = e.getMessage(); |
| toString = ""; |
| this.disconnect(); |
| } |
| } else { |
| hasValue = true; |
| typeName = "Connection has been lost"; |
| toString = ""; |
| } |
| } |
| if (TIMING) { |
| System.out.println("Time to send compiled classes, run on target and get result is " + (System.currentTimeMillis() - this.sentTime) + "ms"); |
| } |
| Result result = new Result(); |
| result.displayString = toString == null ? null : toString.toCharArray(); |
| result.typeName = typeName == null ? null : typeName.toCharArray(); |
| return result; |
| } |
| /** |
| * Returns whether this interface is connected to the target. |
| */ |
| boolean isConnected() { |
| return this.socket != null; |
| } |
| /** |
| * Sends the given class definitions to the target for loading and (if specified) for running. |
| */ |
| |
| } |