| /******************************************************************************* |
| * Copyright (c) 2001, 2005 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.jem.internal.proxy.remote; |
| /* |
| |
| |
| */ |
| |
| import java.lang.reflect.Array; |
| import java.util.logging.Level; |
| |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Status; |
| |
| import org.eclipse.jem.internal.proxy.common.CommandException; |
| import org.eclipse.jem.internal.proxy.common.remote.CommandErrorException; |
| import org.eclipse.jem.internal.proxy.common.remote.Commands; |
| import org.eclipse.jem.internal.proxy.common.remote.Commands.ValueObject; |
| import org.eclipse.jem.internal.proxy.core.*; |
| /** |
| * IDE VM version of the Array proxy |
| */ |
| |
| public final class REMArrayBeanProxy extends REMBeanProxy implements IArrayBeanProxy { |
| private int fLength = -1; |
| |
| REMArrayBeanProxy(REMProxyFactoryRegistry aRegistry, Integer anID, IBeanTypeProxy aType) { |
| super(aRegistry, anID, aType); |
| } |
| |
| public boolean equals(Object anObject) { |
| if (!(anObject instanceof IArrayBeanProxy)) |
| return false; |
| if (sameAs((IBeanProxy) anObject)) |
| return true; // Identity |
| if (((IBeanProxy) anObject).getProxyFactoryRegistry() == fFactory) |
| try { |
| // The other is an array also, let the server do the check. We will use Arrays.equals. |
| return ((IBooleanBeanProxy) REMStandardBeanProxyConstants.getConstants(fFactory).getArrayHelperEquals().invoke(null, new IBeanProxy[] {this, (IBeanProxy) anObject})).booleanValue(); |
| } catch (ThrowableProxy e) { |
| ProxyPlugin.getPlugin().getLogger().log(e, Level.INFO); |
| } |
| return false; |
| } |
| |
| /** |
| * Get the object at the specified index. |
| */ |
| public IBeanProxy get(int index) throws ThrowableProxy { |
| // Format of getter parms is: (Object (array), int (index)). |
| Object[] parms = new Object[] {this, new Integer(index)}; |
| // If the component type is primitive, we need to use the correct getter so that a valid value is returned, |
| // if we just used the standard get, if the type was "int" the value returned would be an java.lang.Integer. |
| IBeanTypeProxy compType = ((IArrayBeanTypeProxy) getTypeProxy()).getComponentType(); |
| if (!compType.isPrimitive()) { |
| // Use standard getter. |
| return ((IREMMethodProxy) REMStandardBeanProxyConstants.getConstants(fFactory).getArrayGet()).invokeWithParms(null, parms); |
| } else { |
| // Use the correct primitive getter. |
| int id = ((IREMBeanProxy) compType).getID().intValue(); |
| switch (id) { |
| case Commands.BYTE_TYPE: |
| return ((IREMMethodProxy) REMStandardBeanProxyConstants.getConstants(fFactory).getArrayGetByte()).invokeWithParms(null, parms); |
| case Commands.BOOLEAN_TYPE: |
| return ((IREMMethodProxy) REMStandardBeanProxyConstants.getConstants(fFactory).getArrayGetBoolean()).invokeWithParms(null, parms); |
| case Commands.CHARACTER_TYPE: |
| return ((IREMMethodProxy) REMStandardBeanProxyConstants.getConstants(fFactory).getArrayGetChar()).invokeWithParms(null, parms); |
| case Commands.DOUBLE_TYPE: |
| return ((IREMMethodProxy) REMStandardBeanProxyConstants.getConstants(fFactory).getArrayGetDouble()).invokeWithParms(null, parms); |
| case Commands.FLOAT_TYPE: |
| return ((IREMMethodProxy) REMStandardBeanProxyConstants.getConstants(fFactory).getArrayGetFloat()).invokeWithParms(null, parms); |
| case Commands.INTEGER_TYPE: |
| return ((IREMMethodProxy) REMStandardBeanProxyConstants.getConstants(fFactory).getArrayGetInt()).invokeWithParms(null, parms); |
| case Commands.LONG_TYPE: |
| return ((IREMMethodProxy) REMStandardBeanProxyConstants.getConstants(fFactory).getArrayGetLong()).invokeWithParms(null, parms); |
| case Commands.SHORT_TYPE: |
| return ((IREMMethodProxy) REMStandardBeanProxyConstants.getConstants(fFactory).getArrayGetShort()).invokeWithParms(null, parms); |
| } |
| } |
| |
| return null; |
| } |
| |
| /** |
| * Get the object at the specified multi-dimensional index. |
| * The array must be at least the number of dimensions specified, |
| * and each index along the way must exist. |
| * The number of dimensions can't be greater than the number |
| * of dimensions of the real object. |
| */ |
| public IBeanProxy get(int [] indexes) throws ThrowableProxy { |
| // Format of getter parms is: (Object (array), int[] (indexes)). |
| Object[] parms = new Object[] {this, indexes}; |
| // If the component type at the specified dimension is primitive, we need to use the correct getter so that a valid value is returned, |
| // if we just used the standard get, if the type was "int" the value returned would be an java.lang.Integer. |
| int dims = ((IArrayBeanTypeProxy) getTypeProxy()).getDimensions(); |
| if (dims < indexes.length) |
| throw new IllegalArgumentException(); // Too many dimensions |
| IBeanTypeProxy finalCompType = ((IArrayBeanTypeProxy) getTypeProxy()).getFinalComponentType(); |
| if (dims == indexes.length && finalCompType.isPrimitive()) { |
| // Use the correct primitive getter because we are accessing the final component and it is primitive. |
| int id = ((IREMBeanProxy) finalCompType).getID().intValue(); |
| switch (id) { |
| case Commands.BYTE_TYPE: |
| return ((IREMMethodProxy) REMStandardBeanProxyConstants.getConstants(fFactory).getArrayHelperGetByte()).invokeWithParms(null, parms); |
| case Commands.BOOLEAN_TYPE: |
| return ((IREMMethodProxy) REMStandardBeanProxyConstants.getConstants(fFactory).getArrayHelperGetBoolean()).invokeWithParms(null, parms); |
| case Commands.CHARACTER_TYPE: |
| return ((IREMMethodProxy) REMStandardBeanProxyConstants.getConstants(fFactory).getArrayHelperGetChar()).invokeWithParms(null, parms); |
| case Commands.DOUBLE_TYPE: |
| return ((IREMMethodProxy) REMStandardBeanProxyConstants.getConstants(fFactory).getArrayHelperGetDouble()).invokeWithParms(null, parms); |
| case Commands.FLOAT_TYPE: |
| return ((IREMMethodProxy) REMStandardBeanProxyConstants.getConstants(fFactory).getArrayHelperGetFloat()).invokeWithParms(null, parms); |
| case Commands.INTEGER_TYPE: |
| return ((IREMMethodProxy) REMStandardBeanProxyConstants.getConstants(fFactory).getArrayHelperGetInt()).invokeWithParms(null, parms); |
| case Commands.LONG_TYPE: |
| return ((IREMMethodProxy) REMStandardBeanProxyConstants.getConstants(fFactory).getArrayHelperGetLong()).invokeWithParms(null, parms); |
| case Commands.SHORT_TYPE: |
| return ((IREMMethodProxy) REMStandardBeanProxyConstants.getConstants(fFactory).getArrayHelperGetShort()).invokeWithParms(null, parms); |
| } |
| } else { |
| // It is not the final component, or it is not primitive, use the standard accessor. |
| return ((IREMMethodProxy) REMStandardBeanProxyConstants.getConstants(fFactory).getArrayHelperGet()).invokeWithParms(null, parms); |
| } |
| |
| return null; |
| } |
| |
| /** |
| * Set the object at the specified index. |
| */ |
| public void set(IBeanProxy value, int index) throws ThrowableProxy { |
| // Format of setter parms is: (Object (array), int (index), Object (value)). |
| Object[] parms = new Object[] {this, new Integer(index), value}; |
| ((IREMMethodProxy) REMStandardBeanProxyConstants.getConstants(fFactory).getArraySet()).invokeWithParms(null, parms); |
| } |
| |
| /** |
| * Set the object at the specified multi-dimensional index. |
| * The array must be at least the number of dimensions specified, |
| * and each index along the way must exist. |
| * The number of dimensions can't be greater than the number |
| * of dimensions of the real object. |
| */ |
| public void set(IBeanProxy value, int [] indexes) throws ThrowableProxy { |
| // Format of setter parms is: (Object (array), int[] (indexes), Object (value)). |
| Object[] parms = new Object[] {this, indexes, value}; |
| ((IREMMethodProxy) REMStandardBeanProxyConstants.getConstants(fFactory).getArrayHelperSet()).invokeWithParms(null, parms); |
| } |
| |
| /** |
| * Get the length of the first dimension of this array. |
| * If there are multi-dimensions, you must get the appropriate |
| * dimension from the get method to see the size of that dimension. |
| * |
| * e.g. |
| * int [3] returns 3 |
| * int [3][2] returns 3 |
| * |
| * ((IArrayBeanProxy) get(1)).getLength() returns 2 |
| * Since arrays do not have to be homogenous, there could |
| * be a different length array for each of the arrays |
| * returned from the first dimension, the returned length |
| * from get(2) and get(3) could result in a different value |
| * from get(1). |
| */ |
| public int getLength() { |
| if (fLength == -1) { |
| // It hasn't yet been quiered. |
| fLength = ((IIntegerBeanProxy) REMStandardBeanProxyConstants.getConstants(fFactory).getArrayGetLength().invokeCatchThrowableExceptions(null, this)).intValue(); |
| } |
| return fLength; |
| } |
| |
| public IBeanProxy getCatchThrowableException(int index){ |
| try { |
| return get(index); |
| } catch (ThrowableProxy e) { |
| ProxyPlugin.getPlugin().getLogger().log(new Status(IStatus.WARNING, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, "", e)); //$NON-NLS-1$ |
| fFactory.releaseProxy(e); // Since it's no longer needed, get rid of now instead of GC time. |
| return null; |
| } |
| } |
| |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jem.internal.proxy.core.IArrayBeanProxy#getSnapshot() |
| */ |
| public IBeanProxy[] getSnapshot() throws ThrowableProxy { |
| IREMConnection connect = fFactory.getFreeConnection(); |
| REMStandardBeanProxyFactory proxyFactory = (REMStandardBeanProxyFactory) fFactory.getBeanProxyFactory(); |
| proxyFactory.startTransaction(); // This is definately a transaction, so start it. |
| try { |
| Commands.ValueObject returnValue = new Commands.ValueObject(); |
| try { |
| try { |
| connect.getArrayContents(getID().intValue(), returnValue); |
| return processReturnValue(connect, returnValue); |
| } catch (CommandErrorException e) { |
| proxyFactory.processErrorReturn(e); |
| } |
| } catch (CommandException e) { |
| if (!e.isRecoverable()) { |
| // Close the connection and try again. |
| fFactory.closeConnection(connect); |
| connect = null; |
| connect = fFactory.getFreeConnection(); |
| try { |
| connect.getArrayContents(getID().intValue(), returnValue); |
| return processReturnValue(connect, returnValue); |
| } catch (CommandException eAgain) { |
| // Failed again. Just close and print trace. |
| fFactory.closeConnection(connect); |
| connect = null; |
| ProxyPlugin.getPlugin().getLogger().log(new Status(IStatus.WARNING, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, "", eAgain)); //$NON-NLS-1$ |
| return null; |
| } |
| } else { |
| // A recoverable error, print trace and return |
| ProxyPlugin.getPlugin().getLogger().log(new Status(IStatus.WARNING, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, "", e)); //$NON-NLS-1$ |
| return null; |
| } |
| } |
| } finally { |
| proxyFactory.stopTransaction(); |
| if (connect != null) |
| fFactory.returnConnection(connect); |
| } |
| return null; |
| } |
| |
| |
| /* |
| * @param returnValue |
| * @return |
| * |
| * @since 1.1.0 |
| */ |
| private IBeanProxy[] processReturnValue(IREMConnection connection, ValueObject returnValue) throws CommandException, ThrowableProxy { |
| // It is an array containing IDs, as it normally would be. |
| // However it will become IBeanProxy[]. That is because if ID's |
| // they must be proxies over here. |
| BeanProxyValueSender valueSender = new BeanProxyValueSender((REMStandardBeanProxyFactory) fFactory.getBeanProxyFactory(), returnValue); |
| connection.readProxyArrayValues(returnValue, valueSender, false); |
| Exception e = valueSender.getException(); |
| if (e != null) { |
| if (e instanceof ThrowableProxy) |
| throw (ThrowableProxy) e; |
| else |
| throw (CommandException) e; |
| } |
| Object vals = valueSender.getArray(); |
| IBeanProxy[] proxyArray = new IBeanProxy[Array.getLength(vals)]; |
| System.arraycopy(vals, 0, proxyArray, 0, proxyArray.length); |
| return proxyArray; |
| } |
| |
| } |
| |
| |