I have the following changes to the ArrayValue interface working and can preserve the
primitive type arrays:
| public interface ArrayValue<T extends Serializable>
| extends MetaValue, Iterable<T>
| {
| ArrayMetaType<T> getMetaType();
|
| /**
| * Get the underlying array value. This will not be an
| * Object[] in general.
| * @see #getValue(int)
| *
| * @return the underlying value
| */
| public Object getValue();
| /**
| * Get the length of the array.
| * @return length of the array.
| */
| public int getLength();
| /**
| * Get the array element at index.
| * @param index - index into the array.
| * @return element at index.
| */
| public Object getValue(int index);
| }
|
As this ArrayValueSupportUnitTestCase test shows, you can use the getValue(int) accessor,
the type safe foreach Iterable, or the raw array:
| public void testCharArray() throws Exception
| {
| ArrayMetaType<Character> type = new ArrayMetaType<Character>(1,
SimpleMetaType.CHARACTER);
| char[] value = {'h', 'e', 'l', 'l',
'o'};
| ArrayValueSupport<Character> avs = new
ArrayValueSupport<Character>(type, value);
| // Use getValue(int) accessor
| for(int n = 0; n < avs.getLength(); n ++)
| {
| Object element = avs.getValue(n);
| assertEquals(value[n], element);
| }
| // Use typesafe foreach Iterable
| int i = 0;
| for(Character c : avs)
| {
| assertEquals("["+i+"]", (Character) value[i++], c);
| }
| // Validate the primative array
| char[] raw = (char[]) avs.getValue();
| for(int n = 0; n < value.length; n ++)
| {
| assertEquals(value[n], raw[n]);
| }
| }
|
There are quirks for multi-dimensional primitive arrays though. This 2d char[][] test
shows them:
| public void test2DCharArray() throws Exception
| {
| ArrayMetaType<Character[]> type = new ArrayMetaType<Character[]>(2,
SimpleMetaType.CHARACTER, true);
| char[][] value = {{'h', 'e'}, {'l', 'l',
'o'}};
| ArrayValueSupport<Character[]> avs = new
ArrayValueSupport<Character[]>(type, value);
| assertEquals(value.length, avs.getLength());
| for(int m = 0; m < value.length; m ++)
| {
| Object arraym = avs.getValue(m);
| for(int n = 0; n < value[m].length; n ++)
| {
| // Have to use the java.lang.reflect.Array to access nested elements
| Object valuenm = Array.get(arraym, n);
| assertEquals("["+m+"]["+n+"]", value[m][n],
valuenm);
| }
| }
| // Use typesafe foreach Iterable: current broken with CCE on [C
| int i = 0, j = 0;
| for(Character[] carray : avs) // CCE here
| {
| for(Character c : carray)
| {
| Character cij = value[i ++][j ++];
| assertEquals("["+i+"], ["+j+"]", cij , c);
| }
| }
| // Validate the primitive 2d array
| char[][] raw = (char[][]) avs.getValue();
| for(int m = 0; m < value.length; m ++)
| {
| for(int n = 0; n < value[m].length; n ++)
| {
| assertEquals("["+m+"]["+n+"]", value[m][n],
raw[m][n]);
| }
| }
| }
|
The first is that you have to use java.lang.reflect.Array.get(Object, int) to access the
elements of the nested arrays obtained via the get(int) accessor.
The second is that the Iterable implementation on ArrayValueSupport needs to track whether
the underlying value is a primitive array, and covert it to the primitive wrapper form to
avoid the CCE.
Before going further I want to see if we agree that this is the way to go.
View the original post :
http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4072109#...
Reply to the post :
http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&a...