
hudson.util.RobustCollectionConverter Maven / Gradle / Ivy
package hudson.util;
import com.thoughtworks.xstream.alias.CannotResolveClassException;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.converters.collections.CollectionConverter;
import com.thoughtworks.xstream.converters.reflection.ReflectionProvider;
import com.thoughtworks.xstream.converters.reflection.SerializableConverter;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.mapper.Mapper;
import java.util.Collection;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* {@link CollectionConverter} that ignores {@link CannotResolveClassException}.
*
*
* This allows Hudson to load XML files that contain non-existent classes
* (the expected scenario is that those classes belong to plugins that were unloaded.)
*
* @author Kohsuke Kawaguchi
*/
public class RobustCollectionConverter extends CollectionConverter {
private final SerializableConverter sc;
public RobustCollectionConverter(Mapper mapper, ReflectionProvider reflectionProvider) {
super(mapper);
sc = new SerializableConverter(mapper,reflectionProvider);
}
public boolean canConvert(Class type) {
return super.canConvert(type) || type==CopyOnWriteArrayList.class;
}
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
// CopyOnWriteArrayList used to serialize as custom serialization,
// so read it in a compatible fashion.
String s = reader.getAttribute("serialization");
if(s!=null && s.equals("custom")) {
return sc.unmarshal(reader,context);
} else {
return super.unmarshal(reader, context);
}
}
protected void populateCollection(HierarchicalStreamReader reader, UnmarshallingContext context, Collection collection) {
while (reader.hasMoreChildren()) {
reader.moveDown();
try {
Object item = readItem(reader, context, collection);
collection.add(item);
} catch (CannotResolveClassException e) {
System.err.println("failed to locate class: "+e);
}
reader.moveUp();
}
}
}