Issue with ThreadProxyEventList.addAll(int, Collection)

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Issue with ThreadProxyEventList.addAll(int, Collection)

jh-21
Hi,

there is an issue with ThreadProxyEventList.addAll(int,Collection) that
affects all derived implementations. Using addAll with a number of
elements so that the original list's end is crossed during insertion of
the provided elements, the result is not correct. The following test
case demonstrates this issue:

public class TestThreadProxyList {
   private static class HandCrankedTPEL<E> extends ThreadProxyEventList<E> {
     public HandCrankedTPEL(EventList<E> source) {
       super(source);
     }

     private Queue<Runnable> updates = new LinkedList<Runnable>();

     @Override
     protected void schedule(Runnable runnable, boolean deferred) {
       updates.add(runnable);
     }

     public void crankUpdates() {
       Runnable r;
       while ((r = updates.poll()) != null)
         r.run();
     }
   }

   @Test
   public void demonstrateAddAllIssue() throws Exception {
     BasicEventList<String> src = new BasicEventList<String>();
     src.add("A");
     src.add("B");

     HandCrankedTPEL<String> tpel = new HandCrankedTPEL<String>(src);
     tpel.addAll(1, Arrays.asList("1", "2"));

     tpel.crankUpdates();

     // this will fail: expected:<[A, 1, 2, B]> but was:<[A, 1, B, 2]>
     Assert.assertEquals(Arrays.asList("A", "1", "2", "B"), tpel);
   }
}

The reason is that the addAll() implementation in TransformedList uses
the proxied list's size() (the latter is overridden), but actually works
on the source list. I might be horribly wrong here, but I think the
correct thing to do is to simply delegate the whole addAll-business to
the source list for all TPELs like this:

public abstract class ThreadProxyEventList<E> extends TransformedList<E,
E> implements RandomAccess {
   ...
   @Override
   public boolean addAll(int index, Collection<? extends E> values) {
     // just delegate everything to the source list
     return source.addAll(index, values);
   }
}

Joerg



---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]