LOGGER.log(Level.FINE, "replacing {0} with {1}", newObject[] {o, fields});
@OverridepublicbooleanhasNext() {
return cursor != list.size();
}
@OverridepublicListenableFuture<?>rehydrate() {
ReflectionProvider rp =Jenkins.XSTREAM2.getReflectionProvider();
Object o = rp.newInstance(type);
for (Map.Entry<Class,Map<String,Object>> entry : fields.entrySet()) {
Class definedIn = entry.getKey();
for (Map.Entry<String,Object> entry2 : entry.getValue().entrySet()) {
String fieldName = entry2.getKey();
Object value = entry2.getValue();
rp.writeField(o, fieldName, value, definedIn);
if (fieldName.equals("this$0")) {
try {
Field f =AbstractList.class.getDeclaredField("modCount"); // TODO if not handling only ArrayList.Itr, search in superclasses
f.setAccessible(true);
int modCount = f.getInt(value);
LOGGER.log(Level.FINER, "found a modCount={0}", modCount);
rp.writeField(o, "expectedModCount", modCount, type); // TODO search in superclasses
} catch (Exception x) {
returnFutures.immediateFailedFuture(x);
}
}
@OverridepublicEnext() {
try {
int i = cursor;
E next = list.get(i);
lastRet = i;
cursor = i +1;
return next;
} catch (IndexOutOfBoundsException e) {
thrownewNoSuchElementException();
}
}
@Overridepublicvoidremove() {
if (lastRet <0) {
thrownewIllegalStateException();
}
try {
list.remove(lastRet);
if (lastRet < cursor) {
cursor--;
}
lastRet =-1;
} catch (IndexOutOfBoundsException e) {
thrownewConcurrentModificationException();
}
LOGGER.log(Level.FINE, "reconstructed {0}", o);
returnFutures.immediateFuture(o);
}
}
/** Serializable replacement for {@link List#iterator}. */
publicstatic<E>Iterator<E>iterator(List<E>list) {
// TODO !Caller.isAsynchronous(list, "iterator") && !Caller.isAsynchronous(IteratorHack.class, "iterator", list) when used from a Java 5-style for-loop, so not sure how to sidestep this when running in @NonCPS
returnnewItr<>(list);
}
/** Serializable replacement for {@link Map#entrySet}. */