/******************************************************************************* * 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.remote; /* */ import java.io.*; import java.net.Socket; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.jem.internal.proxy.common.CommandException; import org.eclipse.jem.internal.proxy.common.remote.*; import org.eclipse.jem.internal.proxy.common.remote.Commands.*; import org.eclipse.jem.internal.proxy.core.ProxyPlugin; import org.eclipse.jem.util.TimerTests; /** * The default implementation of the connection. * * It uses the property "proxyvm.bufsize" to determine the buffer size to use. If not specified, it uses the system default */ public class REMConnection implements IREMConnection, IREMExpressionConnection { public final static String INVOKE_STEP = "Invoke"; //$NON-NLS-1$ public final static String INVOKE_METHOD_STEP = "Invoke Method"; //$NON-NLS-1$ protected Socket fSocket = null; protected DataInputStream in = null; protected DataOutputStream out = null; private static final int TIME_OUT = 1000 * 60; // Wait up to a minute before timeout. public REMConnection(Socket socket, boolean noTimeouts) { try { fSocket = socket; fSocket.setSoLinger(true, 30); // Wait 30 seconds if necessary for the final stuff to go out after closing. if (!noTimeouts) fSocket.setSoTimeout(TIME_OUT); // Timeout period Integer bufSize = Integer.getInteger("proxyvm.bufsize"); //$NON-NLS-1$ if (bufSize == null) bufSize = new Integer(16000); out = new DataOutputStream(new BufferedOutputStream(fSocket.getOutputStream(), bufSize.intValue())); // It didn't take the hint, so we will buffer it. in = new DataInputStream(new BufferedInputStream(fSocket.getInputStream(), bufSize.intValue())); // It didn't take the hint, so we will buffer it. } catch (IOException e) { ProxyPlugin.getPlugin().getLogger().log(new Status(IStatus.ERROR, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, "", e)); //$NON-NLS-1$ if (out != null) try { out.close(); } catch (IOException e2) { } if (in != null) try { in.close(); } catch (IOException e3) { } try { fSocket.close(); } catch (IOException e4) { } fSocket = null; in = null; out = null; } } /** * Did this construct correctly. * This is needed because an exception could be thrown in the ctor and * that's not a good thing to do. */ public boolean isConnected() { return fSocket != null; } /** * Terminate the server. */ public void terminateServer() { if (isConnected()) { try { Commands.sendTerminateCommand(out); } catch (IOException e) { } close(); } } /** * Close the connection. */ public void close() { if (isConnected()) { try { Commands.sendQuitCommand(out); } catch (IOException e) { } finally { try { out.close(); } catch (IOException e2) { } try { in.close(); } catch (IOException e3) { } try { fSocket.close(); } catch (IOException e4) { } } fSocket = null; in = null; out = null; } } /** * Return the class information. */ public GetClassReturn getClass(String className) throws CommandException { if (isConnected()) try { // It's simple, just pass onto Commands. return Commands.sendGetClassCommand(out, in, className); } catch (CommandErrorException e) { if (e.getErrorCode() != Commands.GET_CLASS_NOT_FOUND) throw e; // Not class not found, send it on } return null; // Not found, so return null } /** * Return the class information given an ID. */ public GetClassIDReturn getClassFromID(int classID) throws CommandException { if (isConnected()) { // It's simple, just pass onto Commands. return Commands.sendGetClassFromIDCommand(out, in, classID); } return null; // Not found, so return null } /** * Get the object data from an id. */ public void getObjectData(int classID, Commands.ValueObject valueReturn) throws CommandException { if (isConnected()) { // Just pass onto Commands. Commands.sendGetObjectData(out, in, classID, valueReturn); } else valueReturn.set(); // Set it to null since we aren't connected. } /** * Get a new instance using an init string */ public void getNewInstance(int classID, String initString, Commands.ValueObject newInstance) throws CommandException { if (isConnected()) { // Just pass onto Commands. Commands.sendNewInstance(out, in, classID, initString, newInstance); } else newInstance.set(); // Set it to null since we aren't connected. } /** * Release the id. */ public void releaseID(int id){ if (isConnected()) try { // Just pass onto Commands. Commands.releaseObjectCommand(out, id); } catch (IOException e) { // Don't care it didn't work } } /* * (non-Javadoc) * @see org.eclipse.jem.internal.proxy.remote.IREMConnection#getArrayContents(int, org.eclipse.jem.internal.proxy.common.remote.Commands.ValueObject) */ public void getArrayContents(int arrayID, Commands.ValueObject returnValue) throws CommandException { if (isConnected()) { // It's simple, just pass onto Commands. Commands.sendGetArrayContentsCommand(out, in, arrayID, returnValue); } } /** * Invoke the method call */ public void invokeMethod(int methodID, Commands.ValueObject invokeOn, Commands.ValueObject parms, Commands.ValueObject returnValue) throws CommandException { if (isConnected()) { // It's simple, just pass onto Commands. TimerTests.basicTest.startCumulativeStep(INVOKE_METHOD_STEP); Commands.sendInvokeMethodCommand(out, in, methodID, invokeOn, parms, returnValue); TimerTests.basicTest.stopCumulativeStep(INVOKE_METHOD_STEP); } } /* (non-Javadoc) * @see org.eclipse.jem.internal.proxy.remote.IREMConnection#invokeMethod(org.eclipse.jem.internal.proxy.common.remote.Commands.ValueObject, java.lang.String, org.eclipse.jem.internal.proxy.common.remote.Commands.ValueObject, org.eclipse.jem.internal.proxy.common.remote.Commands.ValueObject, org.eclipse.jem.internal.proxy.common.remote.Commands.ValueObject, org.eclipse.jem.internal.proxy.common.remote.Commands.ValueObject) */ public void invokeMethod(ValueObject classType, String methodName, ValueObject parmTypes, ValueObject invokeOn, ValueObject parms, ValueObject returnValue) throws CommandException { if (isConnected()) { // It's simple, just pass onto Commands. TimerTests.basicTest.startCumulativeStep(INVOKE_STEP); Commands.sendInvokeMethodCommand(out, in, classType, methodName, parmTypes, invokeOn, parms, returnValue); TimerTests.basicTest.stopCumulativeStep(INVOKE_STEP); } } /* ************************************************************ * Put the Expression processing commands here. * * ************************************************************/ /* (non-Javadoc) * @see org.eclipse.jem.internal.proxy.remote.IREMExpressionConnection#startExpressionProcessing() */ public void startExpressionProcessing(int expressionID, byte trace) throws IOException { if (isConnected()) ExpressionCommands.sendStartExpressionProcessingCommand(expressionID, trace, out); } /* (non-Javadoc) * @see org.eclipse.jem.internal.proxy.remote.IREMExpressionConnection#pushExpressionCommand(byte) */ public void pushExpressionCommand(int expressionID, byte subcommand) throws IOException { if (isConnected()) ExpressionCommands.sendExpressionCommand(expressionID, out, subcommand); } /* (non-Javadoc) * @see org.eclipse.jem.internal.proxy.remote.IREMExpressionConnection#stopExpressionProcessing() */ public void stopExpressionProcessing(int expressionID) throws IOException { if (isConnected()) ExpressionCommands.sendEndExpressionProcessingCommand(expressionID, out); } /* (non-Javadoc) * @see org.eclipse.jem.internal.proxy.remote.IREMExpressionConnection#pushValueObject(org.eclipse.jem.internal.proxy.common.remote.Commands.ValueObject) */ public void pushValueObject(ValueObject valueObject) throws CommandException { if (isConnected()) Commands.writeValue(out, valueObject, false); } /* (non-Javadoc) * @see org.eclipse.jem.internal.proxy.remote.IREMExpressionConnection#pushByte(byte) */ public void pushByte(byte abyte) throws IOException { if (isConnected()) ExpressionCommands.sendByte(out, abyte); } /* (non-Javadoc) * @see org.eclipse.jem.internal.proxy.remote.IREMExpressionConnection#pushInt(int) */ public void pushInt(int anInt) throws IOException { if (isConnected()) ExpressionCommands.sendInt(out, anInt); } /* (non-Javadoc) * @see org.eclipse.jem.internal.proxy.remote.IREMExpressionConnection#pushString(java.lang.String) */ public void pushString(String aString) throws IOException { if (isConnected()) ExpressionCommands.sendString(out, aString); } /* (non-Javadoc) * @see org.eclipse.jem.internal.proxy.remote.IREMExpressionConnection#pushBoolean(boolean) */ public void pushBoolean(boolean aBool) throws IOException { if (isConnected()) ExpressionCommands.sendBoolean(out, aBool); } /* (non-Javadoc) * @see org.eclipse.jem.internal.proxy.remote.IREMExpressionConnection#getFinalValue(org.eclipse.jem.internal.proxy.common.remote.Commands.ValueObject) */ public void getFinalValue(ValueObject result) throws CommandException { if (isConnected()) Commands.readBackValue(in, result, Commands.NO_TYPE_CHECK); } /* * (non-Javadoc) * @see org.eclipse.jem.internal.proxy.remote.IREMExpressionConnection#pullValue(int, org.eclipse.jem.internal.proxy.common.remote.Commands.ValueObject) */ public void pullValue(int expressionID, ValueObject proxyids, ValueSender sender) throws CommandException { if (isConnected()) ExpressionCommands.sendPullValueCommand(expressionID, out, in, proxyids, sender); } /* * (non-Javadoc) * @see org.eclipse.jem.internal.proxy.remote.IREMExpressionConnection#sync(int, org.eclipse.jem.internal.proxy.common.remote.Commands.ValueObject) */ public void sync(int expressionID, ValueObject proxyids, ValueSender sender) throws CommandException { if (isConnected()) ExpressionCommands.sendSyncCommand(expressionID, out, in, proxyids, sender); } /* * (non-Javadoc) * @see org.eclipse.jem.internal.proxy.remote.IREMConnection#readProxyArrayValues(org.eclipse.jem.internal.proxy.common.remote.Commands.ValueObject, org.eclipse.jem.internal.proxy.common.remote.Commands.ValueSender, boolean) */ public void readProxyArrayValues(Commands.ValueObject returnValue, Commands.ValueSender valueSender, boolean allowFlag) throws CommandException { if (isConnected()) Commands.readArray(in, returnValue.anInt, valueSender, returnValue, allowFlag); } public void transferExpression(int expressionID, ValueObject expController) throws CommandException { if (isConnected()) ExpressionCommands.sendTransferExpressionCommand(expressionID, out, in, expController); } public void resumeExpression(int expressionID, ValueObject expController) throws CommandException { if (isConnected()) ExpressionCommands.sendResumeExpressionCommand(expressionID, out, expController); } }