View Javadoc

1   /*
2    *  Copyright 2003-2004 The Apache Software Foundation
3    *
4    *  Licensed under the Apache License, Version 2.0 (the "License");
5    *  you may not use this file except in compliance with the License.
6    *  You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *  Unless required by applicable law or agreed to in writing, software
11   *  distributed under the License is distributed on an "AS IS" BASIS,
12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *  See the License for the specific language governing permissions and
14   *  limitations under the License.
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 }