| /******************************************************************************* |
| * 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: IDEExpression.java,v $ $Revision: 1.12 $ $Date: 2005/08/24 20:39:06 $ |
| */ |
| package org.eclipse.jem.internal.proxy.ide; |
| |
| import java.util.*; |
| |
| import org.eclipse.core.runtime.Platform; |
| |
| import org.eclipse.jem.internal.proxy.common.MethodHelper; |
| import org.eclipse.jem.internal.proxy.core.*; |
| import org.eclipse.jem.internal.proxy.core.ExpressionProxy.ProxyEvent; |
| import org.eclipse.jem.internal.proxy.initParser.tree.*; |
| |
| /** |
| * IDE expression processing. |
| * |
| * @since 1.0.0 |
| */ |
| public class IDEExpression extends Expression { |
| |
| private final IDEStandardBeanTypeProxyFactory beantypefactory; |
| protected final ExpressionProcesser eproc; |
| { |
| boolean useTracing = !isTraceSet() ? |
| "true".equalsIgnoreCase(Platform.getDebugOption(ProxyPlugin.getPlugin().getBundle().getSymbolicName() + ProxyLaunchSupport.EXPRESSION_TRACING)) : //$NON-NLS-1$ |
| isTrace(); |
| long threshold = Long.getLong(Platform.getDebugOption(ProxyPlugin.getPlugin().getBundle().getSymbolicName() + ProxyLaunchSupport.EXPRESSION_TRACEING_TIMER_THRESHOLD), -1L).longValue(); |
| eproc = new ExpressionProcesser(useTracing, threshold); |
| } |
| |
| |
| private void processExpressionError() throws ThrowableProxy, NoExpressionValueException { |
| if (!eproc.noErrors()) |
| if (eproc.isNoExpressionValue()) |
| throw (NoExpressionValueException) eproc.getErrorThrowable(); |
| else { |
| Throwable t = eproc.getErrorThrowable(); |
| if (t instanceof ThrowableProxy) |
| throw (ThrowableProxy) t; |
| else |
| throw new IDEThrowableProxy(eproc.getErrorThrowable(), beantypefactory.getBeanTypeProxy(t.getClass())); |
| } |
| } |
| |
| /** |
| * Create the IDEExpression |
| * |
| * @param registry |
| * |
| * @since 1.0.0 |
| */ |
| public IDEExpression(ProxyFactoryRegistry registry) { |
| super(registry); |
| beantypefactory = (IDEStandardBeanTypeProxyFactory) registry.getBeanTypeProxyFactory(); |
| } |
| |
| protected final IDEProxyFactoryRegistry getIDERegistry() { |
| return (IDEProxyFactoryRegistry) registry; |
| } |
| |
| protected final IDEStandardBeanTypeProxyFactory getIDEBeanTypeFactory() { |
| return beantypefactory; |
| } |
| |
| /* |
| * (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) |
| eproc.pushExpression(null, MethodHelper.NULL_TYPE); |
| else if (proxy.isBeanProxy()) |
| eproc.pushExpression(((IDEBeanProxy) proxy).getBean(), ((IDEBeanTypeProxy) ((IBeanProxy) proxy).getTypeProxy()).getTypeClass()); |
| else |
| eproc.pushExpressionProxy(((ExpressionProxy) proxy).getProxyID()); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.jem.internal.proxy.core.Expression#closeProxy() |
| */ |
| protected void closeProxy() { |
| methodExpressionProxies = fieldExpressionProxies = null; |
| eproc.close(); |
| } |
| |
| /* |
| * (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 { |
| processExtensionProxies(proxycount, expressionProxies); |
| processExpressionError(); |
| Object result[] = new Object[2]; |
| eproc.pullValue(result); |
| IBeanProxy resultProxy = getIDERegistry().getBeanProxy((Class) result[1], result[0]); |
| return resultProxy; |
| } |
| |
| private void processExtensionProxies(int proxycount, List expressionProxies) { |
| if (proxycount > 0) { |
| int len = expressionProxies.size(); |
| Object[] proxyResolution = new Object[2]; |
| for (int i = 0; i < len; i++) { |
| ExpressionProxy ep = (ExpressionProxy) expressionProxies.get(i); |
| if (ep != null) { |
| try { |
| eproc.pullExpressionProxyValue(ep.getProxyID(), proxyResolution); |
| if (proxyResolution[1] != Void.TYPE) |
| fireProxyResolved(ep, getIDERegistry().getBeanProxy((Class) proxyResolution[1], proxyResolution[0])); |
| else |
| fireProxyVoid(ep); |
| } catch (NoExpressionValueException e) { |
| fireProxyNotResolved(ep); |
| } |
| } |
| } |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * @see org.eclipse.jem.internal.proxy.core.Expression#pushCastToProxy(org.eclipse.jem.internal.proxy.core.IProxyBeanType) |
| */ |
| protected void pushCastToProxy(IProxyBeanType type) { |
| try { |
| eproc.pushCast(getIDEBeanTypeProxy(type).getTypeClass()); |
| } catch (ThrowableProxy e) { |
| eproc.processException(e); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * @see org.eclipse.jem.internal.proxy.core.Expression#pushInstanceofToProxy(org.eclipse.jem.internal.proxy.core.IProxyBeanType) |
| */ |
| protected void pushInstanceofToProxy(IProxyBeanType type) { |
| try { |
| eproc.pushInstanceof(getIDEBeanTypeProxy(type).getTypeClass()); |
| } catch (ThrowableProxy e) { |
| eproc.processException(e); |
| } |
| } |
| |
| /** |
| * Get the BeanType proxy and test if valid. Throw ThrowableProxy if not valid. |
| * |
| * @param type |
| * @return |
| * @throws ThrowableProxy |
| * |
| * @since 1.0.0 |
| */ |
| protected IDEBeanTypeProxy getIDEBeanTypeProxy(IProxyBeanType type) throws ThrowableProxy { |
| IDEBeanTypeProxy typeProxy; |
| if (type.isExpressionProxy()) { |
| // It should already be resolved at this point. |
| typeProxy = ((IDEBeanTypeExpressionProxy) type).getBeanTypeProxy(); |
| } else |
| typeProxy = (IDEBeanTypeProxy) type; |
| if (!typeProxy.isValid()) { |
| throw new IDEThrowableProxy( |
| new Exception(typeProxy.getInitializationError()), |
| getIDEBeanTypeFactory().getBeanTypeProxy(Exception.class)); |
| } else |
| return typeProxy; |
| } |
| |
| |
| /** |
| * Get the BeanType proxy and test if valid. Throw ThrowableProxy if not valid. |
| * @param type |
| * @return |
| * @throws ThrowableProxy |
| * |
| * @since 1.1.0 |
| */ |
| protected IDEBeanTypeProxy getIDEBeanTypeProxy(String type) throws ThrowableProxy { |
| return (IDEBeanTypeProxy) registry.getBeanTypeProxyFactory().getBeanTypeProxy(type); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * @see org.eclipse.jem.internal.proxy.core.Expression#pushPrefixToProxy(org.eclipse.jem.internal.proxy.initParser.tree.PrefixOperator) |
| */ |
| protected void pushPrefixToProxy(PrefixOperator operator) { |
| eproc.pushPrefix(operator); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * @see org.eclipse.jem.internal.proxy.core.Expression#pushInfixToProxy(org.eclipse.jem.internal.proxy.initParser.tree.InfixOperator, org.eclipse.jem.internal.proxy.initParser.tree.InternalInfixOperandType) |
| */ |
| protected void pushInfixToProxy(InfixOperator operator, InternalInfixOperandType operandType) { |
| eproc.pushInfix(operator, operandType); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jem.internal.proxy.core.Expression#pushArrayAccessToProxy(int) |
| */ |
| protected void pushArrayAccessToProxy(int indexCount) { |
| eproc.pushArrayAccess(indexCount); |
| } |
| |
| /* |
| * (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) { |
| try { |
| eproc.pushArrayCreation(getIDEBeanTypeProxy(type).getTypeClass(), dimensionCount); |
| } catch (ThrowableProxy e) { |
| eproc.processException(e); |
| } |
| } |
| |
| protected void pushArrayInitializerToProxy(IProxyBeanType type, int stripCount, int expressionCount) { |
| try { |
| eproc.pushArrayInitializer(getIDEBeanTypeProxy(type).getTypeClass(), stripCount, expressionCount); |
| } catch (ThrowableProxy e) { |
| eproc.processException(e); |
| } |
| } |
| |
| /* |
| * (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) { |
| try { |
| eproc.pushClassInstanceCreation(getIDEBeanTypeProxy(type).getTypeClass(), argumentCount); |
| } catch (ThrowableProxy e) { |
| eproc.processException(e); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * @see org.eclipse.jem.internal.proxy.core.Expression#pushTypeReceiverToProxy(org.eclipse.jem.internal.proxy.core.IProxyBeanType) |
| */ |
| protected void pushTypeReceiverToProxy(IProxyBeanType type) { |
| try { |
| Class c = getIDEBeanTypeProxy(type).getTypeClass(); |
| eproc.pushExpression(c, c); // When as a receiver, the type is the same as the receiver. |
| } catch (ThrowableProxy e) { |
| eproc.processException(e); |
| } catch (RuntimeException e) { |
| eproc.processException(e); |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jem.internal.proxy.core.Expression#pushFieldAccessToProxy(java.lang.Object, boolean) |
| */ |
| protected void pushFieldAccessToProxy(Object field, boolean hasReceiver) { |
| boolean isString = field instanceof String; |
| try { |
| eproc.pushFieldAccess(isString ? field : getIDEFieldProxy((IProxyField) field).getBean(), isString, hasReceiver); |
| } catch (ThrowableProxy e) { |
| eproc.processException(e); |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jem.internal.proxy.core.Expression#pushMethodInvocationToProxy(java.lang.Object, boolean, int) |
| */ |
| protected void pushMethodInvocationToProxy(Object method, boolean hasReceiver, int argCount) { |
| boolean isString = method instanceof String; |
| try { |
| eproc.pushMethodInvocation(isString ? method : getIDEMethodProxy((IProxyMethod) method).getBean(), isString, hasReceiver, argCount); |
| } catch (ThrowableProxy e) { |
| eproc.processException(e); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * @see org.eclipse.jem.internal.proxy.core.Expression#pushConditionalToProxy(org.eclipse.jem.internal.proxy.initParser.tree.InternalConditionalOperandType) |
| */ |
| protected void pushConditionalToProxy(InternalConditionalOperandType expressionType) { |
| eproc.pushConditional(expressionType); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jem.internal.proxy.core.Expression#pushInvoke() |
| */ |
| protected void pushInvoke(int proxycount, List expressionProxies) throws ThrowableProxy, NoExpressionValueException { |
| // In the IDE case do nothing. Nothing is pending. But still need to handle proxy resolution. |
| processExtensionProxies(proxycount, expressionProxies); |
| processExpressionError(); |
| } |
| |
| /** |
| * This is used as both an ExpressionProxy (i.e. IDE side) and the Expressions expression proxy result on the other side. |
| * This makes it easier to just use same instance on both sides. |
| * |
| * @since 1.1.0 |
| */ |
| protected static class IDEExpressionProxy extends ExpressionProxy implements InternalExpressionProxy { |
| |
| protected IDEExpressionProxy(int proxyid, int proxyType, Expression expression) { |
| super(proxyid, proxyType, expression); |
| } |
| |
| private Object value; |
| private Class type; |
| private boolean set; |
| |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jem.internal.proxy.core.ExpressionProxy#dispose() |
| */ |
| protected void dispose() { |
| super.dispose(); |
| value = null; |
| type = null; |
| set = false; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jem.internal.proxy.initParser.tree.InternalExpressionProxy#getType() |
| */ |
| public Class getType() { |
| return type; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jem.internal.proxy.initParser.tree.InternalExpressionProxy#getValue() |
| */ |
| public Object getValue() { |
| return value; |
| } |
| /* (non-Javadoc) |
| * @see org.eclipse.jem.internal.proxy.initParser.tree.InternalExpressionProxy#setProxy(java.lang.Object, java.lang.Class) |
| */ |
| public void setProxy(Object value, Class type) { |
| this.value = value; |
| this.type = type; |
| set = true; |
| } |
| /* (non-Javadoc) |
| * @see org.eclipse.jem.internal.proxy.initParser.tree.InternalExpressionProxy#isSet() |
| */ |
| public boolean isSet() { |
| return set; |
| } |
| } |
| |
| /** |
| * The Expression proxy for IDE BeanTypes. |
| * |
| * @since 1.1.0 |
| */ |
| protected static class IDEBeanTypeExpressionProxy extends IDEExpressionProxy implements IBeanTypeExpressionProxy { |
| |
| private String typeName; |
| private IDEBeanTypeProxy resolvedProxy; |
| |
| /** |
| * @param proxyid |
| * |
| * @since 1.1.0 |
| */ |
| public IDEBeanTypeExpressionProxy(int proxyid, Expression expression) { |
| super(proxyid, BEANTYPE_EXPRESSION_PROXY, expression); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * @see org.eclipse.jem.internal.proxy.core.IBeanTypeExpressionProxy#setTypeName(java.lang.String) |
| */ |
| public void setTypeName(String typeName) { |
| this.typeName = typeName; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * @see org.eclipse.jem.internal.proxy.core.IProxyBeanType#getTypeName() |
| */ |
| 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$ |
| } |
| |
| /** |
| * Called by IDEExpression to resolve the beantype. |
| * @param beantypeProxy |
| * |
| * @since 1.1.0 |
| */ |
| void setProxy(IDEBeanTypeProxy beantypeProxy) { |
| this.resolvedProxy = beantypeProxy; |
| setProxy(resolvedProxy.getTypeClass(), Class.class); |
| } |
| |
| /** |
| * Called by IDEExpression to get the resolved beantype proxy. |
| * @return |
| * |
| * @since 1.1.0 |
| */ |
| IDEBeanTypeProxy getBeanTypeProxy() { |
| return resolvedProxy; |
| } |
| |
| /* |
| * (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) { |
| IProxyMethod method = ((IDEExpression) expression).getMethodExpressionProxy(this, methodName, parameterTypes); |
| if (method == null) { |
| // Need to go to the expression and create it. |
| method = ((Expression) expression).createMethodExpressionProxy(this, methodName, parameterTypes); |
| } |
| return method; |
| } |
| |
| /* (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) { |
| return ((IDEMethodProxyFactory) expression.getRegistry().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) { |
| IProxyField field = ((IDEExpression) expression).getFieldExpressionProxy(this, fieldName); |
| if (field == null) { |
| // Need to go to the expression and create it. |
| field = ((Expression) expression).createFieldExpressionProxy(this, fieldName); |
| } |
| return field; |
| } |
| } |
| |
| /** |
| * The Expression proxy for IDE BeanTypes. |
| * |
| * @since 1.1.0 |
| */ |
| protected static class IDEMethodExpressionProxy extends IDEExpressionProxy implements IProxyMethod { |
| |
| private String methodName; |
| private IDEMethodProxy resolvedProxy; |
| private ThrowableProxy errorThrowable; |
| |
| /** |
| * @param proxyid |
| * |
| * @since 1.1.0 |
| */ |
| public IDEMethodExpressionProxy(int proxyid, Expression expression) { |
| super(proxyid, METHOD_EXPRESSION_PROXY, expression); |
| } |
| |
| /** |
| * Set by IDEExpression with the method name. |
| * @param methodName |
| * |
| * @since 1.1.0 |
| */ |
| void setMethodName(String methodName) { |
| this.methodName = methodName; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jem.internal.proxy.core.ExpressionProxy#toString() |
| */ |
| public String toString() { |
| return super.toString()+" - "+methodName; //$NON-NLS-1$ |
| } |
| |
| /** |
| * Called by IDEExpression to resolve the beantype. |
| * @param methodProxy |
| * |
| * @since 1.1.0 |
| */ |
| void setProxy(IDEMethodProxy methodProxy) { |
| this.resolvedProxy = methodProxy; |
| setProxy(resolvedProxy.getBean(), Class.class); |
| } |
| |
| /** |
| * Called by IDEExpression to say there was error in creating the proxy. |
| * @param errorThrowable |
| * |
| * @since 1.1.0 |
| */ |
| void setThrowable(ThrowableProxy errorThrowable) { |
| this.errorThrowable = errorThrowable; |
| } |
| |
| /** |
| * Called by IDEExpression to get the resolved method proxy. |
| * @return |
| * @throws ThrowableProxy |
| * |
| * @since 1.1.0 |
| */ |
| IDEMethodProxy getMethodProxy() throws ThrowableProxy { |
| if (errorThrowable != null) |
| throw errorThrowable; |
| return resolvedProxy; |
| } |
| } |
| |
| protected static class IDEFieldExpressionProxy extends IDEExpressionProxy implements IProxyField { |
| |
| private String fieldName; |
| private IDEFieldProxy resolvedProxy; |
| private ThrowableProxy errorThrowable; |
| |
| /** |
| * @param proxyid |
| * |
| * @since 1.1.0 |
| */ |
| public IDEFieldExpressionProxy(int proxyid, Expression expression) { |
| super(proxyid, FIELD_EXPRESSION_PROXY, expression); |
| } |
| |
| /** |
| * Set by IDEExpression with the method name. |
| * @param fieldName |
| * |
| * @since 1.1.0 |
| */ |
| void setField(String fieldName) { |
| this.fieldName = fieldName; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jem.internal.proxy.core.ExpressionProxy#toString() |
| */ |
| public String toString() { |
| return super.toString()+" - "+fieldName; //$NON-NLS-1$ |
| } |
| |
| /** |
| * Called by IDEExpression to resolve the beantype. |
| * @param fieldProxy |
| * |
| * @since 1.1.0 |
| */ |
| void setProxy(IDEFieldProxy fieldProxy) { |
| this.resolvedProxy = fieldProxy; |
| setProxy(resolvedProxy.getBean(), Class.class); |
| } |
| |
| /** |
| * Called by IDEExpression to say there was error in creating the proxy. |
| * @param errorThrowable |
| * |
| * @since 1.1.0 |
| */ |
| void setThrowable(ThrowableProxy errorThrowable) { |
| this.errorThrowable = errorThrowable; |
| } |
| |
| /** |
| * Called by IDEExpression to get the resolved field proxy. |
| * @return |
| * @throws ThrowableProxy |
| * |
| * @since 1.1.0 |
| */ |
| IDEFieldProxy getFieldProxy() throws ThrowableProxy { |
| if (errorThrowable != null) |
| throw errorThrowable; |
| return resolvedProxy; |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * @see org.eclipse.jem.internal.proxy.core.Expression#createExpressionProxy(int, int) |
| */ |
| protected ExpressionProxy createExpressionProxy(int proxyType, int proxyID) { |
| switch (proxyType) { |
| case NORMAL_EXPRESSION_PROXY: |
| default: |
| return new IDEExpressionProxy(proxyID, NORMAL_EXPRESSION_PROXY, this); |
| |
| case BEANTYPE_EXPRESSION_PROXY: |
| return new IDEBeanTypeExpressionProxy(proxyID, this); |
| |
| case METHOD_EXPRESSION_PROXY: |
| return new IDEMethodExpressionProxy(proxyID, this); |
| |
| case FIELD_EXPRESSION_PROXY: |
| return new IDEFieldExpressionProxy(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) { |
| eproc.pushAssignment((InternalExpressionProxy) proxy); |
| } |
| |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jem.internal.proxy.core.Expression#pushAssignmentToProxy() |
| */ |
| protected void pushAssignmentToProxy() { |
| eproc.pushAssignment(); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jem.internal.proxy.core.Expression#pushBlockBeginToProxy(int) |
| */ |
| protected void pushBlockBeginToProxy(int blockNumber) { |
| eproc.pushBlockBegin(blockNumber); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jem.internal.proxy.core.Expression#pushBlockEndToProxy(int) |
| */ |
| protected void pushBlockEndToProxy(int blockNumber) { |
| eproc.pushBlockEnd(blockNumber); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * @see org.eclipse.jem.internal.proxy.core.Expression#pushBlockBreakToProxy(int) |
| */ |
| protected void pushBlockBreakToProxy(int blockNumber) { |
| eproc.pushBlockBreak(blockNumber); |
| } |
| |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jem.internal.proxy.core.Expression#pushTryBeginToProxy(int) |
| */ |
| protected void pushTryBeginToProxy(int tryNumber) { |
| eproc.pushTryBegin(tryNumber); |
| } |
| |
| /* |
| * (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) { |
| try { |
| eproc.pushTryCatchClause(tryNumber, getIDEBeanTypeProxy(exceptionType).getTypeClass(), (InternalExpressionProxy) ep); |
| } catch (ThrowableProxy e) { |
| eproc.processException(e); |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jem.internal.proxy.core.Expression#pushTryFinallyClauseToProxy(int) |
| */ |
| protected void pushTryFinallyClauseToProxy(int tryNumber) { |
| eproc.pushTryFinallyClause(tryNumber); |
| } |
| |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jem.internal.proxy.core.Expression#pushTryEndToProxy(int) |
| */ |
| protected void pushTryEndToProxy(int tryNumber) { |
| eproc.pushTryEnd(tryNumber); |
| } |
| |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jem.internal.proxy.core.Expression#pushThrowToProxy() |
| */ |
| protected void pushThrowToProxy() { |
| eproc.pushThrowException(); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jem.internal.proxy.core.Expression#pushRethrowToProxy(int) |
| */ |
| protected void pushRethrowToProxy(int tryNumber) { |
| eproc.pushTryRethrow(tryNumber); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * @see org.eclipse.jem.internal.proxy.core.Expression#pushBeanTypeToProxy(org.eclipse.jem.internal.proxy.core.IBeanTypeExpressionProxy) |
| */ |
| protected void pushBeanTypeToProxy(IBeanTypeExpressionProxy proxy) { |
| try { |
| IDEBeanTypeExpressionProxy ep = (IDEBeanTypeExpressionProxy) proxy; |
| IDEBeanTypeProxy typeProxy = getIDEBeanTypeProxy(proxy.getTypeName()); |
| ep.setProxy(typeProxy); |
| eproc.allocateExpressionProxy(ep); |
| if (!typeProxy.isValid()) { |
| Throwable cause = ((IDEInitErrorBeanTypeProxy) typeProxy).getCause(); |
| if (cause == null) |
| throw new IDEThrowableProxy( |
| new Exception(typeProxy.getInitializationError()), |
| getIDEBeanTypeFactory().getBeanTypeProxy(Exception.class)); |
| else |
| throw new IDEThrowableProxy( |
| cause, |
| getIDEBeanTypeFactory().getBeanTypeProxy(cause.getClass())); |
| |
| } |
| } catch (ThrowableProxy e) { |
| eproc.processException(e); |
| } |
| } |
| |
| /** |
| * Get the map of IProxyBeanTypes for a beantype name. Meant to be used only in conjunction with IDEStandardBeanTypeFactory. |
| * It is here so the IDDEStandardBeanTypeFactory 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 IDEStandardBeanTypeFactory. |
| * It is here so the IDEStandardBeanTypeFactory 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); |
| } |
| |
| /** |
| * Keeping a local map of Method Expression Proxies so that we don't keep recreating them for each request from within this expression. |
| * The map will be: declaringTypeName->(Map) methodName or IDEMethodKey -> method expression proxy. |
| * @see IDEExpression#pushMethodToProxy(ExpressionProxy, IProxyBeanType, String, IProxyBeanType[]) for the actual implementation. |
| */ |
| protected Map methodExpressionProxies; |
| |
| /** |
| * Keeping a local map of Field Expression Proxies so that we don't keep recreating them for each request from within this expression. |
| * The map will be: declaringTypeName->(Map) fieldname -> field expression proxy. |
| * @see IDEExpression#pushFieldToProxy(ExpressionProxy, IProxyBeanType, String) |
| */ |
| protected Map fieldExpressionProxies; |
| |
| /** |
| * Keeping a local map of BeanType expression proxies so that we don't keep recreating them for each request from within this expression. |
| * The map will be: typename->beanTypeExpressionProxy |
| */ |
| protected Map beanTypeCache; // Use to cache pending BeanTypes. Used in conjunction with IDEStandardBeanTypeFactory. |
| |
| /* |
| * Used as the key to the methodCache when there are parms. |
| * It allows the parms to be either IProxyBeanType without the |
| * overhead of creating complicated strings. |
| * |
| * It will compare method name and each individual parm name without fluffing |
| * up a string and building it up. |
| * |
| * For no parm methods, just the name of the method as a string will be the key. |
| * |
| * @since 1.1.0 |
| */ |
| private static class MethodKey { |
| public String methodName; |
| public IProxyBeanType[] parmTypes; |
| public MethodKey(String methodName, IProxyBeanType[] parmTypes) { |
| this.methodName = methodName; |
| this.parmTypes = parmTypes; |
| } |
| |
| |
| /* (non-Javadoc) |
| * @see java.lang.Object#equals(java.lang.Object) |
| */ |
| public boolean equals(Object obj) { |
| if (this == obj) |
| return true; |
| try { |
| return ((MethodKey) obj).compareParms(parmTypes); |
| } catch (ClassCastException e) { |
| return false; |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jem.internal.proxy.remote.REMProxyConstants.MethodKey#hashCode() |
| */ |
| public int hashCode() { |
| int h = methodName.hashCode();; |
| for (int i = 0; i < parmTypes.length; i++) { |
| h += parmTypes[i].getTypeName().hashCode(); |
| } |
| return h; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jem.internal.proxy.remote.REMProxyConstants.MethodKey#compareParms(java.lang.String[]) |
| */ |
| protected boolean compareParms(IProxyBeanType[] parms) { |
| if (parms.length != parmTypes.length) |
| return false; |
| for (int i = 0; i < parms.length; i++) { |
| if (!parmTypes[i].getTypeName().equals(parms[i].getTypeName())) |
| return false; |
| } |
| return true; |
| } |
| } |
| |
| |
| /* (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) { |
| try { |
| final Map methods = getMethods(declaringType); |
| final Object key = getMethodKey(methodName, parameterTypes); |
| methods.put(key, proxy); |
| proxy.addProxyListener(new ExpressionProxy.ProxyAdapter() { |
| |
| public void proxyNotResolved(ProxyEvent event) { |
| methods.remove(key); // Back it out. tis could happen due to endmark rollback. |
| } |
| |
| }); |
| |
| IDEMethodExpressionProxy ep = (IDEMethodExpressionProxy) proxy; |
| ep.setMethodName(methodName); |
| // We resolve immediately. Any expression proxies should also be resolved at this point too. |
| Class declaringClass = getIDEBeanTypeProxy(declaringType).getTypeClass(); |
| Class[] parameterClasses; |
| if (parameterTypes == null || parameterTypes.length == 0) |
| parameterClasses = null; |
| else { |
| parameterClasses = new Class[parameterTypes.length]; |
| for (int i = 0; i < parameterClasses.length; i++) { |
| parameterClasses[i] = getIDEBeanTypeProxy(parameterTypes[i]).getTypeClass(); |
| } |
| } |
| IDEMethodProxy methodProxy = ((IDEMethodProxyFactory) registry.getMethodProxyFactory()).getMethodProxy(declaringClass, methodName, parameterClasses); |
| if (methodProxy == null) { |
| String parms = ""; //$NON-NLS-1$ |
| if (parameterTypes != null && parameterTypes.length > 0) { |
| StringBuffer st = new StringBuffer(100); |
| for (int i = 0; i < parameterClasses.length; i++) { |
| if (i > 0) |
| st.append(','); |
| st.append(parameterTypes[i].getTypeName()); |
| } |
| parms = st.toString(); |
| } |
| throw new IDEThrowableProxy(new NoSuchMethodException("No method: "+declaringType+'.'+methodName+"("+parms+')'), //$NON-NLS-1$ //$NON-NLS-2$ |
| getIDEBeanTypeFactory().getBeanTypeProxy(NoSuchMethodException.class)); |
| } |
| |
| ep.setProxy(methodProxy); |
| eproc.allocateExpressionProxy(ep); |
| } catch (ThrowableProxy e) { |
| ((IDEMethodExpressionProxy) proxy).setThrowable(e); // So we don't recreate throwable all of the time. |
| eproc.processException(e); |
| } |
| } |
| |
| private Map getMethods(IProxyBeanType classtype) { |
| if (methodExpressionProxies == null) |
| methodExpressionProxies = new HashMap(); |
| Map methods = (Map) methodExpressionProxies.get(classtype.getTypeName()); |
| if (methods == null) |
| methodExpressionProxies.put(classtype.getTypeName(), methods = new HashMap()); |
| return methods; |
| } |
| |
| private Object getMethodKey(String methodName, IProxyBeanType[] parameterTypes) { |
| if (parameterTypes == null || parameterTypes.length == 0) |
| return methodName; |
| else |
| return new MethodKey(methodName, parameterTypes); |
| } |
| |
| private Map getFields(IProxyBeanType classtype) { |
| if (fieldExpressionProxies == null) |
| fieldExpressionProxies = new HashMap(); |
| Map fields = (Map) fieldExpressionProxies.get(classtype.getTypeName()); |
| if (fields == null) |
| fieldExpressionProxies.put(classtype.getTypeName(), fields = new HashMap()); |
| return fields; |
| } |
| |
| /** |
| * This is used by IDEBeanTypes and IDEBeanTypeExpressionProxy to access any already created Method Expression Proxies. |
| * |
| * @param declaringType |
| * @param methodName |
| * @param parameterTypes |
| * @return IProxyMethod or <code>null</code> if not yet created. |
| * |
| * @since 1.1.0 |
| */ |
| IProxyMethod getMethodExpressionProxy(IProxyBeanType declaringType, String methodName, IProxyBeanType[] parameterTypes) { |
| Map methods = getMethods(declaringType); |
| Object key = getMethodKey(methodName, parameterTypes); |
| return (IProxyMethod) methods.get(key); |
| } |
| |
| /** |
| * This is used by IDEBeanTypes and IDEBeanTypeExpressionProxy to access any already created Field Expression Proxies. |
| * @param declaringType |
| * @param fieldName |
| * @return |
| * |
| * @since 1.1.0 |
| */ |
| IProxyField getFieldExpressionProxy(IProxyBeanType declaringType, String fieldName) { |
| Map fields = getFields(declaringType); |
| return (IProxyField) fields.get(fieldName); |
| } |
| |
| /** |
| * Get the IDEMethodProxy out of the already resolved Expression Proxy or IDEMethodProxy itself. |
| * @param method |
| * @return |
| * @throws ThrowableProxy |
| * |
| * @since 1.1.0 |
| */ |
| protected IDEMethodProxy getIDEMethodProxy(IProxyMethod method) throws ThrowableProxy { |
| IDEMethodProxy methodProxy; |
| if (method.isExpressionProxy()) { |
| // It should already be resolved at this point. |
| methodProxy = ((IDEMethodExpressionProxy) method).getMethodProxy(); |
| } else |
| methodProxy = (IDEMethodProxy) method; |
| return methodProxy; |
| } |
| |
| /* (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, final String fieldName) { |
| |
| try { |
| final Map fields = getFields(declaringType); |
| fields.put(fieldName, proxy); |
| proxy.addProxyListener(new ExpressionProxy.ProxyAdapter(){ |
| public void proxyNotResolved(ExpressionProxy.ProxyEvent event) { |
| fields.remove(fieldName); // this can happen due to an endmark. It could be one of the ones that are rolled back. |
| } |
| }); |
| |
| |
| IDEFieldExpressionProxy ep = (IDEFieldExpressionProxy) proxy; |
| // We resolve immediately. Any expression proxies should also be resolved at this point too. |
| IDEFieldProxy fieldProxy = (IDEFieldProxy) getIDEBeanTypeProxy(declaringType).getFieldProxy(fieldName); |
| if (fieldProxy == null) { |
| throw new IDEThrowableProxy(new NoSuchFieldException("No field: "+declaringType+'.'+fieldName), //$NON-NLS-1$ |
| getIDEBeanTypeFactory().getBeanTypeProxy(NoSuchFieldException.class)); |
| } |
| |
| ep.setProxy(fieldProxy); |
| eproc.allocateExpressionProxy(ep); |
| } catch (ThrowableProxy e) { |
| ((IDEFieldExpressionProxy) proxy).setThrowable(e); // So we don't recreate throwable all of the time. |
| eproc.processException(e); |
| } |
| |
| } |
| |
| /** |
| * Get the IDEFieldProxy out of the already resolved Expression Proxy or IDEFieldProxy itself. |
| * @param field |
| * @return |
| * @throws ThrowableProxy |
| * |
| * @since 1.1.0 |
| */ |
| protected IDEFieldProxy getIDEFieldProxy(IProxyField field) throws ThrowableProxy { |
| IDEFieldProxy fieldProxy; |
| if (field.isExpressionProxy()) { |
| // It should already be resolved at this point. |
| fieldProxy = ((IDEFieldExpressionProxy) field).getFieldProxy(); |
| } else |
| fieldProxy = (IDEFieldProxy) field; |
| return fieldProxy; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jem.internal.proxy.core.Expression#pushIfTestToProxy() |
| */ |
| protected void pushIfTestToProxy() { |
| eproc.pushIfElse(); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jem.internal.proxy.core.Expression#pushIfElseToProxy(org.eclipse.jem.internal.proxy.initParser.tree.InternalIfElseOperandType) |
| */ |
| protected void pushIfElseToProxy(InternalIfElseOperandType clauseType) { |
| eproc.pushIfElse(clauseType); |
| } |
| |
| /* (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) { |
| try { |
| eproc.pushNewInstanceFromString(initializationString, getIDEBeanTypeProxy(resultType).getTypeClass(), getIDERegistry().fClassLoader); |
| } catch (ThrowableProxy e) { |
| eproc.processException(e); |
| } |
| } |
| |
| protected void pushMarkToProxy(int markID) { |
| eproc.pushMark(markID); |
| } |
| |
| protected void pushEndmarkToProxy(int markID, boolean restore) { |
| eproc.pushEndmark(markID, restore); |
| } |
| |
| protected void pushBeginTransferThreadToProxy() { |
| // For IDE it doesn't matter. Just go ahead and continue processing. |
| } |
| |
| protected void pushTransferThreadToProxy() { |
| // For IDE it doesn't matter. Just go ahead and continue processing. |
| } |
| |
| protected void pushSubexpressionBeginToProxy(int subexpressionNumber) { |
| eproc.pushSubexpressionBegin(subexpressionNumber); |
| } |
| |
| protected void pushSubexpressionEndToProxy(int subexpressionNumber) { |
| eproc.pushSubexpressionEnd(subexpressionNumber); |
| } |
| } |