| /******************************************************************************* |
| * 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.ide; |
| /* |
| |
| |
| */ |
| |
| import org.eclipse.jem.internal.proxy.core.*; |
| import java.lang.reflect.*; |
| import java.util.Arrays; |
| |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Status; |
| /** |
| * IDE VM version of the Array proxy |
| */ |
| |
| public final class IDEArrayBeanProxy extends IDEObjectBeanProxy implements IArrayBeanProxy { |
| |
| private IDEStandardBeanTypeProxyFactory fBeanTypeProxyFactory; |
| |
| IDEArrayBeanProxy(IDEProxyFactoryRegistry aRegistry, Object array,IBeanTypeProxy aType) { |
| super(aRegistry, array ,aType); |
| fBeanTypeProxyFactory = (IDEStandardBeanTypeProxyFactory)aRegistry.getBeanTypeProxyFactory(); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jem.internal.proxy.ide.IDEBeanProxy#equals(java.lang.Object) |
| */ |
| public boolean equals(Object obj) { |
| if (super.equals(obj)) |
| return true; |
| if (!(obj instanceof IDEArrayBeanProxy)) |
| return false; |
| Object arrayBean = ((IDEArrayBeanProxy) obj).getBean(); |
| |
| if (getBean() == null || arrayBean == null) |
| return false; |
| Object thisArrayBean = getBean(); |
| Class aclass = thisArrayBean.getClass(); |
| Class bclass = arrayBean.getClass(); |
| Class acomp = aclass.getComponentType(); |
| Class bcomp = bclass.getComponentType(); |
| if (acomp.isPrimitive() || bcomp.isPrimitive()) { |
| if (acomp != bcomp) |
| return false; |
| if (acomp == Integer.TYPE) |
| return Arrays.equals((int[]) thisArrayBean, (int[]) arrayBean); |
| else if (acomp == Boolean.TYPE) |
| return Arrays.equals((boolean[]) thisArrayBean, (boolean[]) arrayBean); |
| else if (acomp == Long.TYPE) |
| return Arrays.equals((long[]) thisArrayBean, (long[]) arrayBean); |
| else if (acomp == Short.TYPE) |
| return Arrays.equals((short[]) thisArrayBean, (short[]) arrayBean); |
| else if (acomp == Double.TYPE) |
| return Arrays.equals((double[]) thisArrayBean, (double[]) arrayBean); |
| else if (acomp == Float.TYPE) |
| return Arrays.equals((float[]) thisArrayBean, (float[]) arrayBean); |
| else if (acomp == Character.TYPE) |
| return Arrays.equals((char[]) thisArrayBean, (char[]) arrayBean); |
| else if (acomp == Byte.TYPE) |
| return Arrays.equals((byte[]) thisArrayBean, (byte[]) arrayBean); |
| else |
| return false; |
| } else |
| return Arrays.equals((Object[]) thisArrayBean, (Object[]) arrayBean); |
| } |
| /** |
| * Get the object at the specified index. |
| */ |
| public IBeanProxy get(int index) throws ThrowableProxy { |
| // 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. |
| Object result = Array.get(fBean,index); |
| if ( result == null ) return null; |
| return ((IDEBeanTypeProxy)fBeanTypeProxyFactory.getBeanTypeProxy(result.getClass())).newBeanProxy(result); |
| } else { |
| // Use the correct primitive getter. |
| int id = ((IDEPrimitiveBeanTypeProxy)compType).getPrimitiveType(); |
| switch (id) { |
| case IDEPrimitiveBeanTypeProxy.BYTE: |
| return fBeanTypeProxyFactory.byteType.createByteBeanProxy(Array.getByte(fBean,index)); |
| case IDEPrimitiveBeanTypeProxy.BOOLEAN: |
| return fBeanTypeProxyFactory.booleanType.createBooleanBeanProxy(Array.getBoolean(fBean,index)); |
| case IDEPrimitiveBeanTypeProxy.CHAR: |
| return fBeanTypeProxyFactory.charType.createCharBeanProxy(Array.getChar(fBean,index)); |
| case IDEPrimitiveBeanTypeProxy.DOUBLE: |
| return fBeanTypeProxyFactory.doubleType.createDoubleBeanProxy(Array.getDouble(fBean,index)); |
| case IDEPrimitiveBeanTypeProxy.FLOAT: |
| return fBeanTypeProxyFactory.floatType.createFloatBeanProxy(Array.getFloat(fBean,index)); |
| case IDEPrimitiveBeanTypeProxy.INTEGER: |
| return fBeanTypeProxyFactory.intType.createIntegerBeanProxy(Array.getInt(fBean,index)); |
| case IDEPrimitiveBeanTypeProxy.LONG: |
| return fBeanTypeProxyFactory.longType.createLongBeanProxy(Array.getLong(fBean,index)); |
| case IDEPrimitiveBeanTypeProxy.SHORT: |
| return fBeanTypeProxyFactory.shortType.createShortBeanProxy(Array.getShort(fBean,index)); |
| default : |
| return null; // Shouldn't get here, said it was primitive, but not one we understand |
| } |
| } |
| } |
| /** |
| * 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 { |
| if (indexes.length == 1) |
| return get(indexes[0]); |
| int dims = ((IArrayBeanTypeProxy) getTypeProxy()).getDimensions(); |
| if (dims < indexes.length) |
| throw new IllegalArgumentException(); // Too many dimensions |
| // Get up to the next to last dimension so that we can do the appropriate final get depending upon primitive or not. |
| Object array = fBean; |
| int lastArrayDim = indexes.length - 1; |
| for (int i = 0; i < lastArrayDim; i++) |
| array = Array.get(array, indexes[i]); |
| |
| int index = indexes[lastArrayDim]; // Final array dim to retrieve |
| |
| if (dims == indexes.length) { |
| IBeanTypeProxy finalCompType = ((IArrayBeanTypeProxy) getTypeProxy()).getFinalComponentType(); |
| if (finalCompType.isPrimitive()) { |
| // 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 id = ((IDEPrimitiveBeanTypeProxy) finalCompType).getPrimitiveType(); |
| switch (id) { |
| case IDEPrimitiveBeanTypeProxy.BYTE : |
| return fBeanTypeProxyFactory.byteType.createByteBeanProxy(Array.getByte(array, index)); |
| case IDEPrimitiveBeanTypeProxy.BOOLEAN : |
| return fBeanTypeProxyFactory.booleanType.createBooleanBeanProxy(Array.getBoolean(array, index)); |
| case IDEPrimitiveBeanTypeProxy.CHAR : |
| return fBeanTypeProxyFactory.charType.createCharBeanProxy(Array.getChar(array, index)); |
| case IDEPrimitiveBeanTypeProxy.DOUBLE : |
| return fBeanTypeProxyFactory.doubleType.createDoubleBeanProxy(Array.getDouble(array, index)); |
| case IDEPrimitiveBeanTypeProxy.FLOAT : |
| return fBeanTypeProxyFactory.floatType.createFloatBeanProxy(Array.getFloat(array, index)); |
| case IDEPrimitiveBeanTypeProxy.INTEGER : |
| return fBeanTypeProxyFactory.intType.createIntegerBeanProxy(Array.getInt(array, index)); |
| case IDEPrimitiveBeanTypeProxy.LONG : |
| return fBeanTypeProxyFactory.longType.createLongBeanProxy(Array.getLong(array, index)); |
| case IDEPrimitiveBeanTypeProxy.SHORT : |
| return fBeanTypeProxyFactory.shortType.createShortBeanProxy(Array.getShort(array, index)); |
| default : |
| return null; // Shouldn't get here, said it was primitive, but not one we understand |
| } |
| } |
| } |
| |
| // Won't be returning a primitive, so use standard accessor |
| Object result = Array.get(array, index); |
| if (result == null) |
| return null; |
| return ((IDEBeanTypeProxy) fBeanTypeProxyFactory.getBeanTypeProxy(result.getClass())).newBeanProxy( |
| result); |
| } |
| |
| /** |
| * Set the object at the specified index. |
| */ |
| public void set(IBeanProxy valueProxy, int index) throws ThrowableProxy { |
| // 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. |
| Object value = ((IIDEBeanProxy)valueProxy).getBean(); |
| Class valueClass = value.getClass(); |
| if (!valueClass.isPrimitive()) { |
| // Use standard getter. |
| Array.set(fBean,index,value); |
| } else if (valueClass == Byte.TYPE ) { |
| Array.setByte(fBean,index,((Byte)value).byteValue()); |
| } else if (valueClass == Boolean.TYPE ){ |
| Array.setBoolean(fBean,index,((Boolean)value).booleanValue()); |
| } else if (valueClass == Character.TYPE) { |
| Array.setChar(fBean,index,((Character)value).charValue()); |
| } else if (valueClass == Double.TYPE) { |
| Array.setDouble(fBean,index,((Double)value).doubleValue()); |
| } else if (valueClass == Float.TYPE) { |
| Array.setFloat(fBean,index,((Float)value).floatValue()); |
| } else if (valueClass == Integer.TYPE) { |
| Array.setInt(fBean,index,((Integer)value).intValue()); |
| } else if (valueClass == Long.TYPE ) { |
| Array.setLong(fBean,index,((Long)value).longValue()); |
| } else if (valueClass == Short.TYPE ) { |
| Array.setShort(fBean,index,((Short)value).shortValue()); |
| } |
| } |
| /** |
| * 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 valueProxy, int[] indexes) throws ThrowableProxy { |
| |
| Object subArray = fBean; |
| int upTo = indexes.length - 1; |
| for (int i = 0; i < upTo; i++) |
| subArray = Array.get(subArray, indexes[i]); |
| int index = indexes[upTo]; |
| |
| // Now set the appropriate value in |
| // 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. |
| Object value = ((IIDEBeanProxy) valueProxy).getBean(); |
| Class valueClass = value.getClass(); |
| if (!valueClass.isPrimitive()) { |
| // Use standard getter. |
| Array.set(subArray, index, value); |
| } else if (valueClass == Byte.TYPE) { |
| Array.setByte(subArray, index, ((Byte) value).byteValue()); |
| } else if (valueClass == Boolean.TYPE) { |
| Array.setBoolean(subArray, index, ((Boolean) value).booleanValue()); |
| } else if (valueClass == Character.TYPE) { |
| Array.setChar(subArray, index, ((Character) value).charValue()); |
| } else if (valueClass == Double.TYPE) { |
| Array.setDouble(subArray, index, ((Double) value).doubleValue()); |
| } else if (valueClass == Float.TYPE) { |
| Array.setFloat(subArray, index, ((Float) value).floatValue()); |
| } else if (valueClass == Integer.TYPE) { |
| Array.setInt(subArray, index, ((Integer) value).intValue()); |
| } else if (valueClass == Long.TYPE) { |
| Array.setLong(subArray, index, ((Long) value).longValue()); |
| } else if (valueClass == Short.TYPE) { |
| Array.setShort(subArray, index, ((Short) value).shortValue()); |
| } |
| |
| } |
| /** |
| * 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() { |
| return Array.getLength(fBean); |
| } |
| /** |
| * @see org.eclipse.jem.internal.proxy.core.IArrayBeanProxy#getCatchThrowableException(int) |
| */ |
| public IBeanProxy getCatchThrowableException(int index) { |
| try { |
| return get(index); |
| } catch ( ThrowableProxy exc ) { |
| ProxyPlugin.getPlugin().getLogger().log(new Status(IStatus.WARNING, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, "", exc)); //$NON-NLS-1$ |
| return null; |
| } |
| } |
| |
| |
| public IBeanProxy[] getSnapshot() throws ThrowableProxy { |
| // 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(); |
| int id = compType.isPrimitive() ? ((IDEPrimitiveBeanTypeProxy)compType).getPrimitiveType() : -1; |
| IBeanProxy[] result = new IBeanProxy[Array.getLength(fBean)]; |
| for (int i = 0; i < result.length; i++) { |
| if (id == -1) { |
| // Use standard getter. |
| Object val = Array.get(fBean,i); |
| if ( val != null ) |
| result[i] = ((IDEBeanTypeProxy)fBeanTypeProxyFactory.getBeanTypeProxy(val.getClass())).newBeanProxy(val); |
| } else { |
| // Use the correct primitive getter. |
| switch (id) { |
| case IDEPrimitiveBeanTypeProxy.BYTE: |
| result[i] = fBeanTypeProxyFactory.byteType.createByteBeanProxy(Array.getByte(fBean,i)); |
| break; |
| case IDEPrimitiveBeanTypeProxy.BOOLEAN: |
| result[i] = fBeanTypeProxyFactory.booleanType.createBooleanBeanProxy(Array.getBoolean(fBean,i)); |
| break; |
| case IDEPrimitiveBeanTypeProxy.CHAR: |
| result[i] = fBeanTypeProxyFactory.charType.createCharBeanProxy(Array.getChar(fBean,i)); |
| break; |
| case IDEPrimitiveBeanTypeProxy.DOUBLE: |
| result[i] = fBeanTypeProxyFactory.doubleType.createDoubleBeanProxy(Array.getDouble(fBean,i)); |
| break; |
| case IDEPrimitiveBeanTypeProxy.FLOAT: |
| result[i] = fBeanTypeProxyFactory.floatType.createFloatBeanProxy(Array.getFloat(fBean,i)); |
| break; |
| case IDEPrimitiveBeanTypeProxy.INTEGER: |
| result[i] = fBeanTypeProxyFactory.intType.createIntegerBeanProxy(Array.getInt(fBean,i)); |
| break; |
| case IDEPrimitiveBeanTypeProxy.LONG: |
| result[i] = fBeanTypeProxyFactory.longType.createLongBeanProxy(Array.getLong(fBean,i)); |
| break; |
| case IDEPrimitiveBeanTypeProxy.SHORT: |
| result[i] = fBeanTypeProxyFactory.shortType.createShortBeanProxy(Array.getShort(fBean,i)); |
| break; |
| default : |
| break; // Shouldn't get here, said it was primitive, but not one we understand |
| } |
| } |
| } |
| return result; |
| } |
| |
| } |