Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/org.eclipse.jem.proxy/vm_remotevm/org/eclipse/jem/internal/proxy/vm/remote/ConnectionHandler.java')
-rw-r--r--plugins/org.eclipse.jem.proxy/vm_remotevm/org/eclipse/jem/internal/proxy/vm/remote/ConnectionHandler.java926
1 files changed, 0 insertions, 926 deletions
diff --git a/plugins/org.eclipse.jem.proxy/vm_remotevm/org/eclipse/jem/internal/proxy/vm/remote/ConnectionHandler.java b/plugins/org.eclipse.jem.proxy/vm_remotevm/org/eclipse/jem/internal/proxy/vm/remote/ConnectionHandler.java
deleted file mode 100644
index d7780b913..000000000
--- a/plugins/org.eclipse.jem.proxy/vm_remotevm/org/eclipse/jem/internal/proxy/vm/remote/ConnectionHandler.java
+++ /dev/null
@@ -1,926 +0,0 @@
-/*******************************************************************************
- * 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.vm.remote;
-/*
- * $RCSfile: ConnectionHandler.java,v $
- * $Revision: 1.16 $ $Date: 2005/12/02 18:41:25 $
- */
-
-
-import java.io.*;
-import java.lang.reflect.Array;
-import java.net.Socket;
-import java.net.SocketException;
-import java.util.*;
-
-import org.eclipse.jem.internal.proxy.common.CommandException;
-import org.eclipse.jem.internal.proxy.common.remote.*;
-import org.eclipse.jem.internal.proxy.initParser.*;
-import org.eclipse.jem.internal.proxy.initParser.tree.NoExpressionValueException;
-
-/**
- * This handles one connection.
- */
-
-public class ConnectionHandler {
-
- protected Socket socket;
- final protected RemoteVMServerThread server;
- final protected Thread connectionThread;
- protected DataInputStream in;
- protected DataOutputStream out;
-
- // Kludge: Bug in Linux 1.3.xxx of JVM. Closing a socket while the socket is being read/accept will not interrupt the
- // wait. Need to timeout to the socket read/accept before the socket close will be noticed. This has been fixed
- // in Linux 1.4. So on Linux 1.3 need to put timeouts in on those sockets that can be separately closed while reading/accepting.
- static boolean LINUX_1_3 = "linux".equalsIgnoreCase(System.getProperty("os.name")) && System.getProperty("java.version","").startsWith("1.3"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
-
- /**
- * This may be running as a callback, in that case there is no connectionThread.
- */
- public ConnectionHandler(Socket sc, RemoteVMServerThread svr, Thread connectionThread) {
- socket = sc;
- server = svr;
- this.connectionThread = connectionThread;
-
- Integer bufSize = Integer.getInteger("proxyvm.bufsize"); //$NON-NLS-1$
- if (bufSize == null)
- bufSize = new Integer(5000);
-
- try {
- out = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream(), bufSize.intValue()));
- in = new DataInputStream(new BufferedInputStream(socket.getInputStream(), bufSize.intValue()));
- } catch (IOException e) {
- }
-
- }
-
- /**
- * 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 socket != null;
- }
-
- /**
- * Request the thread to close down.
- */
- public void close() {
- if (socket != null) {
- try {
- Socket s = socket;
- socket = null;
- s.close();
- } catch (Exception e) {
- }
- }
- }
-
- // Map of ID to expression processers that are currently being processed.
- private Map expressionProcessors = new HashMap();
-
- /**
- * Process and loop until told to stop. A callback_done will stop
- * the loop and will return a result. Otherwise null is returned.
- */
- public Object run() throws CommandException {
- Object result = null;
- boolean shutdown = false;
- boolean closeWhenDone = true;
- Commands.ValueObject valueObject = new Commands.ValueObject(); // Working value object so not continually recreated.
- InvokableValueSender valueSender = new InvokableValueSender(); // Working valuesender so not continually recreated.
- try {
- boolean doLoop = true;
-
- /**
- * Note: In the cases below you will see a lot of finally clauses that null variables out.
- * This is because this is a long running loop, and variables declared within blocks are not
- * garbage collected until the method is terminated, so these variables once set would never
- * be GC'd. The nulling at the end of the case makes sure that any of those objects set are
- * now available for garbage collection when necessary.
- */
- while(doLoop && isConnected()) {
- byte cmd = 0;
- try {
- if (LINUX_1_3)
- socket.setSoTimeout(1000); // Linux 1.3 bug, see comment on LINUX_1_3
- cmd = in.readByte();
- if (LINUX_1_3 && isConnected())
- socket.setSoTimeout(0); // Linux 1.3 bug, see comment on LINUX_1_3
- } catch (InterruptedIOException e) {
- continue; // Timeout, try again
- }
- switch (cmd) {
- case Commands.QUIT_CONNECTION:
- doLoop = false;
- break; // Close this connection
-
- case Commands.TERMINATE_SERVER:
- doLoop = false;
- shutdown = true; // Shutdown everything
- break;
-
- case Commands.GET_CLASS:
- String className = in.readUTF();
- Class aClass = null;
- Class superClass = null;
- String superClassName = null;
- boolean added = false;
- try {
- aClass = Class.forName(className); // Turns out using JNI format for array type will work fine.
-
- added = server.getIdentityID(aClass, valueObject);
- boolean isInterface = aClass.isInterface();
- boolean isAbstract = java.lang.reflect.Modifier.isAbstract(aClass.getModifiers());
- superClass = aClass.getSuperclass();
- superClassName = (superClass != null) ? superClass.getName() : ""; //$NON-NLS-1$
- out.writeByte(Commands.GET_CLASS_RETURN);
- out.writeInt(valueObject.objectID);
- out.writeBoolean(isInterface);
- out.writeBoolean(isAbstract);
- out.writeUTF(superClassName);
- out.flush();
- } catch (ClassNotFoundException e) {
- valueObject.set();
- Commands.sendErrorCommand(out, Commands.GET_CLASS_NOT_FOUND, valueObject);
- } catch (ExceptionInInitializerError e) {
- sendException(e.getException(), valueObject, out);
- } catch (LinkageError e) {
- sendException(e, valueObject, out);
- } catch (Throwable e) {
- // Something bad, did we add a class? If we did remove it from the table.
- if (added)
- server.removeObject(server.getObject(valueObject.objectID));
- throw e;
- } finally {
- // clear out for GC to work.
- className = null;
- aClass = null;
- superClass = null;
- superClassName = null;
- valueObject.set();
- }
- break;
-
- case Commands.GET_CLASS_FROM_ID:
- int classID = in.readInt();
- try {
- aClass = (Class) server.getObject(classID);
- boolean isInterface = aClass.isInterface();
- boolean isAbstract = java.lang.reflect.Modifier.isAbstract(aClass.getModifiers());
- superClass = aClass.getSuperclass();
- superClassName = (superClass != null) ? superClass.getName() : ""; //$NON-NLS-1$
- out.writeByte(Commands.GET_CLASS_ID_RETURN);
- out.writeUTF(aClass.getName());
- out.writeBoolean(isInterface);
- out.writeBoolean(isAbstract);
- out.writeUTF(superClassName);
- out.flush();
- } catch (ClassCastException e) {
- valueObject.set();
- Commands.sendErrorCommand(out, Commands.CLASS_CAST_EXCEPTION, valueObject);
- } finally {
- // clear out for GC to work.
- aClass = null;
- superClass = null;
- superClassName = null;
- valueObject.set();
- }
- break;
-
- case Commands.GET_OBJECT_DATA:
- int objectID = in.readInt();
- Object anObject = null;
- try {
- anObject = server.getObject(objectID);
- valueObject.setObjectID(objectID, server.getIdentityID(anObject.getClass()));
- Commands.writeValue(out, valueObject, true);
- } catch (ClassCastException e) {
- valueObject.set();
- Commands.sendErrorCommand(out, Commands.CLASS_CAST_EXCEPTION, valueObject);
- } finally {
- anObject = null; // Clear out for GC to work
- valueObject.set();
- }
- break;
-
- case Commands.RELEASE_OBJECT:
- int id = in.readInt();
- server.removeObject(server.getObject(id));
- break;
-
- case Commands.NEW_INIT_STRING:
- classID = in.readInt(); // ID Of class to do new upon.
- String initString = in.readUTF(); // The init string.
- Object newValue = null;
- Class theClass = null;
- try {
- theClass = (Class) server.getObject(classID);
- if (theClass == null) {
- // The class wasn't found. So imply ClassNotFound exception.
- throw new ClassNotFoundException();
- }
-
- InitializationStringParser parser = null;
- try {
- parser = InitializationStringParser.createParser(initString);
- newValue = parser.evaluate();
- boolean primitive = parser.isPrimitive();
- // If expected class is Void.TYPE, that means don't test the type of the result
- // to verify if correct type, just return what it really is.
- if (theClass != Void.TYPE && primitive != theClass.isPrimitive()) {
- valueObject.set();
- Commands.sendErrorCommand(out, Commands.CLASS_CAST_EXCEPTION, valueObject);
- continue; // Goto next command.
- }
- if (primitive) {
- try {
- // Need to do special tests for compatibility and assignment.
- sendObject(newValue, classID != Commands.VOID_TYPE ? classID : server.getIdentityID(parser.getExpectedType()), valueObject, out, true); // This will make sure it goes out as the correct primitive type
- } catch (ClassCastException e) {
- // The returned type is not of the correct type for what is expected.
- valueObject.set();
- Commands.sendErrorCommand(out, Commands.CLASS_CAST_EXCEPTION, valueObject);
- continue; // Goto next command
- }
- } else {
- if (newValue != null) {
- // Test to see if they are compatible. (Null can be assigned to any object,
- // so that is why it was tested out above).
- // If expected class is Void.TYPE, that means don't test the type of the result
- // to verify if correct type, just return what it really is.
- if (theClass != Void.TYPE && !theClass.isInstance(newValue)) {
- // The returned type is not of the correct type for what is expected.
- valueObject.set();
- Commands.sendErrorCommand(out, Commands.CLASS_CAST_EXCEPTION, valueObject);
- continue; // Goto next command
- }
- }
- sendObject(newValue, NOT_A_PRIMITIVE, valueObject, out, true); // Send out as an object.
- }
- } catch (InitializationStringEvaluationException e) {
- if (e instanceof EvaluationException) {
- // Want to return the real exception.
- sendException(e.getOriginalException(), valueObject, out);
- } else {
- // Couldn't be evaluated, return an error for this.
- setExceptionIntoValue(e.getOriginalException(), valueObject);
- Commands.sendErrorCommand(out, Commands.CANNOT_EVALUATE_STRING, valueObject);
- }
- } finally {
- parser = null; // Clear out for GC to work
- }
- } catch (Throwable e) {
- sendException(e, valueObject, out);
- } finally {
- // Clear out for GC to work
- initString = null;
- theClass = null;
- newValue = null;
- valueObject.set();
- }
- break;
-
- case Commands.INVOKE:
- Object target = null;
- Object[] parms = null;
- Class returnType = null;
- java.lang.reflect.Method aMethod = null;
- try {
- int methodID = in.readInt(); // ID of method to invoke
- aMethod = (java.lang.reflect.Method) server.getObject(methodID); // Method to invoke
- Commands.readValue(in, valueObject);
- target = getInvokableObject(valueObject);
- Commands.readValue(in, valueObject);
- if (valueObject.type == Commands.ARRAY_IDS) {
- // It is an array containing IDs, as it normally would be.
- valueSender.initialize(valueObject);
- Commands.readArray(in, valueObject.anInt, valueSender, valueObject, false);
- parms = (Object[]) valueSender.getArray();
- } else {
- // It is all objects or null, so it should be an Object[] or null. If not, then this is an error.
- parms = (Object[]) valueObject.anObject;
- }
-
- if (!aMethod.isAccessible())
- aMethod.setAccessible(true); // We will allow all to occur. Let access control be handled by IDE and compiler.
- newValue = aMethod.invoke(target, parms);
- returnType = aMethod.getReturnType();
- if (returnType.isPrimitive()) {
- int returnTypeID = server.getIdentityID(returnType);
- // Need to tell sendObject the correct primitive type.
- sendObject(newValue, returnTypeID, valueObject, out, true);
-
- } else {
- sendObject(newValue, NOT_A_PRIMITIVE, valueObject, out, true); // Just send the object back. sendObject knows how to iterpret the type
- }
- } catch (CommandException e) {
- throw e; // Throw it again. These we don't want to come up as an exception proxy. These should end the thread.
- } catch (java.lang.reflect.InvocationTargetException e) {
- // This is a wrappered exception. Return the wrappered one so it looks like
- // it was the real one. (Sometimes the method being invoked is on a java.lang.reflect.Constructor.newInstance,
- // which in turn is an InvocationTargetException, so we will go until we don't have an InvocationTargetException.
- Throwable t = e;
- do {
- t = ((java.lang.reflect.InvocationTargetException) t).getTargetException();
- } while (t instanceof java.lang.reflect.InvocationTargetException);
- sendException(t, valueObject, out);
- } catch (Throwable e) {
- sendException(e, valueObject, out); // Turn it into a exception proxy on the client.
- } finally {
- // Clear out for GC to work
- valueObject.set();
- parms = null;
- target = null;
- aMethod = null;
- returnType = null;
- newValue = null;
- valueSender.clear();
- }
- break;
-
- case Commands.INVOKE_WITH_METHOD_PASSED:
- aClass = null;
- String methodName = null;
- Class[] parmTypes = null;
- target = null;
- parms = null;
- returnType = null;
- aMethod = null;
-
- try {
- Commands.readValue(in, valueObject);
- aClass = (Class) getInvokableObject(valueObject); // The class that has the method.
- methodName = in.readUTF();
- Commands.readValue(in, valueObject);
- if (valueObject.type == Commands.ARRAY_IDS) {
- // It is an array containing IDs, as it normally would be.
- valueSender.initialize(valueObject);
- Commands.readArray(in, valueObject.anInt, valueSender, valueObject, false);
- parmTypes = (Class[]) valueSender.getArray();
- } else {
- // It null, so it should be an null. If not, then this is an error.
- parmTypes = null;
- }
- aMethod = aClass.getMethod(methodName, parmTypes);
-
- // Now we get the info for the invocation of the method and execute it.
- Commands.readValue(in, valueObject);
- target = getInvokableObject(valueObject);
- Commands.readValue(in, valueObject);
- if (valueObject.type == Commands.ARRAY_IDS) {
- // It is an array containing IDs, as it normally would be.
- valueSender.initialize(valueObject);
- Commands.readArray(in, valueObject.anInt, valueSender, valueObject, false);
- parms = (Object[]) valueSender.getArray();
- } else {
- // It is all objects or null, so it should be an Object[] or null. If not, then this is an error.
- parms = (Object[]) valueObject.anObject;
- }
-
- if (!aMethod.isAccessible())
- aMethod.setAccessible(true); // We will allow all to occur. Let access control be handled by IDE and compiler.
- newValue = aMethod.invoke(target, parms);
- returnType = aMethod.getReturnType();
- if (returnType.isPrimitive()) {
- int returnTypeID = server.getIdentityID(returnType);
- // Need to tell sendObject the correct primitive type.
- sendObject(newValue, returnTypeID, valueObject, out, true);
-
- } else {
- sendObject(newValue, NOT_A_PRIMITIVE, valueObject, out, true); // Just send the object back. sendObject knows how to iterpret the type
- }
- } catch (CommandException e) {
- throw e; // Throw it again. These we don't want to come up as an exception proxy. These should end the thread.
- } catch (java.lang.reflect.InvocationTargetException e) {
- // This is a wrappered exception. Return the wrappered one so it looks like
- // it was the real one. (Sometimes the method being invoked is on a java.lang.reflect.Constructor.newInstance,
- // which in turn is an InvocationTargetException, so we will go until we don't have an InvocationTargetException.
- Throwable t = e;
- do {
- t = ((java.lang.reflect.InvocationTargetException) t).getTargetException();
- } while (t instanceof java.lang.reflect.InvocationTargetException);
- sendException(t, valueObject, out);
-
- } catch (Throwable e) {
- sendException(e, valueObject, out); // Turn it into a exception proxy on the client.
- } finally {
- aClass = null;
- methodName = null;
- parmTypes = null;
- // Clear out for GC to work
- valueObject.set();
- parms = null;
- target = null;
- aMethod = null;
- returnType = null;
- newValue = null;
- valueSender.clear();
- }
- break;
-
- case Commands.GET_ARRAY_CONTENTS:
- try {
- target = server.getObject(in.readInt()); // Array to get the ids for.
- valueObject.setArrayIDS(new ArrayContentsRetriever(target), Array.getLength(target), Commands.OBJECT_CLASS);
- Commands.writeValue(out, valueObject, true); // Write it back as a value command.
- } catch (CommandException e) {
- throw e; // Throw it again. These we don't want to come up as an exception proxy. These should end the thread.
- } catch (Throwable e) {
- sendException(e, valueObject, out); // Turn it into a exception proxy on the client.
- } finally {
- target = null;
- valueObject.set();
- }
- break;
-
- case Commands.CALLBACK_DONE:
- try {
- if (connectionThread != null) {
- valueObject.set();
- Commands.sendErrorCommand(out, Commands.UNKNOWN_COMMAND_SENT, valueObject);
- } else {
- try {
- Commands.readBackValue(in, valueObject, Commands.NO_TYPE_CHECK);
- if (valueObject.type == Commands.ARRAY_IDS) {
- // It is an array containing IDs, as it normally would be.
- valueSender.initialize(valueObject);
- Commands.readArray(in, valueObject.anInt, valueSender, valueObject, false);
- result = valueSender.getArray();
- } else {
- result = getInvokableObject(valueObject);
- }
- doLoop = false; // We need to terminate and return result
- closeWhenDone = false; // Don't close, we will continue.
- } catch (CommandErrorException e) {
- // There was an command error on the other side. This means
- // connection still good, but don't continue the callback processing.
- doLoop = false; // We need to terminate and return result
- closeWhenDone = false; // Don't close, we will continue.
- throw e; // Let it go on out.
- }
- }
- } finally {
- valueObject.set();
- valueSender.clear();
- }
- break;
-
- case Commands.ERROR:
- try {
- // Got an error command. Don't know what to do but read the
- // value and simply print it out.
- Commands.readValue(in, valueObject);
- result = getInvokableObject(valueObject);
- System.out.println("Error sent to server: Result=" + result); //$NON-NLS-1$
- } finally {
- valueObject.set();
- }
- break;
-
- case Commands.EXPRESSION_TREE_COMMAND:
- try {
- processExpressionCommand(valueObject, valueSender);
- } finally {
- valueObject.set();
- valueSender.clear();
- }
- break;
-
- default:
- // Unknown command. We don't know how long it is, so we need to shut the connection down.
- System.err.println("Error: Invalid cmd send to server: Cmd=" + cmd); //$NON-NLS-1$
- doLoop = false;
- closeWhenDone = true;
- break;
- }
- }
- } catch (EOFException e) {
- // This is ok. It means that the connection on the other side was terminated.
- // So just accept this and go down.
- } catch (CommandException e) {
- throw e;
- } catch (SocketException e) {
- if (socket != null)
- throw new UnexpectedExceptionCommandException(false, e); // socket null means a valid close request
- } catch (Throwable e) {
- e.printStackTrace();
- } finally {
- if (closeWhenDone) {
- try {
- for (Iterator itr = expressionProcessors.values().iterator(); itr.hasNext();) {
- ExpressionProcesserController exp = (ExpressionProcesserController) itr.next();
- exp.close();
- }
- } finally {
- expressionProcessors.clear();
- }
-
- if (in != null)
- try {
- in.close();
- } catch (Exception e) {
- }
- in = null;
- if (out != null)
- try {
- out.close();
- } catch (Exception e) {
- }
- out = null;
- close();
- }
- }
-
- if (closeWhenDone && connectionThread != null)
- server.removeConnectionThread(connectionThread);
- if (shutdown)
- server.requestShutdown();
-
- return result;
- }
-
- // A retriever is what handles the array get contents.
- private class ArrayContentsRetriever implements Commands.ValueRetrieve {
- int index=0;
- Object array;
- int length;
- int componentType;
- Commands.ValueObject worker = new Commands.ValueObject();
-
-
- public ArrayContentsRetriever(Object anArray) {
- array = anArray;
- length = Array.getLength(anArray);
- if (anArray.getClass().getComponentType().isPrimitive()) {
- componentType = server.getIdentityID(anArray.getClass().getComponentType());
- } else
- componentType = NOT_A_PRIMITIVE;
- }
-
- public Commands.ValueObject nextValue() {
- fillInValue(Array.get(array, index++), componentType, worker);
- return worker;
- }
- };
-
-
- private void processExpressionCommand(Commands.ValueObject valueObject, InvokableValueSender valueSender) throws IOException, CommandException {
- Integer expressionID = new Integer(in.readInt());
- byte cmdType = in.readByte();
- ExpressionProcesserController exp = null;
- switch (cmdType) {
- case ExpressionCommands.START_EXPRESSION_TREE_PROCESSING:
- byte trace = in.readByte();
- if (trace == ExpressionCommands.TRACE_DEFAULT)
- exp = new ExpressionProcesserController(server, this);
- else
- exp = new ExpressionProcesserController(server, this, trace == ExpressionCommands.TRACE_ON);
- expressionProcessors.put(expressionID, exp);
- break;
- case ExpressionCommands.TRANSFER_EXPRESSION_REQUEST:
- exp = (ExpressionProcesserController) expressionProcessors.remove(expressionID);
- sendObject(exp, NOT_A_PRIMITIVE, valueObject, out, true);
- break;
- case ExpressionCommands.RESUME_EXPRESSION_REQUEST:
- Commands.readValue(in, valueObject);
- exp = (ExpressionProcesserController) getInvokableObject(valueObject);
- expressionProcessors.put(expressionID, exp);
- break;
- case ExpressionCommands.PUSH_EXPRESSION:
- exp = (ExpressionProcesserController) expressionProcessors.get(expressionID);
- exp.process(in);
- break;
- case ExpressionCommands.SYNC_REQUEST:
- boolean haveProxies = in.readBoolean(); // See if we expression proxy ids that need to be resolved
- if (haveProxies) {
- Commands.readValue(in, valueObject);
- valueSender.initialize(valueObject);
- Commands.readArray(in, valueObject.anInt, valueSender, valueObject, false);
- }
-
- exp = (ExpressionProcesserController) expressionProcessors.get(expressionID);
- if (haveProxies)
- sendExpressionProxyResolutions(valueObject, (int[]) valueSender.getArray(), exp);
- if (exp.noErrors()) {
- valueObject.set(true); // Mark that all is good.
- Commands.writeValue(out, valueObject, true, true);
- } else {
- processExpressionError(exp, valueObject);
- }
- break;
- case ExpressionCommands.PULL_VALUE_REQUEST:
- haveProxies = in.readBoolean(); // See if we expression proxy ids that need to be resolved
- if (haveProxies) {
- Commands.readValue(in, valueObject);
- valueSender.initialize(valueObject);
- Commands.readArray(in, valueObject.anInt, valueSender, valueObject, false);
- }
-
- exp = (ExpressionProcesserController) expressionProcessors.get(expressionID);
- if (haveProxies)
- sendExpressionProxyResolutions(valueObject, (int[]) valueSender.getArray(), exp);
- if (exp.noErrors()) {
- try {
- Object[] pulledValue = exp.pullValue();
- // Send back the command code for pull value. Don't flush. We will flush when all done.
- if (((Class) pulledValue[1]).isPrimitive()) {
- int returnTypeID = server.getIdentityID(pulledValue[1]);
- // Need to tell sendObject the correct primitive type.
- sendObject(pulledValue[0], returnTypeID, valueObject, out, true, true);
-
- } else {
- sendObject(pulledValue[0], NOT_A_PRIMITIVE, valueObject, out, true, true); // Just send the object back. sendObject knows how to iterpret the type
- }
- } catch (NoExpressionValueException e) {
- sendNoValueErrorCommand(exp, valueObject);
- }
- } else
- processExpressionError(exp, valueObject);
- break;
- case ExpressionCommands.END_EXPRESSION_TREE_PROCESSING:
- exp = (ExpressionProcesserController) expressionProcessors.remove(expressionID);
- exp.close();
- break;
- }
- }
-
- /*
- * @param is
- * @param exp
- *
- * @since 1.1.0
- */
- private void sendExpressionProxyResolutions(Commands.ValueObject valueObject, final int[] proxyIDs, final ExpressionProcesserController exp) throws CommandException {
- class ExpressionProxyRetriever implements Commands.ValueRetrieve {
- int index = 0;
- Object[] proxyResolution = new Object[2];
- Commands.ValueObject worker = new Commands.ValueObject();
-
- public Commands.ValueObject nextValue() {
- int proxyID = proxyIDs[index++];
- if (exp.pullExpressionProxyValue(proxyID, proxyResolution)) {
- if (proxyResolution[1] != Void.TYPE) {
- if (((Class) proxyResolution[1]).isPrimitive()) {
- int returnTypeID = server.getIdentityID(proxyResolution[1]);
- // Need to tell worker the correct primitive type.
- fillInValue(proxyResolution[0], returnTypeID, worker);
- } else {
- fillInValue(proxyResolution[0], NOT_A_PRIMITIVE, worker);
- }
- } else
- worker.setFlag(ExpressionCommands.EXPRESSIONPROXY_VOIDTYPE); // It was resolved, but to not set due to void type of expression.
- } else
- worker.setFlag(ExpressionCommands.EXPRESSIONPROXY_NOTRESOLVED); // It wasn't resolved.
-
- return worker;
- }
- };
-
- valueObject.setArrayIDS(new ExpressionProxyRetriever(), proxyIDs.length, Commands.OBJECT_CLASS);
- Commands.writeValue(out, valueObject, true, false); // Write it back as a value command.
-
- }
-
- private void processExpressionError(ExpressionProcesserController exp, Commands.ValueObject valueObject) throws CommandException {
- if (exp.isNoExpressionValue()) {
- sendNoValueErrorCommand(exp, valueObject);
- } else
- sendException(exp.getErrorThrowable(), valueObject, out);
- }
-
- /*
- * @param exp
- * @param valueObject
- * @throws CommandException
- *
- * @since 1.1.0
- */
- private void sendNoValueErrorCommand(ExpressionProcesserController exp, Commands.ValueObject valueObject) throws CommandException {
- setExceptionIntoValue(exp.getErrorThrowable(), valueObject);
- Commands.sendErrorCommand(out, ExpressionCommands.EXPRESSION_NOEXPRESSIONVALUE_EXCEPTION, valueObject);
- }
-
-protected static final int NOT_A_PRIMITIVE = Commands.NOT_AN_ID;
-protected static final int SEND_AS_IS = -2; // This means sends as an object not as an id.
-
-public static final int CLASS_ADDED = 1;
-public static final int OBJECT_ADDED = 2;
-public int fillInValue(Object object, int primitiveTypeID, Commands.ValueObject valueObject) {
- int added = 0;
- if (object == null) {
- valueObject.set();
- } else {
- int classID = 0;
- if (primitiveTypeID != NOT_A_PRIMITIVE && primitiveTypeID != SEND_AS_IS) {
- classID = primitiveTypeID; // The object is really supposed to be a primitive of this type
- switch (classID) {
- case Commands.BOOLEAN_TYPE:
- valueObject.set(((Boolean) object).booleanValue());
- break;
- case Commands.INTEGER_TYPE:
- if (object instanceof Character)
- valueObject.set((int) ((Character) object).charValue()); // Because char can be widened to an int
- else
- valueObject.set(((Number) object).intValue());
- break;
- case Commands.BYTE_TYPE:
- valueObject.set(((Number) object).byteValue());
- break;
- case Commands.CHARACTER_TYPE:
- valueObject.set(((Character) object).charValue());
- break;
- case Commands.DOUBLE_TYPE:
- if (object instanceof Character)
- valueObject.set((double) ((Character) object).charValue()); // Because char can be widened to a double
- else
- valueObject.set(((Number) object).doubleValue());
- break;
- case Commands.FLOAT_TYPE:
- if (object instanceof Character)
- valueObject.set((float) ((Character) object).charValue()); // Because char can be widened to a float
- else
- valueObject.set(((Number) object).floatValue());
- break;
- case Commands.SHORT_TYPE:
- valueObject.set(((Number) object).shortValue());
- break;
- case Commands.LONG_TYPE:
- if (object instanceof Character)
- valueObject.set((long) ((Character) object).charValue()); // Because char can be widened to a long
- else
- valueObject.set(((Number) object).longValue());
- break;
- }
- } else {
- // It's not a primitive.
- boolean addObject = false, addClass = false;
- Class objClass = object.getClass();
- classID = server.getIdentityID(objClass);
- if (classID == RemoteVMServerThread.ID_NOT_FOUND) {
- Commands.ValueObject classValue = new Commands.ValueObject();
- addClass = server.getIdentityID(objClass, classValue);
- if (addClass)
- added |= CLASS_ADDED;
- classID = classValue.objectID;
- }
-
- switch (classID) {
- case Commands.BYTE_CLASS:
- valueObject.set((Byte) object);
- break;
- case Commands.CHARACTER_CLASS:
- valueObject.set((Character) object);
- break;
- case Commands.DOUBLE_CLASS:
- valueObject.set((Double) object);
- break;
- case Commands.FLOAT_CLASS:
- valueObject.set((Float) object);
- break;
- case Commands.INTEGER_CLASS:
- valueObject.set((Integer) object);
- break;
- case Commands.LONG_CLASS:
- valueObject.set((Long) object);
- break;
- case Commands.SHORT_CLASS:
- valueObject.set((Short) object);
- break;
- case Commands.BOOLEAN_CLASS:
- valueObject.set((Boolean) object);
- break;
- case Commands.STRING_CLASS:
- valueObject.set((String) object);
- break;
- case Commands.BIG_DECIMAL_CLASS:
- valueObject.set(object, Commands.BIG_DECIMAL_CLASS);
- break;
- case Commands.BIG_INTEGER_CLASS:
- valueObject.set(object, Commands.BIG_INTEGER_CLASS);
- break;
- default:
- if (primitiveTypeID != SEND_AS_IS) {
- addObject = server.getIdentityID(object, valueObject);
- if (addObject) {
- added |= OBJECT_ADDED;
- valueObject.setObjectID(valueObject.objectID, classID);
- } else
- valueObject.setObjectID(valueObject.objectID);
- } else
- valueObject.set(object, classID);
- break;
- }
- }
- }
-
- return added;
-}
-
-public void sendObject(Object object, int primitiveTypeID, Commands.ValueObject valueObject, DataOutputStream out, boolean writeAsCommand) throws CommandException {
- sendObject(object, primitiveTypeID, valueObject, out, writeAsCommand, writeAsCommand);
-}
-public void sendObject(Object object, int primitiveTypeID, Commands.ValueObject valueObject, DataOutputStream out, boolean writeAsCommand, boolean flush) throws CommandException {
- int added = fillInValue(object, primitiveTypeID, valueObject);
- boolean sent = false;
- try {
- Commands.writeValue(out, valueObject, writeAsCommand, flush); // Write it back as a value command.
- sent = true;
- } finally {
- if (!sent) {
- // Ending due to some problem, so clean up any added objects from the id table.
- if ((added & OBJECT_ADDED) != 0)
- server.removeObject(valueObject.objectID);
- if ((added & CLASS_ADDED) != 0)
- server.removeObject(valueObject.classID);
- }
- }
-}
-
-
- public void sendException(Throwable e, Commands.ValueObject value, DataOutputStream out) throws CommandException {
- // Exception ocurred, return a value command with the exception within it.
- setExceptionIntoValue(e, value);
- Commands.sendErrorCommand(out, Commands.THROWABLE_SENT, value);
- }
-
- public void setExceptionIntoValue(Throwable e, Commands.ValueObject value) {
- server.getIdentityID(e, value); // It should always create it so we don't need to know.
- int eID = value.objectID;
- Class eClass = e.getClass();
- server.getIdentityID(eClass, value);
- int eClassID = value.objectID;
- value.setException(eID, eClassID);
- }
-
- /**
- * From the valueObject, get an Object that is invokable (i.e. can be the target of an invoke, or one of its parms).
- * If it is an array type, the a ValueSender is returned. The invoker needs to then cast this
- * to a ValueSender and call the readArray routine.
- */
- public Object getInvokableObject(final Commands.ValueObject value) {
- switch (value.type) {
- case Commands.NEW_OBJECT_ID:
- case Commands.OBJECT_ID:
- // These need to have access to the server to get the real object
- return server.getObject(value.objectID);
- default:
- // These have all the info needed within the value object itself, so ask it.
- return value.getAsObject();
- }
- }
-
- // Helper class for getting an array.
- private class InvokableValueSender implements Commands.ValueSender {
- int index = 0;
- Object array;
-
- public InvokableValueSender() {
- }
-
- public InvokableValueSender(Commands.ValueObject arrayHeader) {
- initialize(arrayHeader);
- }
-
- public void initialize(Commands.ValueObject arrayHeader) {
- index = 0;
- Class arrayType = (Class) server.getObject(arrayHeader.classID);
- array = java.lang.reflect.Array.newInstance(arrayType, arrayHeader.anInt);
- }
-
- public void clear() {
- array = null;
- index = 0;
- }
-
- public Object getArray() {
- return array;
- }
-
- // A new value is being sent to the array
- public void sendValue(Commands.ValueObject value) {
- java.lang.reflect.Array.set(array, index++, getInvokableObject(value)); // add it to the array
- }
-
- // The next entry is an array too!
- public Commands.ValueSender nestedArray(Commands.ValueObject arrayHeader) {
- InvokableValueSender sender = new InvokableValueSender(arrayHeader);
- // Take the newly created array and put it into the current array.
- java.lang.reflect.Array.set(array, index++, sender.getArray());
- return sender;
- }
- }
-
-}
-
-

Back to the top