View Javadoc
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.collections4;
18  
19  import static org.junit.jupiter.api.Assertions.assertEquals;
20  import static org.junit.jupiter.api.Assertions.assertNotNull;
21  import static org.junit.jupiter.api.Assertions.assertNotSame;
22  import static org.junit.jupiter.api.Assertions.assertNull;
23  import static org.junit.jupiter.api.Assertions.assertSame;
24  import static org.junit.jupiter.api.Assertions.assertThrows;
25  import static org.junit.jupiter.api.Assertions.assertTrue;
26  
27  import java.io.IOException;
28  import java.io.Serializable;
29  import java.util.Date;
30  import java.util.TimeZone;
31  
32  import org.apache.commons.collections4.functors.ConstantFactory;
33  import org.apache.commons.collections4.functors.ExceptionFactory;
34  import org.junit.jupiter.api.Test;
35  
36  /**
37   * Tests the org.apache.commons.collections.FactoryUtils class.
38   */
39  public class FactoryUtilsTest {
40  
41      public static class Mock1 {
42          private final int iVal;
43          public Mock1(final int val) {
44              iVal = val;
45          }
46          public Mock1(final Mock1 mock) {
47              iVal = mock.iVal;
48          }
49          @Override
50          public boolean equals(final Object obj) {
51              if (obj instanceof Mock1 && iVal == ((Mock1) obj).iVal) {
52                  return true;
53              }
54              return false;
55          }
56          @Override
57          public int hashCode() { // please Findbugs
58              return super.hashCode();
59          }
60      }
61  
62      public static class Mock2 implements Serializable {
63          /**
64           * Generated serial version ID.
65           */
66          private static final long serialVersionUID = 4899282162482588924L;
67          private final Object iVal;
68          public Mock2(final Object val) {
69              iVal = val;
70          }
71          @Override
72          public boolean equals(final Object obj) {
73              if (obj instanceof Mock2 && iVal == ((Mock2) obj).iVal) {
74                  return true;
75              }
76              return false;
77          }
78          @Override
79          public int hashCode() { // please Findbugs
80              return super.hashCode();
81          }
82      }
83  
84      public static class Mock3 {
85          private static int cCounter;
86          private final int iVal;
87          public Mock3() {
88              iVal = cCounter++;
89          }
90          public int getValue() {
91              return iVal;
92          }
93      }
94  
95      @Test
96      public void testConstantFactoryConstant() {
97          final Integer constant = Integer.valueOf(9);
98          final Factory<Integer> factory = FactoryUtils.constantFactory(constant);
99          assertNotNull(factory);
100         final Integer created = factory.create();
101         assertSame(constant, created);
102     }
103 
104     @Test
105     public void testConstantFactoryNull() {
106         final Factory<Object> factory = FactoryUtils.constantFactory(null);
107         assertNotNull(factory);
108         final Object created = factory.create();
109         assertNull(created);
110     }
111 
112     @Test
113     public void testExceptionFactory() {
114         assertNotNull(FactoryUtils.exceptionFactory());
115         assertSame(FactoryUtils.exceptionFactory(), FactoryUtils.exceptionFactory());
116 
117         assertThrows(FunctorException.class, () -> FactoryUtils.exceptionFactory().create());
118     }
119 
120     @Test
121     public void testInstantiateFactoryComplex() {
122         TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
123         // 2nd Jan 1970
124         final Factory<Date> factory = FactoryUtils.instantiateFactory(Date.class,
125             new Class[] {Integer.TYPE, Integer.TYPE, Integer.TYPE},
126             new Object[] {Integer.valueOf(70), Integer.valueOf(0), Integer.valueOf(2)});
127         assertNotNull(factory);
128         final Date created = factory.create();
129         // long time of 1 day (== 2nd Jan 1970)
130         assertEquals(new Date(1000 * 60 * 60 * 24), created);
131     }
132 
133     @Test
134     public void testInstantiateFactoryMismatch() {
135         assertThrows(IllegalArgumentException.class, () -> FactoryUtils.instantiateFactory(Date.class, null, new Object[] {null}));
136     }
137 
138     @Test
139     public void testInstantiateFactoryNoConstructor() {
140         assertThrows(IllegalArgumentException.class, () -> FactoryUtils.instantiateFactory(Date.class, new Class[] {Long.class}, new Object[] {null}));
141     }
142 
143     @Test
144     public void testInstantiateFactoryNull() {
145         assertThrows(NullPointerException.class, () -> FactoryUtils.instantiateFactory(null));
146     }
147 
148     @Test
149     public void testInstantiateFactorySimple() {
150         final Factory<Mock3> factory = FactoryUtils.instantiateFactory(Mock3.class);
151         assertNotNull(factory);
152         Mock3 created = factory.create();
153         assertEquals(0, created.getValue());
154         created = factory.create();
155         assertEquals(1, created.getValue());
156     }
157 
158     @Test
159     public void testNullFactory() {
160         final Factory<Object> factory = FactoryUtils.nullFactory();
161         assertNotNull(factory);
162         final Object created = factory.create();
163         assertNull(created);
164     }
165 
166     @Test
167     public void testPrototypeFactoryNull() {
168         assertSame(ConstantFactory.NULL_INSTANCE, FactoryUtils.prototypeFactory(null));
169     }
170 
171     @Test
172     public void testPrototypeFactoryPublicBad() {
173         final Object proto = new Object();
174         assertThrows(IllegalArgumentException.class, () -> FactoryUtils.prototypeFactory(proto));
175     }
176 
177     @Test
178     public void testPrototypeFactoryPublicCloneMethod() throws Exception {
179         final Date proto = new Date();
180         final Factory<Date> factory = FactoryUtils.prototypeFactory(proto);
181         assertNotNull(factory);
182         final Date created = factory.create();
183         assertNotSame(proto, created);
184         assertEquals(proto, created);
185     }
186 
187     @Test
188     public void testPrototypeFactoryPublicCopyConstructor() throws Exception {
189         final Mock1 proto = new Mock1(6);
190         final Factory<Object> factory = FactoryUtils.<Object>prototypeFactory(proto);
191         assertNotNull(factory);
192         final Object created = factory.create();
193         assertNotSame(proto, created);
194         assertEquals(proto, created);
195     }
196 
197     @Test
198     public void testPrototypeFactoryPublicSerialization() throws Exception {
199         final Integer proto = 9;
200         final Factory<Integer> factory = FactoryUtils.prototypeFactory(proto);
201         assertNotNull(factory);
202         final Integer created = factory.create();
203         assertNotSame(proto, created);
204         assertEquals(proto, created);
205     }
206 
207     @Test
208     public void testPrototypeFactoryPublicSerializationError() {
209         final Mock2 proto = new Mock2(new Object());
210         final Factory<Object> factory = FactoryUtils.<Object>prototypeFactory(proto);
211         assertNotNull(factory);
212 
213         final FunctorException thrown = assertThrows(FunctorException.class, () -> factory.create());
214         assertTrue(thrown.getCause() instanceof IOException);
215     }
216 
217     /**
218      * Test that all Factory singletons hold singleton pattern in
219      * serialization/deserialization process.
220      */
221     @Test
222     public void testSingletonPatternInSerialization() {
223         final Object[] singletons = {
224             ExceptionFactory.INSTANCE,
225         };
226 
227         for (final Object original : singletons) {
228             TestUtils.assertSameAfterSerialization(
229                     "Singleton pattern broken for " + original.getClass(),
230                     original
231             );
232         }
233     }
234 
235 }