1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one or more
3    *  contributor license agreements.  See the NOTICE file distributed with
4    *  this work for additional information regarding copyright ownership.
5    *  The ASF licenses this file to You under the Apache License, Version 2.0
6    *  (the "License"); you may not use this file except in compliance with
7    *  the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   *  Unless required by applicable law or agreed to in writing, software
12   *  distributed under the License is distributed on an "AS IS" BASIS,
13   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   *  See the License for the specific language governing permissions and
15   *  limitations under the License.
16   */
17  package org.apache.commons.collections;
18  
19  import java.io.ByteArrayInputStream;
20  import java.io.ByteArrayOutputStream;
21  import java.io.IOException;
22  import java.io.NotSerializableException;
23  import java.io.ObjectInputStream;
24  import java.io.ObjectOutputStream;
25  import java.io.Serializable;
26  import java.util.Date;
27  import java.util.TimeZone;
28  
29  import junit.framework.Test;
30  import junit.framework.TestSuite;
31  import junit.textui.TestRunner;
32  
33  import org.apache.commons.collections.functors.ConstantFactory;
34  
35  /**
36   * Tests the org.apache.commons.collections.FactoryUtils class.
37   * 
38   * @since Commons Collections 3.0
39   * @version $Revision: 646780 $ $Date: 2008-04-10 13:48:07 +0100 (Thu, 10 Apr 2008) $
40   *
41   * @author Stephen Colebourne
42   */
43  public class TestFactoryUtils extends junit.framework.TestCase {
44  
45      /**
46       * Construct
47       */
48      public TestFactoryUtils(String name) {
49          super(name);
50      }
51  
52      /**
53       * Main.
54       * @param args
55       */    
56      public static void main(String[] args) {
57          TestRunner.run(suite());
58      }
59  
60      /**
61       * Return class as a test suite.
62       */
63      public static Test suite() {
64          return new TestSuite(TestFactoryUtils.class);
65      }
66  
67      /**
68       * Set up instance variables required by this test case.
69       */
70      public void setUp() {
71      }
72  
73      /**
74       * Tear down instance variables required by this test case.
75       */
76      public void tearDown() {
77      }
78  
79      // exceptionFactory
80      //------------------------------------------------------------------
81  
82      public void testExceptionFactory() {
83          assertNotNull(FactoryUtils.exceptionFactory());
84          assertSame(FactoryUtils.exceptionFactory(), FactoryUtils.exceptionFactory());
85          try {
86              FactoryUtils.exceptionFactory().create();
87          } catch (FunctorException ex) {
88              try {
89                  FactoryUtils.exceptionFactory().create();
90              } catch (FunctorException ex2) {
91                  return;
92              }
93          }
94          fail();
95      }
96      
97      // nullFactory
98      //------------------------------------------------------------------
99      
100     public void testNullFactory() {
101         Factory factory = FactoryUtils.nullFactory();
102         assertNotNull(factory);
103         Object created = factory.create();
104         assertNull(created);
105     }
106 
107     // constantFactory
108     //------------------------------------------------------------------
109     
110     public void testConstantFactoryNull() {
111         Factory factory = FactoryUtils.constantFactory(null);
112         assertNotNull(factory);
113         Object created = factory.create();
114         assertNull(created);
115     }
116 
117     public void testConstantFactoryConstant() {
118         Integer constant = new Integer(9);
119         Factory factory = FactoryUtils.constantFactory(constant);
120         assertNotNull(factory);
121         Object created = factory.create();
122         assertSame(constant, created);
123     }
124 
125     // prototypeFactory
126     //------------------------------------------------------------------
127     
128     public void testPrototypeFactoryNull() {
129         assertSame(ConstantFactory.NULL_INSTANCE, FactoryUtils.prototypeFactory(null));
130     }
131 
132     public void testPrototypeFactoryPublicCloneMethod() throws Exception {
133         Date proto = new Date();
134         Factory factory = FactoryUtils.prototypeFactory(proto);
135         assertNotNull(factory);
136         Object created = factory.create();
137         assertTrue(proto != created);
138         assertEquals(proto, created);
139         
140         // check serialisation works
141         ByteArrayOutputStream buffer = new ByteArrayOutputStream();
142         ObjectOutputStream out = new ObjectOutputStream(buffer);
143         out.writeObject(factory);
144         out.close();
145         ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(buffer.toByteArray()));
146         Object dest = in.readObject();
147         in.close();
148     }
149 
150     public void testPrototypeFactoryPublicCopyConstructor() throws Exception {
151         Mock1 proto = new Mock1(6);
152         Factory factory = FactoryUtils.prototypeFactory(proto);
153         assertNotNull(factory);
154         Object created = factory.create();
155         assertTrue(proto != created);
156         assertEquals(proto, created);
157         
158         // check serialisation works
159         ByteArrayOutputStream buffer = new ByteArrayOutputStream();
160         ObjectOutputStream out = new ObjectOutputStream(buffer);
161         try {
162             out.writeObject(factory);
163         } catch (NotSerializableException ex) {
164             out.close();
165         }
166         factory = FactoryUtils.prototypeFactory(new Mock2("S"));
167         buffer = new ByteArrayOutputStream();
168         out = new ObjectOutputStream(buffer);
169         out.writeObject(factory);
170         out.close();
171         ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(buffer.toByteArray()));
172         Object dest = in.readObject();
173         in.close();
174     }
175 
176     public void testPrototypeFactoryPublicSerialization() throws Exception {
177         Integer proto = new Integer(9);
178         Factory factory = FactoryUtils.prototypeFactory(proto);
179         assertNotNull(factory);
180         Object created = factory.create();
181         assertTrue(proto != created);
182         assertEquals(proto, created);
183         
184         // check serialisation works
185         ByteArrayOutputStream buffer = new ByteArrayOutputStream();
186         ObjectOutputStream out = new ObjectOutputStream(buffer);
187         out.writeObject(factory);
188         out.close();
189         ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(buffer.toByteArray()));
190         Object dest = in.readObject();
191         in.close();
192     }
193 
194     public void testPrototypeFactoryPublicSerializationError() {
195         Mock2 proto = new Mock2(new Object());
196         Factory factory = FactoryUtils.prototypeFactory(proto);
197         assertNotNull(factory);
198         try {
199             Object created = factory.create();
200             
201         } catch (FunctorException ex) {
202             assertTrue(ex.getCause() instanceof IOException);
203             return;
204         }
205         fail();
206     }
207 
208     public void testPrototypeFactoryPublicBad() {
209         Object proto = new Object();
210         try {
211             Factory factory = FactoryUtils.prototypeFactory(proto);
212             
213         } catch (IllegalArgumentException ex) {
214             return;
215         }
216         fail();
217     }
218 
219     public static class Mock1 {
220         private final int iVal;
221         public Mock1(int val) {
222             iVal = val;
223         }
224         public Mock1(Mock1 mock) {
225             iVal = mock.iVal;
226         }
227         public boolean equals(Object obj) {
228             if (obj instanceof Mock1) {
229                 if (iVal == ((Mock1) obj).iVal) {
230                     return true;
231                 }
232             }
233             return false;
234         }
235     }
236     
237     public static class Mock2 implements Serializable {
238         private final Object iVal;
239         public Mock2(Object val) {
240             iVal = val;
241         }
242         public boolean equals(Object obj) {
243             if (obj instanceof Mock2) {
244                 if (iVal == ((Mock2) obj).iVal) {
245                     return true;
246                 }
247             }
248             return false;
249         }
250     }
251     
252     public static class Mock3 {
253         private static int cCounter = 0;
254         private final int iVal;
255         public Mock3() {
256             iVal = cCounter++;
257         }
258         public int getValue() {
259             return iVal;
260         }
261     }
262     
263     // instantiateFactory
264     //------------------------------------------------------------------
265     
266     public void testInstantiateFactoryNull() {
267         try {
268             Factory factory = FactoryUtils.instantiateFactory(null);
269             
270         } catch (IllegalArgumentException ex) {
271             return;
272         }
273         fail();
274     }
275 
276     public void testInstantiateFactorySimple() {
277         Factory factory = FactoryUtils.instantiateFactory(Mock3.class);
278         assertNotNull(factory);
279         Object created = factory.create();
280         assertEquals(0, ((Mock3) created).getValue());
281         created = factory.create();
282         assertEquals(1, ((Mock3) created).getValue());
283     }
284 
285     public void testInstantiateFactoryMismatch() {
286         try {
287             Factory factory = FactoryUtils.instantiateFactory(Date.class, null, new Object[] {null});
288             
289         } catch (IllegalArgumentException ex) {
290             return;
291         }
292         fail();
293     }
294 
295     public void testInstantiateFactoryNoConstructor() {
296         try {
297             Factory factory = FactoryUtils.instantiateFactory(Date.class, new Class[] {Long.class}, new Object[] {null});
298             
299         } catch (IllegalArgumentException ex) {
300             return;
301         }
302         fail();
303     }
304 
305     public void testInstantiateFactoryComplex() {
306         TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
307         // 2nd Jan 1970
308         Factory factory = FactoryUtils.instantiateFactory(Date.class,
309             new Class[] {Integer.TYPE, Integer.TYPE, Integer.TYPE},
310             new Object[] {new Integer(70), new Integer(0), new Integer(2)});
311         assertNotNull(factory);
312         Object created = factory.create();
313         assertTrue(created instanceof Date);
314         // long time of 1 day (== 2nd Jan 1970)
315         assertEquals(new Date(1000 * 60 * 60 * 24), created);
316     }
317 
318 }