Bugzilla – Bug 3302
ReflectionResourceProperty inconsistent handling on remove on Array type
Last modified: 2005-05-09 01:28:21
You need to log in before you can comment on or make changes to this bug.
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; } }
Committed the fix and a test case (to trunk and globus_4_0_branch). Thanks!