Bug 3302 - ReflectionResourceProperty inconsistent handling on remove on Array type
: ReflectionResourceProperty inconsistent handling on remove on Array type
Status: RESOLVED FIXED
: Java WS Core
globus_wsrf_core
: 4.0.0
: PC Windows XP
: P3 major
: ---
Assigned To:
:
:
:
:
  Show dependency treegraph
 
Reported: 2005-05-05 22:17 by
Modified: 2005-05-09 01:28 (History)


Attachments


Note

You need to log in before you can comment on or make changes to this bug.


Description From 2005-05-05 22:17:16
The remove operation on the reflection resource property (array type only) 
removes all items matching the argument, versus the first object matching the 
argument.

From wsrf/ResourceProperty.java:
    /**
     * Removes a specific value. If the resource property contains
     * multiple of the same value, only the first one is removed. 
     *
     * @param value value to remove.
     * @return true if the value was removed. False otherwise.
     */
    boolean remove(Object value);

The problem appears to be in the following code in 
wsrf/impl/ReflectionResourceProperty.java :


    private boolean removeArray(Object value) {
        Object array = getValueArray();
        if (array == null) {
            return false;
        }
        Object convertedValue = convert(value);

        int len = Array.getLength(array);
        int j = 0;
        Object currValue = null;
        for (int i = 0; i < len; i++) {       // NOTE:loops thru entire array
            currValue = Array.get(array, i);
            if (!currValue.equals(convertedValue)) {  //ANY MATCHING VALUE
                if (j != i) {                         // not just First
                    Array.set(array, j, currValue);
                }
                j++;
            }
        }

        if (j != len) {
            Object newArray = null;
            if (j > 0) {
                Class componentType =
                    this.getMethod.getReturnType().getComponentType();
                newArray = Array.newInstance(componentType, j);
                System.arraycopy(array, 0, newArray, 0, j);
            }
            try {
                this.setMethod.invoke(this.obj, new Object[] {newArray});
            } catch (Exception e) {
                throw handleException(e);
            }
            return true;
        } else {
            return false;
        }
    }

While I believe the problem is fixed by:

    private boolean removeArray(Object value) {
        Object array = getValueArray();
        if (array == null) {
            return false;
        }
        Object convertedValue = convert(value);

        int len = Array.getLength(array);
        int j = 0;
        Object currValue = null;
        boolean found = false;
        for (int i = 0; i < len; i++) {
            currValue = Array.get(array, i);
            if (found || !currValue.equals(convertedValue)) {
                if (j != i) {
                    Array.set(array, j, currValue);
                }
                j++;
            } else {
                found = true;
            }
        }

        if (j != len) {
            Object newArray = null;
            if (j > 0) {
                Class componentType =
                    this.getMethod.getReturnType().getComponentType();
                newArray = Array.newInstance(componentType, j);
                System.arraycopy(array, 0, newArray, 0, j);
            }
            try {
                this.setMethod.invoke(this.obj, new Object[] {newArray});
            } catch (Exception e) {
                throw handleException(e);
            }
            return true;
        } else {
            return false;
        }
    }

I actually prefer:


    private boolean removeArray(Object value) {
        Object array = getValueArray();
        if (array == null) {
            return false;
        }
        Object convertedValue = convert(value);

        int len = Array.getLength(array);
        int j = 0;
        Object currValue = null;
        for (j = 0; j < len; j++) {
            currValue = Array.get(array, j);
            if (currValue.equals(convertedValue)) {
                break;
            }
        }

        if (j != len) {
            len--;	// new array is one shorter
            Object newArray = null;
            if (len > 0) {
                Class componentType =
                    this.getMethod.getReturnType().getComponentType();
                newArray = Array.newInstance(componentType, len);
                if(j > 0) {
                    System.arraycopy(array, 0, newArray, 0, j);
                }
                if(j < len) {
                    System.arraycopy(array, j+1, newArray, j, len-j);
                }
            }
            try {
                this.setMethod.invoke(this.obj, new Object[] {newArray});
            } catch (Exception e) {
                throw handleException(e);
            }
            return true;
        } else {
            return false;
        }
    }
------- Comment #1 From 2005-05-09 01:28:21 -------
Committed the fix and a test case (to trunk and globus_4_0_branch). Thanks!