1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package net.sf.collections15.collection;
17
18 import java.util.ArrayList;
19 import java.util.Collection;
20 import java.util.List;
21
22 import net.sf.collections15.Transformer;
23
24
25 /***
26 * Decorates another <code>Collection</code> to transform objects that are added.
27 * <p>
28 * The add methods are affected by this class.
29 * Thus objects must be removed or searched for using their transformed form.
30 * For example, if the transformation converts Strings to Integers, you must
31 * use the Integer form to remove objects.
32 * <p>
33 * This class is Serializable from Commons Collections 3.1.
34 *
35 * @since Commons Collections 3.0
36 * @version $Revision: 1.1 $ $Date: 2005/05/25 21:25:42 $
37 *
38 * @author Stephen Colebourne
39 */
40 public class TransformedCollection<I, O> extends AbstractSerializableCollectionDecorator<Object> {
41
42 /*** Serialization version */
43 private static final long serialVersionUID = 3257288032699625529L;
44
45 /*** The transformer to use */
46 protected final Transformer<? super I, ? extends O> transformer;
47
48 /***
49 * Factory method to create a transforming collection.
50 * <p>
51 * If there are any elements already in the collection being decorated, they
52 * are NOT transformed.
53 *
54 * @param coll the collection to decorate, must not be null
55 * @param transformer the transformer to use for conversion, must not be null
56 * @return a new transformed collection
57 * @throws IllegalArgumentException if collection or transformer is null
58 */
59 public static <E,S> Collection<S> decorate(Collection<? extends S> coll, Transformer<? super E, ? extends S> transformer) {
60 return (Collection<S>) new TransformedCollection<E,S>(coll, transformer);
61 }
62
63
64 /***
65 * Constructor that wraps (not copies).
66 * <p>
67 * If there are any elements already in the collection being decorated, they
68 * are NOT transformed.
69 *
70 * @param coll the collection to decorate, must not be null
71 * @param transformer the transformer to use for conversion, must not be null
72 * @throws IllegalArgumentException if collection or transformer is null
73 */
74 protected TransformedCollection(Collection<? extends O> coll, Transformer<? super I, ? extends O> transformer) {
75 super( (Collection<Object>) coll );
76 if (transformer == null) {
77 throw new IllegalArgumentException("Transformer must not be null");
78 }
79 this.transformer = transformer;
80 }
81
82 /***
83 * Transforms an object.
84 * <p>
85 * The transformer itself may throw an exception if necessary.
86 *
87 * @param object the object to transform
88 * @return a transformed object
89 */
90 protected O transform(I object) {
91 return transformer.transform(object);
92 }
93
94 /***
95 * Transforms a collection.
96 * <p>
97 * The transformer itself may throw an exception if necessary.
98 *
99 * @param coll the collection to transform
100 * @return a transformed object
101 */
102 protected Collection<O> transform(Collection<? extends I> coll) {
103 List<O> list = new ArrayList<O>(coll.size());
104 for( I input : coll ) {
105 list.add(transform(input));
106 }
107 return list;
108 }
109
110
111
112 /***
113 * First transform the given input then add the result to the collection
114 *
115 * @param input
116 * @return
117 */
118 public boolean add(Object input) {
119 O output = transform( (I) input );
120 return getCollection().add(output);
121 }
122
123 /***
124 * First transform all the elements of the input collection, then add the resulting
125 * collection to the collection.
126 *
127 * @param input
128 * @return
129 */
130 public boolean addAll(Collection<? extends Object> input) {
131 Collection<O> output = transform( (Collection<? extends I>) input );
132 return getCollection().addAll(output);
133 }
134
135
136 /***
137 * Add the given object to the collection without first transforming it.
138 *
139 * @since collections15
140 * @param object
141 * @return
142 */
143 public boolean addNoTransform(O object) {
144 return super.add(object);
145 }
146
147 /***
148 * Add the given collection without first transforming it.
149 *
150 * @since collections15
151 * @param input
152 * @return
153 */
154 public boolean addAllNoTransform(Collection<? extends O> coll) {
155 return super.addAll(coll);
156 }
157
158 }