1 package hudson.util; 2 3 import com.thoughtworks.xstream.alias.CannotResolveClassException; 4 import com.thoughtworks.xstream.converters.Converter; 5 import com.thoughtworks.xstream.converters.MarshallingContext; 6 import com.thoughtworks.xstream.converters.UnmarshallingContext; 7 import com.thoughtworks.xstream.converters.collections.AbstractCollectionConverter; 8 import com.thoughtworks.xstream.io.HierarchicalStreamReader; 9 import com.thoughtworks.xstream.io.HierarchicalStreamWriter; 10 import com.thoughtworks.xstream.mapper.Mapper; 11 12 import java.util.ArrayList ; 13 import java.util.Collections ; 14 import java.util.Iterator ; 15 import java.util.List ; 16 import java.util.Collection ; 17 18 27 public class CopyOnWriteList<E> implements Iterable <E> { 28 private volatile List <? extends E> core; 29 30 public CopyOnWriteList(List <E> core) { 31 this(core,false); 32 } 33 34 private CopyOnWriteList(List <E> core, boolean noCopy) { 35 this.core = noCopy ? core : new ArrayList <E>(core); 36 } 37 38 public CopyOnWriteList() { 39 this.core = Collections.emptyList(); 40 } 41 42 public synchronized void add(E e) { 43 List <E> n = new ArrayList <E>(core); 44 n.add(e); 45 core = n; 46 } 47 48 55 public synchronized boolean remove(E e) { 56 List <E> n = new ArrayList <E>(core); 57 boolean r = n.remove(e); 58 core = n; 59 return r; 60 } 61 62 67 public Iterator <E> iterator() { 68 final Iterator <? extends E> itr = core.iterator(); 69 return new Iterator <E>() { 70 public boolean hasNext() { 71 return itr.hasNext(); 72 } 73 74 public E next() { 75 return itr.next(); 76 } 77 78 public void remove() { 79 throw new UnsupportedOperationException (); 80 } 81 }; 82 } 83 84 87 public void replaceBy(CopyOnWriteList<? extends E> that) { 88 this.core = that.core; 89 } 90 91 94 public void replaceBy(Collection <? extends E> that) { 95 this.core = new ArrayList <E>(that); 96 } 97 98 public E[] toArray(E[] array) { 99 return core.toArray(array); 100 } 101 102 public void addAllTo(Collection <? super E> dst) { 103 dst.addAll(core); 104 } 105 106 109 public static final class ConverterImpl extends AbstractCollectionConverter { 110 public ConverterImpl(Mapper mapper) { 111 super(mapper); 112 } 113 114 public boolean canConvert(Class type) { 115 return type==CopyOnWriteList.class; 116 } 117 118 public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { 119 for (Object o : (CopyOnWriteList) source) 120 writeItem(o, context, writer); 121 } 122 123 @SuppressWarnings ("unchecked") 124 public CopyOnWriteList unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { 125 List items = new ArrayList (); 127 while (reader.hasMoreChildren()) { 128 reader.moveDown(); 129 try { 130 Object item = readItem(reader, context, items); 131 items.add(item); 132 } catch (CannotResolveClassException e) { 133 System.err.println("failed to locate class: "+e); 134 } 135 reader.moveUp(); 136 } 137 138 return new CopyOnWriteList(items,true); 139 } 140 } 141 } 142 | Popular Tags |