diff options
Diffstat (limited to 'plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMExpression.java')
-rw-r--r-- | plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMExpression.java | 1864 |
1 files changed, 0 insertions, 1864 deletions
diff --git a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMExpression.java b/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMExpression.java deleted file mode 100644 index ee7f450a0..000000000 --- a/plugins/org.eclipse.jem.proxy/proxyRemote/org/eclipse/jem/internal/proxy/remote/REMExpression.java +++ /dev/null @@ -1,1864 +0,0 @@ -/******************************************************************************* - * 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 - *******************************************************************************/ -/* - - - */ -package org.eclipse.jem.internal.proxy.remote; - -import java.io.*; -import java.util.*; -import java.util.logging.Level; - -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.ValueObject; -import org.eclipse.jem.internal.proxy.core.*; -import org.eclipse.jem.internal.proxy.initParser.tree.*; - -/** - * The Remote proxy version of Expression. - * - * @since 1.0.0 - */ -public class REMExpression extends Expression { - - private IREMExpressionConnection connection; - private boolean closed; // Are we closed. - - protected Commands.ValueObject workerValue; // A worker object so that we don't need to keep creating one and throwing it away. - - protected Map beanTypeCache; // Use to cache pending BeanTypes. Used in conjunction with REMStandardBeanTypeFactory. - protected Map methodsCache; // Use to cache pending expression method proxies. Used in conjunction with REMProxyConsants. - protected Map fieldsCache; // Use to cache pending expression field proxies. Used in conjunction with REMProxyConsants. - - /* - * This is very special list. It tries to eliminate unneeded traffic. For example a mark immediately followed by an endmark does - * not need to be sent. Many expressions can look like: mark, endmark, endtransaction. This is a do nothing and we don't want - * to create a connection to just send this. So this list is used to queue up these and remove them too when found as not needed. - * - * However, this is very tricky because all pushToProxy transactions that actually do something MUST call the processPending() method - * first to make sure any pending transactions are submitted. Because once a real type transaction, such as assignment occurs, any - * pending transaction is a valid transaction, and no longer a do-nothing transaction. - * - * Each transaction type uses a subclass of PendingTransaction to be an entry on the list. - * - * The pendings currently supported are: - * mark/endmark - * try/catch/endtry - * block/endblock - * - * See each individual transaction type to see how it is handled. - */ - protected List pendingTransactions; - - /** - * PendingTransaction entry. - * - * @since 1.1.0 - */ - protected abstract static class PendingTransaction { - - /** - * The transaction is now being pushed. The implementation should - * actually do the push. - * - * @param remExpression The REMExpression for this transaction. - * - * @since 1.1.0 - */ - public abstract void pushTransaction(REMExpression remExpression); - } - - /** - * @param registry - * - * @since 1.0.0 - */ - public REMExpression(REMProxyFactoryRegistry registry) { - super(registry); - } - - /** - * Return the expression id for this REMExpression. This id is used on the remote vm to - * identify who the request is for. - * @return - * - * @since 1.1.0 - */ - protected int getREMExpressionID() { - return this.hashCode(); - } - /** - * Get the pending transactions list. - * @return - * - * @since 1.1.0 - */ - protected List getPendingTransactions() { - if (pendingTransactions == null) - pendingTransactions = new ArrayList(); - return pendingTransactions; - } - - // Use this flag when debugging to test if errors are due to improper pending processing. - // If true they will be treated as if not pending and will be executed immediately. - private static final boolean EXECUTE_PENDING_IMMEDIATELY = false; - protected void addPendingTransaction(PendingTransaction pending) { - if (!EXECUTE_PENDING_IMMEDIATELY) - getPendingTransactions().add(pending); - else - pending.pushTransaction(this); - } - - private boolean sentData; // Flag to indicate if we have sent anything yet to the remote vm. This is used for the pending optimizations. - - /** - * Have we sent any data in this transaction yet. - * @return - * - * @since 1.1.0 - */ - protected boolean haveSentData() { - return sentData; - } - - /** - * @return Returns the connection. - * - * @since 1.1.0 - */ - protected IREMExpressionConnection getConnection() { - if (connection == null) { - if (!sentData) - getREMBeanProxyFactory().startTransaction(); // This is the first time we send data, so start transaction. - - sentData = true; // If we are getting a transaction, that means we are sending data. - connection = (IREMExpressionConnection) getREMRegistry().getFreeConnection(); - // This will actually not be stopped until closeproxy. There could be a slight problem if the expression is never closed. - // But that shouldn't happen. This is to prevent any proxy that was released during the execution but was used by - // the expression from being released on the remote vm until after the expression is finished. - try { - if (workerValue == null) - workerValue = new Commands.ValueObject(); - if (expressionProcesserController == null) { - byte trace = !isTraceSet() ? ExpressionCommands.TRACE_DEFAULT : (isTrace() ? ExpressionCommands.TRACE_ON : ExpressionCommands.TRACE_OFF); - connection.startExpressionProcessing(getREMExpressionID(), trace); // It is a new expression. - } else { - fillProxy(expressionProcesserController, workerValue); - connection.resumeExpression(getREMExpressionID(), workerValue); - expressionProcesserController = null; - } - } catch (IOException e) { - connection.close(); - ProxyPlugin.getPlugin().getLogger().log(e); - throwIllegalStateException(IO_EXCEPTION_MSG); - } catch (CommandException e) { - ProxyPlugin.getPlugin().getLogger().log(e); - if (!e.isRecoverable()) { - connection.close(); - connection = null; - } - throwIllegalStateException(COMMAND_EXCEPTION_MSG); - } - } - return connection; - } - - /** - * General IOException occurred msg. - */ - protected static final String IO_EXCEPTION_MSG = ProxyRemoteMessages.REMExpression_IOExceptionSeeLog_INFO_; - - protected static final String COMMAND_EXCEPTION_MSG = ProxyRemoteMessages.REMExpression_CommandExceptionSeeLog_INFO_; - - /** - * Throw an an illegal state exception if some general error, in particular an I/O or Command Exception - * occurred so that callers know there is something wrong. - * - * @param msg - * @throws IllegalStateException - * - * @since 1.0.0 - */ - protected void throwIllegalStateException(String msg) throws IllegalStateException { - throw new IllegalStateException(msg); - } - - /** - * Return the registry as a REMProxyFactoryRegistry - * @return - * - * @since 1.0.0 - */ - protected final REMProxyFactoryRegistry getREMRegistry() { - return (REMProxyFactoryRegistry) registry; - } - - /** - * Return the bean proxy factory as a REMStandardBeanProxyFactory. - * @return - * - * @since 1.0.0 - */ - protected final REMStandardBeanProxyFactory getREMBeanProxyFactory() { - return (REMStandardBeanProxyFactory) beanProxyFactory; - } - - /** - * Process any pending transactions. - * <p> - * <b>Note: </b>It is required that all non-pending-participating transactions must - * call this method first to make sure pending transactions are sent. If this is - * not done, there will be errors in the expression. - * - * - * @since 1.1.0 - */ - protected void processPendingTransactions() { - if (pendingTransactions != null && !pendingTransactions.isEmpty()) { - try { - for (int i = 0; i < pendingTransactions.size(); i++) { - ((PendingTransaction) pendingTransactions.get(i)).pushTransaction(this); - } - } finally { - pendingTransactions.clear(); - } - } - } - - /** - * Get the pending entry from top. If top is 1, then get top entry (i.e. last one added), 2 is next one. - * @param fromTop - * @return entry requested, or <code>null</code> if no such entry. - * - * @since 1.1.0 - */ - protected PendingTransaction getPendingEntryFromTop(int fromTop) { - if (pendingTransactions != null && pendingTransactions.size() >= fromTop) { - return (PendingTransaction) pendingTransactions.get(pendingTransactions.size()-fromTop); - } else - return null; - } - - /** - * Pop up the top entry from the pending transactions queue. - * @param fromTop how many entries to pop from the pending transaction list. - * - * - * @since 1.1.0 - */ - protected void popPendingEntry(int fromTop) { - if (pendingTransactions != null) - if (pendingTransactions.size() > fromTop) { - while(fromTop-- >0) - pendingTransactions.remove(pendingTransactions.size()-1); - } else - pendingTransactions.clear(); - } - - /* (non-Javadoc) - * @see org.eclipse.jem.internal.proxy.core.Expression#pushToProxy(org.eclipse.jem.internal.proxy.core.IProxy) - */ - protected void pushToProxy(IProxy proxy) { - if (proxy == null || proxy.isBeanProxy()) - pushToProxy((IBeanProxy) proxy); - else - pushToExpressionProxy((ExpressionProxy) proxy); - } - - private void pushToProxy(IBeanProxy proxy) { - processPendingTransactions(); - IREMExpressionConnection connection = getConnection(); - try { - // Format of push proxy command is: - // PushExpressionCommand(push to proxy) followed by: - // ValueObject containing the rendered proxy. - connection.pushExpressionCommand(getREMExpressionID(), (byte)InternalExpressionTypes.PUSH_TO_PROXY_EXPRESSION_VALUE); - if (proxy == null) - workerValue.set(); - else - ((IREMBeanProxy) proxy).renderBean(workerValue); - connection.pushValueObject(workerValue); - } catch (IOException e) { - connection.close(); - ProxyPlugin.getPlugin().getLogger().log(e); - markInvalid(e.getLocalizedMessage()); - throwIllegalStateException(IO_EXCEPTION_MSG); - } catch (CommandException e) { - ProxyPlugin.getPlugin().getLogger().log(e); - markInvalid(e.getLocalizedMessage()); - if (!e.isRecoverable()) { - connection.close(); - throwIllegalStateException(COMMAND_EXCEPTION_MSG); - } - } - } - - /* (non-Javadoc) - * @see org.eclipse.jem.internal.proxy.core.Expression#closeProxy() - */ - protected void closeProxy() { - if (!closed) { - try { - if (connection != null && connection.isConnected()) { - try { - connection.stopExpressionProcessing(getREMExpressionID()); - } catch (IOException e) { - connection.close(); - ProxyPlugin.getPlugin().getLogger().log(e, Level.INFO); - // Not throwing an illegal state here because we don't care, other than logging and not - // returning the connection to the registry that there was an error on close. - } finally { - getREMRegistry().returnConnection(connection); - } - } - } finally { - closed = true; - if (sentData) - getREMBeanProxyFactory().stopTransaction(); // Resume proxy releases. We've sent data at least once. - } - } - methodsCache = null; - fieldsCache = null; - beanTypeCache = null; - pendingTransactions = null; - connection = null; - } - - private static final Object VOIDTYPE = new Object(); // A void type was sent in expression proxy resolution. - private static final Object NOTRESOLVED = new Object(); // A not resolved type was sent in expression proxy resolution. - - /* - * Get the sender to use for pulling the expression proxy resolutions. - */ - private BeanProxyValueSender getExpressionProxiesSender() { - return new BeanProxyValueSender(getREMBeanProxyFactory()) { - - /* - * (non-Javadoc) - * - * @see org.eclipse.jem.internal.proxy.remote.BeanProxyValueSender#sendValue(org.eclipse.jem.internal.proxy.common.remote.Commands.ValueObject) - */ - public void sendValue(ValueObject value) { - if (value.getType() == Commands.FLAG) { - switch (value.anInt) { - case ExpressionCommands.EXPRESSIONPROXY_NOTRESOLVED: - array[index++] = NOTRESOLVED; - break; - case ExpressionCommands.EXPRESSIONPROXY_VOIDTYPE: - array[index++] = VOIDTYPE; - break; - default: - // Shouldn't happen. - break; - } - } else - super.sendValue(value); - } - }; - } - - /* - * Process the pulled expression proxy resolutions. - */ - private void processpulledExpressionProxies(List expressionProxies, BeanProxyValueSender sender) { - - // It is expected that each entry will coorespond to the next non-null expression proxy and will be the bean proxy or one of the special - // types. - int len = expressionProxies.size(); - int j = 0; - Object[] resolveds = sender.getArray(); - for (int i = 0; i < len; i++) { - ExpressionProxy ep = (ExpressionProxy) expressionProxies.get(i); - if (ep != null) { - Object resolved = resolveds[j++]; - if (resolved == NOTRESOLVED) - fireProxyNotResolved(ep); - else if (resolved == VOIDTYPE) - fireProxyVoid(ep); - else - fireProxyResolved(ep, (IBeanProxy) resolved); - } - } - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.jem.internal.proxy.core.Expression#pullProxyValue(int, java.util.List) - */ - protected IBeanProxy pullProxyValue(int proxycount, List expressionProxies) throws ThrowableProxy, NoExpressionValueException { - if (!haveSentData()) { - markAllProxiesNotResolved(expressionProxies); - return null; // We haven't pushed any commands, so there is nothing to do. Don't create a connection for this. - } - // If there are any pending transactions at this point in time, there is no need to send them. They would be do nothings anyway. - - boolean processedExpressionProxies = false; - IREMExpressionConnection lclConnection = getConnection(); - markInTransaction(lclConnection); - try { - Commands.ValueObject proxyids = null; - BeanProxyValueSender sender = null; - if (proxycount > 0) { - proxyids = createExpressionProxiesValueObject(proxycount, expressionProxies); - sender = getExpressionProxiesSender(); - } - - lclConnection.pullValue(getREMExpressionID(), proxyids, sender); - // If we got this far, then if there are proxies, we need to process these too. - if (proxycount > 0) - processpulledExpressionProxies(expressionProxies, sender); - processedExpressionProxies =true; - lclConnection.getFinalValue(workerValue); // Get the returned value. - return getREMBeanProxyFactory().getBeanProxy(workerValue); - } catch (CommandErrorException e) { - try { - if (e.getErrorCode() == ExpressionCommands.EXPRESSION_NOEXPRESSIONVALUE_EXCEPTION) { - // Need to turn it into a Throwable. - ThrowableProxy t = null; - try { - getREMBeanProxyFactory().getBeanProxy(e.getValue()); // This will cause a throw to occur, but we don't want it going out, we want to capture it. - } catch (ThrowableProxy e1) { - t = e1; - } - throw new REMNoExpressionValueException(t); - } - getREMBeanProxyFactory().processErrorReturn(e); - } catch (CommandException e1) { - ProxyPlugin.getPlugin().getLogger().log(e); - if (!e.isRecoverable()) { - lclConnection.close(); - throwIllegalStateException(COMMAND_EXCEPTION_MSG); - } - } - } catch (CommandException e) { - ProxyPlugin.getPlugin().getLogger().log(e); - if (!e.isRecoverable()) { - lclConnection.close(); - throwIllegalStateException(COMMAND_EXCEPTION_MSG); - } - } finally { - markEndTransaction(lclConnection); - if (!processedExpressionProxies) - markAllProxiesNotResolved(expressionProxies); // We failed before we could process the expression proxies. So mark all as not resolved. - } - return null; - } - - /** - * This is called by commands that write some data and will be reading data back immediately - * (i.e. pull value and invoke expression). If we are on a callback thread and have the - * used the connection from the callback thread, we need to tell the callback thread that - * it is in a transaction. This is needed because while reading data back there are - * sometimes calls back to the vm to get beantype data for new classes. This would - * normally be through a new connection so that it doesn't get stuck in the middle of the - * data being sent back. But when running on a callback the same connection is used. So it - * would stick data in the middle of the return stream of data. To prevent this we need - * to tell the callback thread that it is in a transaction during this call so that any - * such new connection requests will get a new connection. - * <p> - * This is not nestable (i.e. the first markEndTransaction will set it false, even if several nested - * markInTransactions are called). - * <p> - * markEndTransaction must be called in ALL cases, such use try/finally. - * @param remConnection the connection to see check against and mark in transaction for. - * - * - * @since 1.1.0 - */ - protected void markInTransaction(IREMExpressionConnection remConnection) { - Thread thread = Thread.currentThread(); - if (thread instanceof REMCallbackThread) { - // We are in a callback, and the callback connection is our connection, tell the callback that it is in transaction. - REMCallbackThread callbackThread = (REMCallbackThread) thread; - if (callbackThread.getConnection() == remConnection) { - callbackThread.setIntransaction(true); - } - } - } - - /** - * Mark end of transaction. - * @param remConn REMConnection to test and mark not in connection for. - * - * @see REMExpression#markInTransaction(IREMExpressionConnection) - * @since 1.1.0 - */ - protected void markEndTransaction(IREMExpressionConnection remConn) { - Thread thread = Thread.currentThread(); - if (thread instanceof REMCallbackThread) { - // We are in a callback, and the callback connection is our connection, tell the callback that it is in transaction. - REMCallbackThread callbackThread = (REMCallbackThread) thread; - if (callbackThread.getConnection() == remConn) { - callbackThread.setIntransaction(false); - } - } - } - - /** - * @param expressionProxies - * - * @since 1.1.0 - */ - private Commands.ValueObject createExpressionProxiesValueObject(int actualCount, List expressionProxies) { - class ExpressionProxyRetriever implements Commands.ValueRetrieve { - Iterator expressionProxiesItr; - Commands.ValueObject worker = new Commands.ValueObject(); - - public ExpressionProxyRetriever(List expressionProxies) { - this.expressionProxiesItr = expressionProxies.iterator(); - } - - public Commands.ValueObject nextValue() { - worker.set(-1); - while (expressionProxiesItr.hasNext()) { - Object parm = expressionProxiesItr.next(); - if (parm != null) { - worker.set(((ExpressionProxy) parm).getProxyID()); - break; - } - } - return worker; - } - }; - - workerValue.setArrayIDS(new ExpressionProxyRetriever(expressionProxies), actualCount, Commands.INT); - return workerValue; - } - - /* - * (non-Javadoc) - * @see org.eclipse.jem.internal.proxy.core.Expression#pushCastToProxy(org.eclipse.jem.internal.proxy.core.IProxyBeanType) - */ - protected void pushCastToProxy(IProxyBeanType type) { - processPendingTransactions(); - IREMExpressionConnection connection = getConnection(); - try { - // Format of push cast to proxy command is: - // PushExpressionCommand(push cast to proxy) followed by: - connection.pushExpressionCommand(getREMExpressionID(), (byte)InternalExpressionTypes.CAST_EXPRESSION_VALUE); - fillProxy(type, workerValue); - connection.pushValueObject(workerValue); - } catch (IOException e) { - connection.close(); - ProxyPlugin.getPlugin().getLogger().log(e); - markInvalid(e.getLocalizedMessage()); - throwIllegalStateException(IO_EXCEPTION_MSG); - } catch (CommandException e) { - ProxyPlugin.getPlugin().getLogger().log(e); - markInvalid(e.getLocalizedMessage()); - if (!e.isRecoverable()) { - connection.close(); - throwIllegalStateException(COMMAND_EXCEPTION_MSG); - } - } - } - - /** - * Push the proxy bean type in the format depending on expression proxy or beantype proxy. - * @param type - * @throws IOException - * - * @since 1.1.0 - */ - protected void fillProxy(IProxy type, Commands.ValueObject value) throws IOException { - // ValueObject containing the rendered bean type proxy if IBeanTypeProxy or int (for expression proxy id) if expression proxy. - if (type.isBeanProxy()) { - ((IREMBeanProxy) type).renderBean(value); - } else { - ExpressionProxy ep = (ExpressionProxy) type; - value.set(ep.getProxyID()); - } - } - - /* - * (non-Javadoc) - * @see org.eclipse.jem.internal.proxy.core.Expression#pushInstanceofToProxy(org.eclipse.jem.internal.proxy.core.IProxyBeanType) - */ - protected void pushInstanceofToProxy(IProxyBeanType type) { - processPendingTransactions(); - IREMExpressionConnection connection = getConnection(); - try { - // Format of push instanceof to proxy command is: - // PushExpressionCommand(push instanceof to proxy) followed by: - // ValueObject containing the rendered bean type proxy or the String representing the name of class. - connection.pushExpressionCommand(getREMExpressionID(), (byte)InternalExpressionTypes.INSTANCEOF_EXPRESSION_VALUE); - fillProxy(type, workerValue); - connection.pushValueObject(workerValue); - } catch (IOException e) { - connection.close(); - ProxyPlugin.getPlugin().getLogger().log(e); - markInvalid(e.getLocalizedMessage()); - throwIllegalStateException(IO_EXCEPTION_MSG); - } catch (CommandException e) { - ProxyPlugin.getPlugin().getLogger().log(e); - markInvalid(e.getLocalizedMessage()); - if (!e.isRecoverable()) { - connection.close(); - throwIllegalStateException(COMMAND_EXCEPTION_MSG); - } - } - } - - /* - * (non-Javadoc) - * @see org.eclipse.jem.internal.proxy.core.Expression#pushInfixToProxy(org.eclipse.jem.internal.proxy.initParser.tree.InfixOperator, int) - */ - protected void pushInfixToProxy(InfixOperator operator, InternalInfixOperandType operandType) { - processPendingTransactions(); - IREMExpressionConnection connection = getConnection(); - try { - // Format of push infix to proxy command is: - // PushExpressionCommand(push infix to proxy) followed by: - // byte: operator - // byte: operandType - connection.pushExpressionCommand(getREMExpressionID(), (byte)InternalExpressionTypes.INFIX_EXPRESSION_VALUE); - connection.pushByte((byte) operator.getValue()); - connection.pushByte((byte) operandType.getValue()); - } catch (IOException e) { - connection.close(); - ProxyPlugin.getPlugin().getLogger().log(e); - markInvalid(e.getLocalizedMessage()); - throwIllegalStateException(IO_EXCEPTION_MSG); - } - } - - /* - * (non-Javadoc) - * @see org.eclipse.jem.internal.proxy.core.Expression#pushPrefixToProxy(org.eclipse.jem.internal.proxy.initParser.tree.PrefixOperator) - */ - protected void pushPrefixToProxy(PrefixOperator operator) { - processPendingTransactions(); - IREMExpressionConnection connection = getConnection(); - try { - // Format of push prefix to proxy command is: - // PushExpressionCommand(push prefix to proxy) followed by: - // byte: operator - connection.pushExpressionCommand(getREMExpressionID(), (byte)InternalExpressionTypes.PREFIX_EXPRESSION_VALUE); - connection.pushByte((byte) operator.getValue()); - } catch (IOException e) { - connection.close(); - ProxyPlugin.getPlugin().getLogger().log(e); - markInvalid(e.getLocalizedMessage()); - throwIllegalStateException(IO_EXCEPTION_MSG); - } - } - - /* (non-Javadoc) - * @see org.eclipse.jem.internal.proxy.core.Expression#pushArrayAccessToProxy(int) - */ - protected void pushArrayAccessToProxy(int indexCount) { - processPendingTransactions(); - IREMExpressionConnection connection = getConnection(); - try { - // Format of push array access to proxy command is: - // PushExpressionCommand(push array acces to proxy) followed by: - // int: indexCount - connection.pushExpressionCommand(getREMExpressionID(), (byte)InternalExpressionTypes.ARRAY_ACCESS_EXPRESSION_VALUE); - connection.pushInt(indexCount); - } catch (IOException e) { - connection.close(); - ProxyPlugin.getPlugin().getLogger().log(e); - markInvalid(e.getLocalizedMessage()); - throwIllegalStateException(IO_EXCEPTION_MSG); - } - } - - /* - * (non-Javadoc) - * @see org.eclipse.jem.internal.proxy.core.Expression#pushArrayCreationToProxy(org.eclipse.jem.internal.proxy.core.IProxyBeanType, int) - */ - protected void pushArrayCreationToProxy(IProxyBeanType type, int dimensionCount) { - processPendingTransactions(); - IREMExpressionConnection connection = getConnection(); - try { - // Format of push array creation to proxy command is: - // PushExpressionCommand(push array creation to proxy) followed by: - // ValueObject containing the rendered bean type proxy or the expression proxy. - // int: dimension count - connection.pushExpressionCommand(getREMExpressionID(), (byte)InternalExpressionTypes.ARRAY_CREATION_EXPRESSION_VALUE); - fillProxy(type, workerValue); - connection.pushValueObject(workerValue); - connection.pushInt(dimensionCount); - } catch (IOException e) { - connection.close(); - ProxyPlugin.getPlugin().getLogger().log(e); - markInvalid(e.getLocalizedMessage()); - throwIllegalStateException(IO_EXCEPTION_MSG); - } catch (CommandException e) { - ProxyPlugin.getPlugin().getLogger().log(e); - markInvalid(e.getLocalizedMessage()); - if (!e.isRecoverable()) { - connection.close(); - throwIllegalStateException(COMMAND_EXCEPTION_MSG); - } - } - } - - protected void pushArrayInitializerToProxy(IProxyBeanType type, int stripCount, int expressionCount) { - processPendingTransactions(); - IREMExpressionConnection connection = getConnection(); - try { - // Format of push array initializer to proxy command is: - // PushExpressionCommand(push array initializer to proxy) followed by: - // ValueObject containing the rendered bean type proxy or expression proxy. - // int: strip count - // int: expression count - connection.pushExpressionCommand(getREMExpressionID(), (byte)InternalExpressionTypes.ARRAY_INITIALIZER_EXPRESSION_VALUE); - fillProxy(type, workerValue); - connection.pushValueObject(workerValue); - connection.pushInt(stripCount); - connection.pushInt(expressionCount); - } catch (IOException e) { - connection.close(); - ProxyPlugin.getPlugin().getLogger().log(e); - markInvalid(e.getLocalizedMessage()); - throwIllegalStateException(IO_EXCEPTION_MSG); - } catch (CommandException e) { - ProxyPlugin.getPlugin().getLogger().log(e); - markInvalid(e.getLocalizedMessage()); - if (!e.isRecoverable()) { - connection.close(); - throwIllegalStateException(COMMAND_EXCEPTION_MSG); - } - } - } - - /* - * (non-Javadoc) - * @see org.eclipse.jem.internal.proxy.core.Expression#pushClassInstanceCreationToProxy(org.eclipse.jem.internal.proxy.core.IProxyBeanType, int) - */ - protected void pushClassInstanceCreationToProxy(IProxyBeanType type, int argumentCount) { - processPendingTransactions(); - IREMExpressionConnection connection = getConnection(); - try { - // Format of push class instance creation to proxy command is: - // PushExpressionCommand(push class instance creation to proxy) followed by: - // ValueObject containing the rendered bean type proxy or the expression proxy - // int: argument count - connection.pushExpressionCommand(getREMExpressionID(), (byte)InternalExpressionTypes.CLASS_INSTANCE_CREATION_EXPRESSION_VALUE); - fillProxy(type, workerValue); - connection.pushValueObject(workerValue); - connection.pushInt(argumentCount); - } catch (IOException e) { - connection.close(); - ProxyPlugin.getPlugin().getLogger().log(e); - markInvalid(e.getLocalizedMessage()); - throwIllegalStateException(IO_EXCEPTION_MSG); - } catch (CommandException e) { - ProxyPlugin.getPlugin().getLogger().log(e); - markInvalid(e.getLocalizedMessage()); - if (!e.isRecoverable()) { - connection.close(); - throwIllegalStateException(COMMAND_EXCEPTION_MSG); - } - } - } - - /* - * (non-Javadoc) - * @see org.eclipse.jem.internal.proxy.core.Expression#pushTypeReceiverToProxy(org.eclipse.jem.internal.proxy.core.IProxyBeanType) - */ - protected void pushTypeReceiverToProxy(IProxyBeanType type) { - processPendingTransactions(); - IREMExpressionConnection connection = getConnection(); - try { - // Format of push type receiver to proxy command is: - // PushExpressionCommand(push type receiver to proxy) followed by: - // ValueObject containing the rendered bean type proxy or the expression proxy. - connection.pushExpressionCommand(getREMExpressionID(), (byte)InternalExpressionTypes.TYPERECEIVER_EXPRESSION_VALUE); - fillProxy(type, workerValue); - connection.pushValueObject(workerValue); - } catch (IOException e) { - connection.close(); - ProxyPlugin.getPlugin().getLogger().log(e); - markInvalid(e.getLocalizedMessage()); - throwIllegalStateException(IO_EXCEPTION_MSG); - } catch (CommandException e) { - ProxyPlugin.getPlugin().getLogger().log(e); - markInvalid(e.getLocalizedMessage()); - if (!e.isRecoverable()) { - connection.close(); - throwIllegalStateException(COMMAND_EXCEPTION_MSG); - } - } - } - - /* (non-Javadoc) - * @see org.eclipse.jem.internal.proxy.core.Expression#pushFieldAccessToProxy(java.lang.String, boolean) - */ - protected void pushFieldAccessToProxy(Object field, boolean hasReceiver) { - processPendingTransactions(); - IREMExpressionConnection connection = getConnection(); - try { - // Format of push field access to proxy command is: - // PushExpressionCommand(push field access to proxy) followed by: - // Commands.Value: fieldName or IProxyField - // boolean: hasReceiver - connection.pushExpressionCommand(getREMExpressionID(), (byte)InternalExpressionTypes.FIELD_ACCESS_EXPRESSION_VALUE); - if (field instanceof String) { - workerValue.set((String) field); - } else { - fillProxy((IProxy) field, workerValue); - } - connection.pushValueObject(workerValue); - connection.pushBoolean(hasReceiver); - } catch (IOException e) { - connection.close(); - ProxyPlugin.getPlugin().getLogger().log(e); - markInvalid(e.getLocalizedMessage()); - throwIllegalStateException(IO_EXCEPTION_MSG); - } catch (CommandException e) { - ProxyPlugin.getPlugin().getLogger().log(e); - markInvalid(e.getLocalizedMessage()); - if (!e.isRecoverable()) { - connection.close(); - throwIllegalStateException(COMMAND_EXCEPTION_MSG); - } - } - } - - /* (non-Javadoc) - * @see org.eclipse.jem.internal.proxy.core.Expression#pushMethodInvocationToProxy(java.lang.String, boolean, int) - */ - protected void pushMethodInvocationToProxy(Object method, boolean hasReceiver, int argCount) { - processPendingTransactions(); - IREMExpressionConnection connection = getConnection(); - try { - // Format of push method invocation to proxy command is: - // PushExpressionCommand(push method invocation to proxy) followed by: - // Commands.ValueObject: methodName or IMethodProxy - // boolean: hasReceiver - // int: argCount - connection.pushExpressionCommand(getREMExpressionID(), (byte)InternalExpressionTypes.METHOD_EXPRESSION_VALUE); - if (method instanceof String) { - workerValue.set((String) method); - } else { - fillProxy((IProxy) method, workerValue); - } - connection.pushValueObject(workerValue); - connection.pushBoolean(hasReceiver); - connection.pushInt(argCount); - } catch (IOException e) { - connection.close(); - ProxyPlugin.getPlugin().getLogger().log(e); - markInvalid(e.getLocalizedMessage()); - throwIllegalStateException(IO_EXCEPTION_MSG); - } catch (CommandException e) { - ProxyPlugin.getPlugin().getLogger().log(e); - markInvalid(e.getLocalizedMessage()); - if (!e.isRecoverable()) { - connection.close(); - throwIllegalStateException(COMMAND_EXCEPTION_MSG); - } - } - } - - /* (non-Javadoc) - * @see org.eclipse.jem.internal.proxy.core.Expression#pushConditionalToProxy(int) - */ - protected void pushConditionalToProxy(InternalConditionalOperandType expressionType) { - processPendingTransactions(); - IREMExpressionConnection connection = getConnection(); - try { - // Format of push conditional to proxy command is: - // PushExpressionCommand(push conditional to proxy) followed by: - // byte: expression type - connection.pushExpressionCommand(getREMExpressionID(), (byte)InternalExpressionTypes.CONDITIONAL_EXPRESSION_VALUE); - connection.pushByte((byte) expressionType.getValue()); - } catch (IOException e) { - connection.close(); - ProxyPlugin.getPlugin().getLogger().log(e); - markInvalid(e.getLocalizedMessage()); - throwIllegalStateException(IO_EXCEPTION_MSG); - } - } - - /* - * A special one that takes the ThrowableProxy for no expression value and - * wrappers it prints its stack trace instead, but still makes it a subclass - * of NoExpressionValueException. - * - * @since 1.1.0 - */ - private static class REMNoExpressionValueException extends NoExpressionValueException { - /** - * Comment for <code>serialVersionUID</code> - * - * @since 1.1.0 - */ - private static final long serialVersionUID = 1692406777391812694L; - - - public REMNoExpressionValueException(ThrowableProxy e) { - super(e); - } - - - /* (non-Javadoc) - * @see java.lang.Throwable#getLocalizedMessage() - */ - public String getLocalizedMessage() { - return ((ThrowableProxy) getCause()).getProxyLocalizedMessage(); - } - - - /* (non-Javadoc) - * @see java.lang.Throwable#getMessage() - */ - public String getMessage() { - return ((ThrowableProxy) getCause()).getProxyMessage(); - } - - - /* (non-Javadoc) - * @see java.lang.Throwable#printStackTrace() - */ - public void printStackTrace() { - getCause().printStackTrace(); - } - - - /* (non-Javadoc) - * @see java.lang.Throwable#printStackTrace(java.io.PrintStream) - */ - public void printStackTrace(PrintStream s) { - getCause().printStackTrace(s); - } - - - /* (non-Javadoc) - * @see java.lang.Throwable#printStackTrace(java.io.PrintWriter) - */ - public void printStackTrace(PrintWriter s) { - getCause().printStackTrace(s); - } - } - - /* - * (non-Javadoc) - * @see org.eclipse.jem.internal.proxy.core.Expression#pushInvoke(int, java.util.List) - */ - protected void pushInvoke(int proxycount, List expressionProxies) throws ThrowableProxy, NoExpressionValueException { - if (!haveSentData()) { - markAllProxiesNotResolved(expressionProxies); - return; // We haven't pushed any commands, so there is nothing to do. Don't create a connection for this. - } - // If at this point there are pending transactions, there is no need to send them because they would all be do-nothings. - - boolean processedExpressionProxies = false; - IREMExpressionConnection lclConnection = getConnection(); - markInTransaction(lclConnection); - try { - Commands.ValueObject proxyids = null; - BeanProxyValueSender sender = null; - if (proxycount > 0) { - proxyids = createExpressionProxiesValueObject(proxycount, expressionProxies); - sender = getExpressionProxiesSender(); - } - - lclConnection.sync(getREMExpressionID(), proxyids, sender); - - // If we got this far, then if there are proxies, we need to process these too. - if (proxycount > 0) - processpulledExpressionProxies(expressionProxies, sender); - processedExpressionProxies = true; - lclConnection.getFinalValue(workerValue); // We don't care what it is, we just need to see if there is an error. - } catch (CommandErrorException e) { - try { - if (e.getErrorCode() == ExpressionCommands.EXPRESSION_NOEXPRESSIONVALUE_EXCEPTION) { - // Need to turn it into a Throwable. - ThrowableProxy t = null; - try { - getREMBeanProxyFactory().getBeanProxy(e.getValue()); // This will cause a throw to occur, but we don't want it going out, we want to capture it. - } catch (ThrowableProxy e1) { - t = e1; - } - throw new REMNoExpressionValueException(t); - } - getREMBeanProxyFactory().processErrorReturn(e); - } catch (CommandException e1) { - ProxyPlugin.getPlugin().getLogger().log(e); - if (!e.isRecoverable()) { - lclConnection.close(); - throwIllegalStateException(COMMAND_EXCEPTION_MSG); - } - } - } catch (CommandException e) { - ProxyPlugin.getPlugin().getLogger().log(e); - if (!e.isRecoverable()) { - lclConnection.close(); - throwIllegalStateException(COMMAND_EXCEPTION_MSG); - } - } finally { - markEndTransaction(lclConnection); - if (!processedExpressionProxies) - markAllProxiesNotResolved(expressionProxies); // We failed before we could process the expression proxies. So mark all as not resolved. - } - } - - private static class REMBeanTypeExpressionProxy extends ExpressionProxy implements IBeanTypeExpressionProxy { - - private String typeName; - - /** - * @param proxyid - * - * @since 1.1.0 - */ - private REMBeanTypeExpressionProxy(int proxyid, Expression expression) { - super(proxyid, BEANTYPE_EXPRESSION_PROXY, expression); - } - - public void setTypeName(String typeName) { - this.typeName = typeName; - } - - public String getTypeName() { - return typeName; - } - - - /* (non-Javadoc) - * @see org.eclipse.jem.internal.proxy.core.ExpressionProxy#toString() - */ - public String toString() { - return super.toString()+" - "+getTypeName(); //$NON-NLS-1$ - } - - - /* (non-Javadoc) - * @see org.eclipse.jem.internal.proxy.core.IProxyBeanType#getMethodProxy(org.eclipse.jem.internal.proxy.core.IExpression, java.lang.String, org.eclipse.jem.internal.proxy.core.IProxyBeanType[]) - */ - public IProxyMethod getMethodProxy(IExpression expression, String methodName, IProxyBeanType[] parameterTypes) { - REMProxyFactoryRegistry registry = (REMProxyFactoryRegistry) expression.getRegistry(); - return ((REMMethodProxyFactory) registry.getMethodProxyFactory()).getMethodProxy(expression, this, methodName, parameterTypes); - } - - - /* (non-Javadoc) - * @see org.eclipse.jem.internal.proxy.core.IProxyBeanType#getMethodProxy(org.eclipse.jem.internal.proxy.core.IExpression, java.lang.String, java.lang.String[]) - */ - public IProxyMethod getMethodProxy(IExpression expression, String methodName, String[] parameterTypes) { - REMProxyFactoryRegistry registry = (REMProxyFactoryRegistry) expression.getRegistry(); - return ((REMMethodProxyFactory) registry.getMethodProxyFactory()).getMethodProxy(expression, this, methodName, parameterTypes); - } - - public IProxyMethod getMethodProxy(IExpression expression, String methodName) { - return getMethodProxy(expression, methodName, (IProxyBeanType[]) null); - } - - /* (non-Javadoc) - * @see org.eclipse.jem.internal.proxy.core.IProxyBeanType#getFieldProxy(org.eclipse.jem.internal.proxy.core.IExpression, java.lang.String) - */ - public IProxyField getFieldProxy(IExpression expression, String fieldName) { - REMProxyFactoryRegistry registry = (REMProxyFactoryRegistry) expression.getRegistry(); - return ((REMMethodProxyFactory) registry.getMethodProxyFactory()).getFieldProxy(expression, this, fieldName); - } - } - - private static class REMMethodExpressionProxy extends ExpressionProxy implements IProxyMethod { - - /** - * @param proxyid - * @param proxyType - * @param expression - * - * @since 1.1.0 - */ - private REMMethodExpressionProxy(int proxyid, Expression expression) { - super(proxyid, METHOD_EXPRESSION_PROXY, expression); - } - } - - private static class REMFieldExpressionProxy extends ExpressionProxy implements IProxyField { - - /** - * @param proxyid - * @param proxyType - * @param expression - * - * @since 1.1.0 - */ - private REMFieldExpressionProxy(int proxyid, Expression expression) { - super(proxyid, FIELD_EXPRESSION_PROXY, expression); - } - } - - /* (non-Javadoc) - * @see org.eclipse.jem.internal.proxy.core.Expression#createExpressionProxy(int) - */ - protected ExpressionProxy createExpressionProxy(int proxyType, int proxyID) { - switch (proxyType) { - case NORMAL_EXPRESSION_PROXY: - default: - return new ExpressionProxy(proxyID, NORMAL_EXPRESSION_PROXY, this); - - case BEANTYPE_EXPRESSION_PROXY: - return new REMBeanTypeExpressionProxy(proxyID, this); - - case METHOD_EXPRESSION_PROXY: - return new REMMethodExpressionProxy(proxyID, this); - - case FIELD_EXPRESSION_PROXY: - return new REMFieldExpressionProxy(proxyID, this); - } - } - - /* (non-Javadoc) - * @see org.eclipse.jem.internal.proxy.core.Expression#pushAssignmentToProxy(org.eclipse.jem.internal.proxy.core.ExpressionProxy) - */ - protected void pushAssignmentToProxy(ExpressionProxy proxy) { - processPendingTransactions(); - IREMExpressionConnection connection = getConnection(); - try { - // Format of push assignment to proxy command is: - // PushExpressionCommand(push assignment to proxy) followed by: - // int: proxy id - connection.pushExpressionCommand(getREMExpressionID(), (byte)InternalExpressionTypes.ASSIGNMENT_PROXY_EXPRESSION_VALUE); - connection.pushInt(proxy.getProxyID()); - } catch (IOException e) { - connection.close(); - ProxyPlugin.getPlugin().getLogger().log(e); - markInvalid(e.getLocalizedMessage()); - throwIllegalStateException(IO_EXCEPTION_MSG); - } - } - - - /* (non-Javadoc) - * @see org.eclipse.jem.internal.proxy.core.Expression#pushAssignmentToProxy() - */ - protected void pushAssignmentToProxy() { - processPendingTransactions(); - IREMExpressionConnection connection = getConnection(); - try { - // Format of the push assignment command is: - // PushAssignmentCommand. - connection.pushExpressionCommand(getREMExpressionID(), (byte) InternalExpressionTypes.ASSIGNMENT_EXPRESSION_VALUE); - } catch (IOException e) { - connection.close(); - ProxyPlugin.getPlugin().getLogger().log(e); - markInvalid(e.getLocalizedMessage()); - throwIllegalStateException(IO_EXCEPTION_MSG); - } - } - - - private void pushToExpressionProxy(ExpressionProxy proxy) { - processPendingTransactions(); - IREMExpressionConnection connection = getConnection(); - try { - // Format of push to expression proxy command is: - // PushExpressionCommand(push expression proxy to proxy) followed by: - // int: proxy id - connection.pushExpressionCommand(getREMExpressionID(), (byte)InternalExpressionTypes.PUSH_TO_EXPRESSION_PROXY_EXPRESSION_VALUE); - connection.pushInt(proxy.getProxyID()); - } catch (IOException e) { - connection.close(); - ProxyPlugin.getPlugin().getLogger().log(e); - markInvalid(e.getLocalizedMessage()); - throwIllegalStateException(IO_EXCEPTION_MSG); - } - - } - - private static class BlockBegin extends PendingTransaction { - public int blockNumber; - - public BlockBegin(int blockNumber) { - this.blockNumber = blockNumber; - } - - public void pushTransaction(REMExpression remExpression) { - IREMExpressionConnection connection = remExpression.getConnection(); - try { - // Format of push to block begin proxy command is: - // PushExpressionCommand(push block begin proxy to proxy) followed by: - // int: block id - connection.pushExpressionCommand(remExpression.getREMExpressionID(), (byte)InternalExpressionTypes.BLOCK_BEGIN_EXPRESSION_VALUE); - connection.pushInt(blockNumber); - } catch (IOException e) { - connection.close(); - ProxyPlugin.getPlugin().getLogger().log(e); - remExpression.markInvalid(e.getLocalizedMessage()); - remExpression.throwIllegalStateException(IO_EXCEPTION_MSG); - } - } - - } - - /* (non-Javadoc) - * @see org.eclipse.jem.internal.proxy.core.Expression#pushBlockBeginToProxy(int) - */ - protected void pushBlockBeginToProxy(int blockNumber) { - addPendingTransaction(new BlockBegin(blockNumber)); - } - - /* (non-Javadoc) - * @see org.eclipse.jem.internal.proxy.core.Expression#pushBlockEndToProxy(int) - */ - protected void pushBlockEndToProxy(int blockNumber) { - // See if the top pending transactions is BreakBlock(blockNumber). If it is then the BreakBlock can be thrown away. - PendingTransaction topEntry = getPendingEntryFromTop(1); - if (topEntry instanceof BlockBreak && ((BlockBreak) topEntry).blockNumber == blockNumber) { - popPendingEntry(1); - topEntry = getPendingEntryFromTop(1); - } - // See if the top pending transaction is now BeginBlock(blockNumber). If it is, then this transaction and the block begin - // can be thrown away because they are an empty block. - if (topEntry instanceof BlockBegin && ((BlockBegin) topEntry).blockNumber == blockNumber) { - popPendingEntry(1); - return; - } - processPendingTransactions(); - IREMExpressionConnection connection = getConnection(); - try { - // Format of push to block end proxy command is: - // PushExpressionCommand(push block end proxy to proxy) followed by: - // int: block id - connection.pushExpressionCommand(getREMExpressionID(), (byte)InternalExpressionTypes.BLOCK_END_EXPRESSION_VALUE); - connection.pushInt(blockNumber); - } catch (IOException e) { - connection.close(); - ProxyPlugin.getPlugin().getLogger().log(e); - markInvalid(e.getLocalizedMessage()); - throwIllegalStateException(IO_EXCEPTION_MSG); - } - } - - private static class BlockBreak extends PendingTransaction { - public int blockNumber; - - public BlockBreak(int blockNumber) { - this.blockNumber = blockNumber; - } - - public void pushTransaction(REMExpression remExpression) { - IREMExpressionConnection connection = remExpression.getConnection(); - try { - // Format of push to block break proxy command is: - // PushExpressionCommand(push block break proxy to proxy) followed by: - // int: block id - connection.pushExpressionCommand(remExpression.getREMExpressionID(), (byte)InternalExpressionTypes.BLOCK_BREAK_EXPRESSION_VALUE); - connection.pushInt(blockNumber); - } catch (IOException e) { - connection.close(); - ProxyPlugin.getPlugin().getLogger().log(e); - remExpression.markInvalid(e.getLocalizedMessage()); - remExpression.throwIllegalStateException(IO_EXCEPTION_MSG); - } - } - } - - /* (non-Javadoc) - * @see org.eclipse.jem.internal.proxy.core.Expression#pushBlockBreakToProxy(int) - */ - protected void pushBlockBreakToProxy(int blockNumber) { - // Even if there is no pending block begin for this block, we will pend the break. - // This is so that if the break occurred just before the block end, then it can be ignored. - addPendingTransaction(new BlockBreak(blockNumber)); - } - - private static class TryBegin extends PendingTransaction { - - public final int tryNumber; - - public TryBegin(int tryNumber) { - this.tryNumber = tryNumber; - - } - public void pushTransaction(REMExpression remExpression) { - IREMExpressionConnection connection = remExpression.getConnection(); - try { - // Format of push to try begin proxy command is: - // PushExpressionCommand(push try begin to proxy) followed by: - // int: try id - connection.pushExpressionCommand(remExpression.getREMExpressionID(), (byte)InternalExpressionTypes.TRY_BEGIN_EXPRESSION_VALUE); - connection.pushInt(tryNumber); - } catch (IOException e) { - connection.close(); - ProxyPlugin.getPlugin().getLogger().log(e); - remExpression.markInvalid(e.getLocalizedMessage()); - remExpression.throwIllegalStateException(IO_EXCEPTION_MSG); - } - } - - } - /* (non-Javadoc) - * @see org.eclipse.jem.internal.proxy.core.Expression#pushTryBeginToProxy(int) - */ - protected void pushTryBeginToProxy(int tryNumber) { - addPendingTransaction(new TryBegin(tryNumber)); - } - - private static class TryCatch extends PendingTransaction { - - public final int tryNumber; - private final IProxyBeanType exceptionType; - private final ExpressionProxy ep; - - public TryCatch(int tryNumber, IProxyBeanType exceptionType, ExpressionProxy ep) { - this.tryNumber = tryNumber; - this.exceptionType = exceptionType; - this.ep = ep; - } - - public void pushTransaction(REMExpression remExpression) { - IREMExpressionConnection connection = remExpression.getConnection(); - try { - // Format of push to try begin proxy command is: - // PushExpressionCommand(push try begin to proxy) followed by: - // int: try id - // object: expression type (as beantype or as expression proxy) - // int: proxy id or (-1 if null). - connection.pushExpressionCommand(remExpression.getREMExpressionID(), (byte)InternalExpressionTypes.TRY_CATCH_EXPRESSION_VALUE); - connection.pushInt(tryNumber); - remExpression.fillProxy(exceptionType, remExpression.workerValue); - connection.pushValueObject(remExpression.workerValue); - if (ep != null) - connection.pushInt(ep.getProxyID()); - else - connection.pushInt(-1); - } catch (IOException e) { - connection.close(); - ProxyPlugin.getPlugin().getLogger().log(e); - remExpression.markInvalid(e.getLocalizedMessage()); - remExpression.throwIllegalStateException(IO_EXCEPTION_MSG); - } catch (CommandException e) { - ProxyPlugin.getPlugin().getLogger().log(e); - remExpression.markInvalid(e.getLocalizedMessage()); - if (!e.isRecoverable()) { - connection.close(); - remExpression.throwIllegalStateException(COMMAND_EXCEPTION_MSG); - } - } - } - - } - /* - * (non-Javadoc) - * @see org.eclipse.jem.internal.proxy.core.Expression#pushTryCatchClauseToProxy(int, org.eclipse.jem.internal.proxy.core.IProxyBeanType, org.eclipse.jem.internal.proxy.core.ExpressionProxy) - */ - protected void pushTryCatchClauseToProxy(int tryNumber, IProxyBeanType exceptionType, ExpressionProxy ep) { - addPendingTransaction(new TryCatch(tryNumber, exceptionType, ep)); - } - - private static class TryFinally extends PendingTransaction { - - public final int tryNumber; - - public TryFinally(int tryNumber) { - this.tryNumber = tryNumber; - - } - - public void pushTransaction(REMExpression remExpression) { - IREMExpressionConnection connection = remExpression.getConnection(); - try { - // Format of push to try begin proxy command is: - // PushExpressionCommand(push try finally to proxy) followed by: - // int: try id - connection.pushExpressionCommand(remExpression.getREMExpressionID(), (byte)InternalExpressionTypes.TRY_FINALLY_EXPRESSION_VALUE); - connection.pushInt(tryNumber); - } catch (IOException e) { - connection.close(); - ProxyPlugin.getPlugin().getLogger().log(e); - remExpression.markInvalid(e.getLocalizedMessage()); - remExpression.throwIllegalStateException(IO_EXCEPTION_MSG); - } - } - - } - /* (non-Javadoc) - * @see org.eclipse.jem.internal.proxy.core.Expression#pushTryFinallyClauseToProxy(int) - */ - protected void pushTryFinallyClauseToProxy(int tryNumber) { - addPendingTransaction(new TryFinally(tryNumber)); - } - - /* (non-Javadoc) - * @see org.eclipse.jem.internal.proxy.core.Expression#pushTryEndToProxy(int) - */ - protected void pushTryEndToProxy(int tryNumber) { - // This is a little tricky. We need to find if there is nothing but try/catch/finally for this tryNumber on the pending - // transactions up to the try begin, if there is nothing else, then we can throw the entire try away. That - // means there was no code at all in any of the try/catch/finally blocks. - int fromTop = 0; - while (true) { - PendingTransaction topEntry = getPendingEntryFromTop(++fromTop); - if (topEntry instanceof TryFinally) { - if (((TryFinally) topEntry).tryNumber != tryNumber) - break; // We met a finally that wasn't ours, so entire try group must be sent. - } else if (topEntry instanceof TryCatch) { - if (((TryCatch) topEntry).tryNumber != tryNumber) - break; // We met a catch that wasn't ours, so entire try group must be sent. - } else if (topEntry instanceof TryBegin) { - if (((TryBegin) topEntry).tryNumber == tryNumber) { - // We've met our try begin, and nothing but empty catch/finally in between, so the entire group can be thrown away - popPendingEntry(fromTop); - return; - } else - break; // We've hit a try begin that wasn't ours, so the entire try group must be sent. - } else - break; // We've hit something other than our try group, so process everything. - } - processPendingTransactions(); - IREMExpressionConnection connection = getConnection(); - try { - // Format of push to try begin proxy command is: - // PushExpressionCommand(push try end to proxy) followed by: - // int: try id - connection.pushExpressionCommand(getREMExpressionID(), (byte)InternalExpressionTypes.TRY_END_EXPRESSION_VALUE); - connection.pushInt(tryNumber); - } catch (IOException e) { - connection.close(); - ProxyPlugin.getPlugin().getLogger().log(e); - markInvalid(e.getLocalizedMessage()); - throwIllegalStateException(IO_EXCEPTION_MSG); - } - } - - /* (non-Javadoc) - * @see org.eclipse.jem.internal.proxy.core.Expression#pushThrowToProxy() - */ - protected void pushThrowToProxy() { - processPendingTransactions(); - IREMExpressionConnection connection = getConnection(); - try { - // Format of push to try begin proxy command is: - // PushExpressionCommand(push throw to proxy) - connection.pushExpressionCommand(getREMExpressionID(), (byte)InternalExpressionTypes.THROW_EXPRESSION_VALUE); - } catch (IOException e) { - connection.close(); - ProxyPlugin.getPlugin().getLogger().log(e); - markInvalid(e.getLocalizedMessage()); - throwIllegalStateException(IO_EXCEPTION_MSG); - } - } - - /* (non-Javadoc) - * @see org.eclipse.jem.internal.proxy.core.Expression#pushRethrowToProxy(int) - */ - protected void pushRethrowToProxy(int tryNumber) { - processPendingTransactions(); - IREMExpressionConnection connection = getConnection(); - try { - // Format of push to rethow proxy command is: - // PushExpressionCommand(push rethrow to proxy) - // int: try id - connection.pushExpressionCommand(getREMExpressionID(), (byte)InternalExpressionTypes.RETHROW_EXPRESSION_VALUE); - connection.pushInt(tryNumber); - } catch (IOException e) { - connection.close(); - ProxyPlugin.getPlugin().getLogger().log(e); - markInvalid(e.getLocalizedMessage()); - throwIllegalStateException(IO_EXCEPTION_MSG); - } - } - - /* (non-Javadoc) - * @see org.eclipse.jem.internal.proxy.core.Expression#pushBeanTypeToProxy(org.eclipse.jem.internal.proxy.core.IBeanTypeExpressionProxy) - */ - protected void pushBeanTypeToProxy(IBeanTypeExpressionProxy proxy) { - // Push beantype to proxy is sent out of sequence without respect to where in expression we are, - // so no need to handle pending transactions at this point. They would not affect the result - // of this call. - IREMExpressionConnection connection = getConnection(); - try { - // Format of push to beanType proxy command is: - // PushExpressionCommand(push bean type expression proxy) - // int: proxy id - // string: typename - connection.pushExpressionCommand(getREMExpressionID(), (byte)InternalExpressionTypes.PUSH_BEANTYPE_EXPRESSIONPROXY_EXPRESSION_VALUE); - REMBeanTypeExpressionProxy ep = (REMBeanTypeExpressionProxy) proxy; - connection.pushInt(ep.getProxyID()); - connection.pushString(ep.getTypeName()); - } catch (IOException e) { - connection.close(); - ProxyPlugin.getPlugin().getLogger().log(e); - markInvalid(e.getLocalizedMessage()); - throwIllegalStateException(IO_EXCEPTION_MSG); - } - } - - /* (non-Javadoc) - * @see org.eclipse.jem.internal.proxy.core.Expression#pushMethodToProxy(org.eclipse.jem.internal.proxy.core.ExpressionProxy, org.eclipse.jem.internal.proxy.core.IProxyBeanType, java.lang.String, org.eclipse.jem.internal.proxy.core.IProxyBeanType[]) - */ - protected void pushMethodToProxy(ExpressionProxy proxy, IProxyBeanType declaringType, String methodName, IProxyBeanType[] parameterTypes) { - // Push method to proxy is sent out of sequence without respect to where in expression we are, - // so no need to handle pending transactions at this point. They would not affect the result - // of this call. - - IREMExpressionConnection connection = getConnection(); - try { - // Format of push to method proxy command is: - // PushExpressionCommand(push method type expression proxy) - // int: proxy id - // ValueObject: containing the rendered bean type proxy or the expression proxy for the declaring type - // string: method name - // int: number of parameter types - // ValueObject(s): containing the rendered bean type proxy or the expression proxy for the parameter types. - connection.pushExpressionCommand(getREMExpressionID(), (byte)InternalExpressionTypes.PUSH_METHOD_EXPRESSIONPROXY_EXPRESSION_VALUE); - connection.pushInt(proxy.getProxyID()); - fillProxy(declaringType, workerValue); - connection.pushValueObject(workerValue); - connection.pushString(methodName); - if (parameterTypes == null || parameterTypes.length == 0) - connection.pushInt(0); - else { - connection.pushInt(parameterTypes.length); - for (int i = 0; i < parameterTypes.length; i++) { - fillProxy(parameterTypes[i], workerValue); - connection.pushValueObject(workerValue); - } - } - } catch (IOException e) { - connection.close(); - ProxyPlugin.getPlugin().getLogger().log(e); - markInvalid(e.getLocalizedMessage()); - throwIllegalStateException(IO_EXCEPTION_MSG); - } catch (CommandException e) { - ProxyPlugin.getPlugin().getLogger().log(e); - markInvalid(e.getLocalizedMessage()); - if (!e.isRecoverable()) { - connection.close(); - throwIllegalStateException(COMMAND_EXCEPTION_MSG); - } - } - } - - /* (non-Javadoc) - * @see org.eclipse.jem.internal.proxy.core.Expression#pushFieldToProxy(org.eclipse.jem.internal.proxy.core.ExpressionProxy, org.eclipse.jem.internal.proxy.core.IProxyBeanType, java.lang.String) - */ - protected void pushFieldToProxy(ExpressionProxy proxy, IProxyBeanType declaringType, String fieldName) { - // Push field to proxy is sent out of sequence without respect to where in expression we are, - // so no need to handle pending transactions at this point. They would not affect the result - // of this call. - - IREMExpressionConnection connection = getConnection(); - try { - // Format of push to field proxy command is: - // PushExpressionCommand(push field type expression proxy) - // int: proxy id - // ValueObject: containing the rendered bean type proxy or the expression proxy for the declaring type - // string: field name - connection.pushExpressionCommand(getREMExpressionID(), (byte)InternalExpressionTypes.PUSH_FIELD_EXPRESSIONPROXY_EXPRESSION_VALUE); - connection.pushInt(proxy.getProxyID()); - fillProxy(declaringType, workerValue); - connection.pushValueObject(workerValue); - connection.pushString(fieldName); - } catch (IOException e) { - connection.close(); - ProxyPlugin.getPlugin().getLogger().log(e); - markInvalid(e.getLocalizedMessage()); - throwIllegalStateException(IO_EXCEPTION_MSG); - } catch (CommandException e) { - ProxyPlugin.getPlugin().getLogger().log(e); - markInvalid(e.getLocalizedMessage()); - if (!e.isRecoverable()) { - connection.close(); - throwIllegalStateException(COMMAND_EXCEPTION_MSG); - } - } - } - - /** - * Get the map of IProxyMethods for a beantype. Meant to be used only in conjunction with REMProxyConstants. - * It is here so the REMProxyConstants can store pending proxies per expression. - * - * @param beanType - * @return - * - * @since 1.1.0 - */ - public Map getMethods(IProxyBeanType beanType) { - if (methodsCache == null) - methodsCache = new HashMap(); - Map methods = (Map) methodsCache.get(beanType.getTypeName()); - if(methods == null){ - methods = new HashMap(20); - methodsCache.put(beanType.getTypeName(),methods); - } - return methods; - } - - /** - * Get the map of IProxyFields for a beantype. Meant to be used only in conjunction with REMProxyConstants. - * It is here so the REMProxyConstants can store pending proxies per expression. - * - * @param beanType - * @return - * - * @since 1.1.0 - */ - public Map getFields(IProxyBeanType beanType) { - if (fieldsCache == null) - fieldsCache = new HashMap(); - Map fields = (Map) fieldsCache.get(beanType.getTypeName()); - if(fields == null){ - fields = new HashMap(20); - fieldsCache.put(beanType.getTypeName(),fields); - } - return fields; - } - - /** - * Get the map of IProxyBeanTypes for a beantype name. Meant to be used only in conjunction with REMSgtandardBeanTypeFactory. - * It is here so the REMStandardBeanTypeFactory can store pending proxies per expression. - * - * @param beanType - * @return - * - * @since 1.1.0 - */ - public IProxyBeanType getBeanType(String beanTypeName) { - if (beanTypeCache == null) - beanTypeCache = new HashMap(); - return (IProxyBeanType) beanTypeCache.get(beanTypeName); - } - - /** - * Add the beantype expression proxy to the map of bean type expression proxies. Used in conjunction with REMStandardBeanTypeFactory. - * It is here so the REMStandardBeanTypeFactory can store pending proxies per expression. - * @param beanTypeName - * @param beantype - * - * @since 1.1.0 - */ - public void addBeanType(String beanTypeName, IProxyBeanType beantype) { - beanTypeCache.put(beanTypeName, beantype); - } - - /** - * Remove the beantype expression proxy from the map. This is called because there was a rollback due to an endmark. - * @param beanTypeName - * - * @since 1.1.0 - */ - public void removeBeanType(String beanTypeName) { - beanTypeCache.remove(beanTypeName); - } - - /* (non-Javadoc) - * @see org.eclipse.jem.internal.proxy.core.Expression#pushIfTestToProxy() - */ - protected void pushIfTestToProxy() { - processPendingTransactions(); - IREMExpressionConnection connection = getConnection(); - try { - // Format of push if test to proxy command is: - // PushExpressionCommand(push if test to proxy) - connection.pushExpressionCommand(getREMExpressionID(), (byte)InternalExpressionTypes.IF_TEST_EXPRESSION_VALUE); - } catch (IOException e) { - connection.close(); - ProxyPlugin.getPlugin().getLogger().log(e); - markInvalid(e.getLocalizedMessage()); - throwIllegalStateException(IO_EXCEPTION_MSG); - } - } - - /* (non-Javadoc) - * @see org.eclipse.jem.internal.proxy.core.Expression#pushIfElseToProxy(org.eclipse.jem.internal.proxy.initParser.tree.InternalIfElseOperandType) - */ - protected void pushIfElseToProxy(InternalIfElseOperandType clauseType) { - processPendingTransactions(); - IREMExpressionConnection connection = getConnection(); - try { - // Format of push conditional to proxy command is: - // PushExpressionCommand(push if/else clause to proxy) followed by: - // byte: clause type - connection.pushExpressionCommand(getREMExpressionID(), (byte)InternalExpressionTypes.IF_ELSE_EXPRESSION_VALUE); - connection.pushByte((byte) clauseType.getValue()); - } catch (IOException e) { - connection.close(); - ProxyPlugin.getPlugin().getLogger().log(e); - markInvalid(e.getLocalizedMessage()); - throwIllegalStateException(IO_EXCEPTION_MSG); - } - } - - /* (non-Javadoc) - * @see org.eclipse.jem.internal.proxy.core.Expression#pushNewInstanceToProxy(java.lang.String, org.eclipse.jem.internal.proxy.core.IProxyBeanType) - */ - protected void pushNewInstanceToProxy(String initializationString, IProxyBeanType resultType) { - processPendingTransactions(); - IREMExpressionConnection connection = getConnection(); - try { - // Format of push new instance from initstring to proxy command is: - // PushExpressionCommand(push new instance to proxy) followed by: - // string: init string - // ValueObject: containing the rendered bean type proxy or the expression proxy for the declaring type - connection.pushExpressionCommand(getREMExpressionID(), (byte)InternalExpressionTypes.NEW_INSTANCE_VALUE); - connection.pushString(initializationString); - fillProxy(resultType, workerValue); - connection.pushValueObject(workerValue); - } catch (IOException e) { - connection.close(); - ProxyPlugin.getPlugin().getLogger().log(e); - markInvalid(e.getLocalizedMessage()); - throwIllegalStateException(IO_EXCEPTION_MSG); - } catch (CommandException e) { - ProxyPlugin.getPlugin().getLogger().log(e); - markInvalid(e.getLocalizedMessage()); - if (!e.isRecoverable()) { - connection.close(); - throwIllegalStateException(COMMAND_EXCEPTION_MSG); - } - } - } - - private static class Mark extends PendingTransaction { - public int markID; - - public Mark(int markID) { - this.markID = markID; - } - - public void pushTransaction(REMExpression remExpression) { - IREMExpressionConnection connection = remExpression.getConnection(); - try { - // Format of push mark to proxy command is: - // PushExpressionCommand(push mark to proxy) followed by: - // int: markID - connection.pushExpressionCommand(remExpression.getREMExpressionID(), (byte)InternalExpressionTypes.MARK_VALUE); - connection.pushInt(markID); - } catch (IOException e) { - connection.close(); - ProxyPlugin.getPlugin().getLogger().log(e); - remExpression.markInvalid(e.getLocalizedMessage()); - remExpression.throwIllegalStateException(IO_EXCEPTION_MSG); - } - } - - } - - protected void pushMarkToProxy(int markID) { - addPendingTransaction(new Mark(markID)); - } - - protected void pushEndmarkToProxy(int markID, boolean restore) { - // See if the top pending transaction is now Mark(markID). If it is, then this transaction and the mark begin - // can be thrown away because they are an empty block. - PendingTransaction topEntry = getPendingEntryFromTop(1); - if (topEntry instanceof Mark && ((Mark) topEntry).markID == markID) { - popPendingEntry(1); - return; - } - processPendingTransactions(); - IREMExpressionConnection connection = getConnection(); - try { - // Format of push end mark to proxy command is: - // PushExpressionCommand(push end mark to proxy) followed by: - // int: markID - // boolean: restore - connection.pushExpressionCommand(getREMExpressionID(), (byte)InternalExpressionTypes.ENDMARK_VALUE); - connection.pushInt(markID); - connection.pushBoolean(restore); - } catch (IOException e) { - connection.close(); - ProxyPlugin.getPlugin().getLogger().log(e); - markInvalid(e.getLocalizedMessage()); - throwIllegalStateException(IO_EXCEPTION_MSG); - } - } - - // This is the expression processor controller used to transfer. - // This is the guy that maintains continuity of the transaction as - // it is passed from one connection to another. - protected IBeanProxy expressionProcesserController; - protected void pushBeginTransferThreadToProxy() throws ThrowableProxy { - // If the controller is not null, that means we had already requested a transfer - // but had not used it in this thread so there is no need to do anything. It - // will be handled when switching back to the other thread. - // If the connection is null, no need to do anything since there is no connection - // to transfer. - if (connection != null && expressionProcesserController == null) { - IREMExpressionConnection lclConnection = getConnection(); - markInTransaction(lclConnection); - try { - workerValue.set(); - lclConnection.transferExpression(getREMExpressionID(), workerValue); - expressionProcesserController = getREMBeanProxyFactory().getBeanProxy(workerValue); - getREMRegistry().returnConnection(lclConnection); - this.connection = null; - } catch (CommandException e) { - ProxyPlugin.getPlugin().getLogger().log(e); - if (!e.isRecoverable()) { - lclConnection.close(); - throwIllegalStateException(COMMAND_EXCEPTION_MSG); - } - } finally { - markEndTransaction(lclConnection); - } - } - } - - protected void pushTransferThreadToProxy() { - // Don't need to do anything. The next time we need to push data across, we will get a connection and the getConnection() - // will hook up the expression processor controller for us. This way if nothing happens in this thread then we won't - // waste communication time on it. - } - - private static class SubexpressionBegin extends PendingTransaction { - public int subexpressionNumber; - - public SubexpressionBegin(int subexpressionNumber) { - this.subexpressionNumber = subexpressionNumber; - } - - public void pushTransaction(REMExpression remExpression) { - IREMExpressionConnection connection = remExpression.getConnection(); - try { - // Format of push to subexpression begin proxy command is: - // PushExpressionCommand(push subexpression begin proxy to proxy) followed by: - // int: subexpression id - connection.pushExpressionCommand(remExpression.getREMExpressionID(), (byte)InternalExpressionTypes.SUBEXPRESSION_BEGIN_EXPRESSION_VALUE); - connection.pushInt(subexpressionNumber); - } catch (IOException e) { - connection.close(); - ProxyPlugin.getPlugin().getLogger().log(e); - remExpression.markInvalid(e.getLocalizedMessage()); - remExpression.throwIllegalStateException(IO_EXCEPTION_MSG); - } - } - - } - - protected void pushSubexpressionBeginToProxy(int subexpressionNumber) { - addPendingTransaction(new SubexpressionBegin(subexpressionNumber)); - } - - protected void pushSubexpressionEndToProxy(int subexpressionNumber) { - // See if the top pending transactions is SubexpressionBegin(subexpressionNumber). If it is then the SubexpressionBegin can be thrown away. - PendingTransaction topEntry = getPendingEntryFromTop(1); - if (topEntry instanceof SubexpressionBegin && ((SubexpressionBegin) topEntry).subexpressionNumber == subexpressionNumber) { - popPendingEntry(1); - return; - } - processPendingTransactions(); - IREMExpressionConnection connection = getConnection(); - try { - // Format of push to block end proxy command is: - // PushExpressionCommand(push subexpression end proxy to proxy) followed by: - // int: subexpression id - connection.pushExpressionCommand(getREMExpressionID(), (byte)InternalExpressionTypes.SUBEXPRESSION_END_EXPRESSION_VALUE); - connection.pushInt(subexpressionNumber); - } catch (IOException e) { - connection.close(); - ProxyPlugin.getPlugin().getLogger().log(e); - markInvalid(e.getLocalizedMessage()); - throwIllegalStateException(IO_EXCEPTION_MSG); - } - } -} |