| /******************************************************************************* |
| * Copyright (c) 2004, 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 |
| *******************************************************************************/ |
| /* |
| * $RCSfile: ExpressionCommands.java,v $ |
| * $Revision: 1.8 $ $Date: 2005/08/24 20:39:08 $ |
| */ |
| package org.eclipse.jem.internal.proxy.common.remote; |
| |
| import java.io.*; |
| |
| import org.eclipse.jem.internal.proxy.common.CommandException; |
| |
| |
| /** |
| * |
| * @since 1.0.0 |
| */ |
| public class ExpressionCommands { |
| |
| // These are the sub-commands under EXPRESSION_TREE_COMMANDS that can be send. |
| public static final byte |
| START_EXPRESSION_TREE_PROCESSING = 0, |
| PUSH_EXPRESSION = 1, |
| END_EXPRESSION_TREE_PROCESSING = 2, |
| SYNC_REQUEST = 3, |
| PULL_VALUE_REQUEST = 4, |
| TRANSFER_EXPRESSION_REQUEST = 5, |
| RESUME_EXPRESSION_REQUEST = 6; |
| |
| // These are the expression specific error codes (it can also send back general ones. See SYNC_REQUEST docs lower down). |
| public static final int |
| EXPRESSION_NOEXPRESSIONVALUE_EXCEPTION = Commands.MAX_ERROR_CODE+1; // No expression value occurred. |
| |
| // These are the flag values sent in proxy resolution when doesn't resolve to proxy. |
| public static final int |
| EXPRESSIONPROXY_VOIDTYPE = 0, // Expression proxy resolves to void type. |
| EXPRESSIONPROXY_NOTRESOLVED = 1; // Expression proxy not resolved. |
| |
| // These are the trace values sent in START_EXPRESSION_TREE_PROCESSING |
| public static final byte |
| TRACE_DEFAULT = -1, |
| TRACE_OFF = 0, |
| TRACE_ON = 1; |
| |
| public static final String EXPRESSIONTRACE = "proxyvm.expressionTrace"; // The system property for turning on expression tracing. //$NON-NLS-1$ |
| public static final String EXPRESSIONTRACE_TIMER_THRESHOLD = "proxyvm.expressionTraceTimerThreshold"; // The system property for timer threshold. //$NON-NLS-1$ |
| |
| /* |
| * The format of the commands are: |
| * Note: Most of the commands will not being doing a os.flush() at the end. We are just going to |
| * be streaming the data over the line. At the end we will flush and then catch up. That way |
| * we aren't waiting for the other side as we send the data. |
| * |
| * START_EXPRESSION_TREE_PROCESSING: 0b, trace |
| * Start processing. |
| * byte(trace): -1 : do default |
| * 0 : no trace |
| * 1 : do trace |
| * |
| * PUSH_EXPRESSION: 1b, b |
| * Push an expression. Where "b" is the expression type from IInternalExpressionConstants. |
| * The actual data that follows is expression type dependent and will be |
| * sent in a following call to ExpressionCommands as it builds up the actual command. |
| * See REMExpression and each type of push call method within it to see the actual |
| * sent data. |
| * |
| * END_EXPRESSION_TREE_PROCESSING: 2b |
| * End the processing and clean up. |
| * |
| * SYNC_REQUEST: 3b |
| * This will return the current status. The reason it is called sync is because the |
| * IDE will wait for it to complete and read back the value. It will send back: |
| * 1: VALUE command with boolean true as the value. |
| * 2: ERROR command with code of ExpressionClassNotFound, with value of String with message from exception. |
| * 3: ERROR command with code of EXPRESSION_NOEXPRESSIONVALUE_EXCEPTION, with value of String with message from exception. |
| * 4: THROWABLE command with the actual exception that occurred. |
| * |
| * |
| * PULL_VALUE_REQUEST: 4b |
| * This will do a sync up and return the value from the expression. |
| * IDE will wait for it to compleate and read back the value. It will send back: |
| * 1: VALUE command with the result as the value. |
| * 2: ERROR or EXCEPTION if there were errors, see SYNC_REQUEST with the format they are sent back. |
| * |
| * TRANSFER_EXPRESSION_REQUEST: 5b |
| * This will do a sync up, and return the ExpressionProcessorController that the request is for. And remove |
| * the controller from its list of active expression controllers. |
| * |
| * RESUME_EXPRESSION_REQUEST: 6b, anExpressionProcessorController |
| * This will take the given controller and add it to the list of controllers this connection is handling. It returns nothing. |
| * |
| * @see org.eclipse.jem.internal.proxy.initParser.tree.IInternalExpressionConstants |
| * @see org.eclipse.jem.internal.proxy.remote.REMExpression |
| * |
| */ |
| |
| /** |
| * Send the start expression processing command. |
| * @param expressionID |
| * @param trace |
| * @param os |
| * |
| * @throws IOException |
| * |
| * @since 1.0.0 |
| */ |
| public static void sendStartExpressionProcessingCommand(int expressionID, byte trace, DataOutputStream os) throws IOException { |
| os.writeByte(Commands.EXPRESSION_TREE_COMMAND); |
| os.writeInt(expressionID); |
| os.writeByte(START_EXPRESSION_TREE_PROCESSING); |
| os.writeByte(trace); |
| } |
| |
| /** |
| * Send the end expression processing command. |
| * @param expressionID |
| * @param os |
| * |
| * @throws IOException |
| * |
| * @since 1.0.0 |
| */ |
| public static void sendEndExpressionProcessingCommand(int expressionID, DataOutputStream os) throws IOException { |
| os.writeByte(Commands.EXPRESSION_TREE_COMMAND); |
| os.writeInt(expressionID); |
| os.writeByte(END_EXPRESSION_TREE_PROCESSING); |
| os.flush(); // Flushing because we are done and want to make sure everything goes out. |
| } |
| |
| /** |
| * Send an expression subcommand. |
| * @param expressionID |
| * @param os |
| * @param subcommand |
| * |
| * @throws IOException |
| * |
| * @since 1.0.0 |
| */ |
| public static void sendExpressionCommand(int expressionID, DataOutputStream os, byte subcommand) throws IOException { |
| os.writeByte(Commands.EXPRESSION_TREE_COMMAND); |
| os.writeInt(expressionID); |
| os.writeByte(PUSH_EXPRESSION); |
| os.writeByte(subcommand); |
| } |
| |
| /** |
| * Send just a byte. |
| * |
| * @param os |
| * @param aByte |
| * @throws IOException |
| * |
| * @since 1.0.0 |
| */ |
| public static void sendByte(DataOutputStream os, byte aByte) throws IOException { |
| os.writeByte(aByte); |
| } |
| |
| /** |
| * Send just an int. |
| * |
| * @param os |
| * @param anInt |
| * @throws IOException |
| * |
| * @since 1.0.0 |
| */ |
| public static void sendInt(DataOutputStream os, int anInt) throws IOException { |
| os.writeInt(anInt); |
| } |
| |
| /** |
| * Send just a string. |
| * |
| * @param os |
| * @param aString |
| * @throws IOException |
| * |
| * @since 1.0.0 |
| */ |
| public static void sendString(DataOutputStream os, String aString) throws IOException { |
| Commands.sendStringData(os, aString); |
| } |
| |
| /** |
| * Send just a boolean. |
| * |
| * @param os |
| * @param aBool |
| * @throws IOException |
| * |
| * @since 1.0.0 |
| */ |
| public static void sendBoolean(DataOutputStream os, boolean aBool) throws IOException { |
| os.writeBoolean(aBool); |
| } |
| |
| /** |
| * Send the pull value command. After processing the proxies, caller should call getFinalValue() to get the value. |
| * @param expressionID |
| * @param os |
| * @param is |
| * @param proxyids if not <code>null</code>, then this is the list of expression proxy ids that need to be returned as rendered. |
| * @param sender sender used to process the resolved proxy ids, or <code>null</code> if no proxy ids. |
| * @throws CommandException |
| * |
| * @since 1.0.0 |
| */ |
| public static void sendPullValueCommand(int expressionID, DataOutputStream os, DataInputStream is, Commands.ValueObject proxyids, Commands.ValueSender sender) throws CommandException { |
| try { |
| os.writeByte(Commands.EXPRESSION_TREE_COMMAND); |
| os.writeInt(expressionID); |
| os.writeByte(PULL_VALUE_REQUEST); |
| sendProxyIDs(os, proxyids); |
| os.flush(); |
| if (proxyids != null) { |
| Commands.readBackValue(is, proxyids, Commands.ARRAY_IDS); // Read the array header. |
| sender.initialize(proxyids); |
| Commands.readArray(is, proxyids.anInt, sender, proxyids, true); // Read the array. |
| } |
| } catch (CommandException e) { |
| // rethrow this exception since we want these to go on out. |
| throw e; |
| } catch (IOException e) { |
| // Wrapper this one. |
| throw new UnexpectedExceptionCommandException(false, e); |
| } |
| } |
| |
| /** |
| * Send a sync command. This does a synchronize with the remote expression processor. It makes sure that the |
| * stream is caught and doesn't return until everything on the stream has been processed. Should then call |
| * getFinalValue() to verify the expression is valid. |
| * @param expressionID |
| * @param os |
| * @param is |
| * @param proxyids if not <code>null</code>, then this is the list of expression proxy ids that need to be returned as rendered. |
| * @param sender the sender used for reading back the proxyid resolutions, or <code>null</code> if no proxy ids. |
| * |
| * @throws CommandException |
| * |
| * @since 1.0.0 |
| */ |
| public static void sendSyncCommand(int expressionID, DataOutputStream os, DataInputStream is, Commands.ValueObject proxyids, Commands.ValueSender sender) throws CommandException { |
| try { |
| os.writeByte(Commands.EXPRESSION_TREE_COMMAND); |
| os.writeInt(expressionID); |
| os.writeByte(SYNC_REQUEST); |
| sendProxyIDs(os, proxyids); |
| os.flush(); |
| if (proxyids != null) { |
| Commands.readBackValue(is, proxyids, Commands.ARRAY_IDS); // Read the array header. |
| sender.initialize(proxyids); |
| Commands.readArray(is, proxyids.anInt, sender, proxyids, true); // Read the array. |
| } |
| } catch (CommandException e) { |
| // rethrow this exception since we want these to go on out. |
| throw e; |
| } catch (Exception e) { |
| // Wrapper this one. |
| throw new UnexpectedExceptionCommandException(false, e); |
| } |
| } |
| |
| /** |
| * Send the proxyids (if not null) as part of a command. Used by sync and pullValue. |
| * @param os |
| * @param proxyids <code>null</code> if not requesting proxy ids. |
| * @throws IOException |
| * @throws CommandException |
| * |
| * @since 1.1.0 |
| */ |
| private static void sendProxyIDs(DataOutputStream os, Commands.ValueObject proxyids) throws IOException, CommandException { |
| if (proxyids != null) { |
| os.writeBoolean(true); // Indicates proxy ids being sent. |
| Commands.writeValue(os, proxyids, false, false); |
| } else |
| os.writeBoolean(false); // No proxyids being sent. |
| } |
| |
| /** |
| * Send the transfer expression command and receive back the expression processor controller. |
| * |
| * @param expressionID |
| * @param os |
| * @param is |
| * @param expressionProcesserController |
| * @throws CommandException |
| * |
| * @since 1.1.0 |
| */ |
| public static void sendTransferExpressionCommand(int expressionID, DataOutputStream os, DataInputStream is, Commands.ValueObject expressionProcesserController) throws CommandException { |
| try { |
| os.writeByte(Commands.EXPRESSION_TREE_COMMAND); |
| os.writeInt(expressionID); |
| os.writeByte(TRANSFER_EXPRESSION_REQUEST); |
| os.flush(); |
| Commands.readBackValue(is, expressionProcesserController, Commands.NO_TYPE_CHECK); // Read the expression processor controller |
| } catch (CommandException e) { |
| throw e; |
| } catch (Exception e) { |
| // Wrapper this one. |
| throw new UnexpectedExceptionCommandException(false, e); |
| } |
| } |
| |
| /** |
| * Send the resume expression command with given expression processor controller. |
| * |
| * @param expressionID |
| * @param os |
| * @param expressionProcessorController |
| * @throws CommandException |
| * |
| * @since 1.1.0 |
| */ |
| public static void sendResumeExpressionCommand(int expressionID, DataOutputStream os, Commands.ValueObject expressionProcessorController) throws CommandException { |
| try { |
| os.writeByte(Commands.EXPRESSION_TREE_COMMAND); |
| os.writeInt(expressionID); |
| os.writeByte(RESUME_EXPRESSION_REQUEST); |
| Commands.writeValue(os, expressionProcessorController, false, false); |
| } catch (CommandException e) { |
| throw e; |
| } catch (Exception e) { |
| // Wrapper this one. |
| throw new UnexpectedExceptionCommandException(false, e); |
| } |
| } |
| |
| private ExpressionCommands() { |
| // Never intended to be instantiated. |
| } |
| |
| } |