2015-01-28 3 views
1

Вызов ListDataProvider.getList(). Remove (...) не использует KeyProvider, переданный в конструкторе. Это ошибка GWT или она должна работать так? Ниже я приложил соответствующий модульный тест.ListDataProvider.getList(). Remove не использует KeyProvider

Спасибо вам,

TestVO ri1 = new TestVO(); 
    ri1.setId(null); 
    ri1.setName("msg1"); 
    TestVO ri2 = new TestVO(); 
    ri2.setId(null); 
    ri2.setName("msg2"); 
    TestVO ri3 = new TestVO(); 
    ri3.setId(null); 
    ri3.setName("msg2"); 

    ListDataProvider<TestVO> ldp = new ListDataProvider<>(new ProvidesKey<TestVO>() { 
     @Override 
     public Object getKey(TestVO pItem) { 
     System.out.println("this never gets invoked"); 
     return pItem.getMessageType(); 
     } 
    }); 
    ldp.setList(Lists.newArrayList(ri1, ri2)); 

    ldp.getList().remove(ri3); 

    //this currently fails, actual size is 1 as it removes ri2 
    assertEquals(2, ldp.getList().size()); 

ответ

1

Нет, это не ошибка и не он не использует getKey реализации предоставленной вами для нахождения элемента в этом списке, так как этот метод используется для других операций. Голый со мной ...

ListDataProvider использует ListWrapper, который реализует интерфейс List и ListWrapper поддерживается обычный List, который держит свои объекты. У ListWrapper есть реализация для методов, которые вы используете (добавьте, установите, удалите и т. Д.), Которые управляют List, которые вы передали Lists.newArrayList(ri1, ri2).

Эта манипуляция осуществляется путем вызова, среди прочего, стандартных операций интерфейса List. Итак, то, что вызывается, чтобы определить, какой объект следует удалить, - это indexOf, который, скажем, ArrayList (это то, что вы проходите, так это то, что используется) использует (как и следовало ожидать) метод equalsTestVO, который в случае, если вы 't overriden - это тот, который вы можете найти в классе Object.

Способ getKey, который вы предоставляете, используется для идентификации строки внутри списка строк (внутри используемого вами дисплея, например DataGrid). Это можно найти в AbstractDataProvider. Этот метод, который вызывает ваш метод, вызывается другими методами (см. То, что я там сделал: P) повсюду, чтобы идентифицировать строку, которая требует определенных действий. Примером может служить обновление строки внутри DataGrid. Метод, который будет определять, какая строка была обновлена, - это метод, который вы предоставили. Поэтому, если ваша реализация не предоставляет уникальный ключ, у вас будет указатель на обновление для всех строк с одним и тем же ключом. Так что будь осторожен.

/** 
    * Get the key for a list item. The default implementation returns the item 
    * itself. 
    * 
    * @param item the list item 
    * @return the key that represents the item 
    */ 
    public Object getKey(T item) { 
    return keyProvider == null ? item : keyProvider.getKey(item); 
    } 

Реализация indexOf в ArrayList

public int indexOf(Object o) { 
    if (o == null) { 
     for (int i = 0; i < size; i++) 
      if (elementData[i]==null) 
       return i; 
    } else { 
     for (int i = 0; i < size; i++) 
      if (o.equals(elementData[i])) 
       return i; 
    } 
    return -1; 
} 

Это РЕАЛИЗАЦИЯ из GWT

/** 
* Construct a new {@link ListWrapper} that delegates flush calls to the 
* specified delegate. 
* 
* @param list the list to wrap 
* @param delegate the delegate 
* @param offset the offset of this list 
*/ 
private ListWrapper(List<T> list, ListWrapper delegate, int offset) { 
    this.list = list; 
    this.delegate = delegate; 
    this.offset = offset; 
} 

@Override 
public void add(int index, T element) { 
    try { 
    list.add(index, element); 
    minModified = Math.min(minModified, index); 
    maxModified = size(); 
    modified = true; 
    flush(); 
    } catch (IndexOutOfBoundsException e) { 
    throw new IndexOutOfBoundsException(e.getMessage()); 
    } 
} 
@Override 
public T remove(int index) { 
    try { 
    T toRet = list.remove(index); 
    minModified = Math.min(minModified, index); 
    maxModified = size(); 
    modified = true; 
    flush(); 
    return toRet; 
    } catch (IndexOutOfBoundsException e) { 
    throw new IndexOutOfBoundsException(e.getMessage()); 
    } 
} 

@Override 
public boolean remove(Object o) { 
    int index = indexOf(o); 
    if (index == -1) { 
    return false; 
    } 
    remove(index); 
    return true; 
} 

public void setList(List<T> listToWrap) { 
    listWrapper = new ListWrapper(listToWrap); 
    listWrapper.minModified = 0; 
    listWrapper.maxModified = listWrapper.size(); 
    listWrapper.modified = true; 
    flush(); 
} 

public List<T> getList() { 
    return listWrapper; 
}