1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package net.sf.collections15.functors.factory;
17
18 import net.sf.collections15.Factory;
19
20
21 /***
22 * <code>FactoryUtils</code> provides reference implementations and utilities
23 * for the <code>Factory</code> functor interface. The supplied factories are:
24 * <ul> <li>Constant - always returns the same object.</li> <li>Exception -
25 * always throws an exception.</li> <li>Instantiate - creates objects using
26 * reflection.</li> <li>Null - always returns null.</li> <li>Prototype - clones
27 * a specified object.</li> </ul> All the supplied factories are Serializable.
28 *
29 * @author Stephen Colebourne
30 * @author Chris Lambrou (port to Java 5.0)
31 * @since Collections15 1.0
32 */
33 public class FactoryUtils
34 {
35
36 /***
37 * Protected constructor prevents direct instantiation, but allows users to
38 * extend this library to provide their own augmented static library class.
39 */
40 protected FactoryUtils()
41 {
42 }
43
44 /***
45 * Returns a <code>Factory</code> that always throws an exception. This
46 * could be useful during testing as a placeholder.
47 *
48 * @return A <code>Factory</code> whose {@link Factory#create() create}
49 * method always throws an exception.
50 *
51 * @see ExceptionFactory
52 */
53 public static <T> Factory<T> exceptionFactory()
54 {
55 return ExceptionFactory.getInstance();
56 }
57
58 /***
59 * Returns a <code>Factory</code> that will return <code>null</code> each
60 * time the <code>Factory</code> is used. This could be useful during
61 * testing as a placeholder.
62 *
63 * @return A <code>Factory</code> whose {@link Factory#create() create}
64 * method always return <code>null</code>.
65 *
66 * @see ConstantFactory
67 */
68 public static <T> Factory<T> nullFactory()
69 {
70 return ConstantFactory.getInstance(null);
71 }
72
73 /***
74 * Returns a <code>Factory</code> that will return the same object each time
75 * the <code>Factory</code> is used. No check is made that the object is
76 * immutable. In general, only immutable objects should use
77 * <code>constantFactory</code>. Mutable objects should use {@link
78 * #prototypeFactory} instead.
79 *
80 * @param constantToReturn The constant object to return each time the
81 * <code>Factory</code> is used.
82 *
83 * @return A <code>Factory</code> whose {@link Factory#create() create}
84 * method always returns the specified constant.
85 *
86 * @see ConstantFactory
87 */
88 public static <T> Factory<T> constantFactory(T constantToReturn)
89 {
90 return ConstantFactory.getInstance(constantToReturn);
91 }
92
93 /***
94 * Returns a <code>Factory</code> that will return a copy of a specified
95 * prototype object each time the factory is used.
96 *
97 * @param prototype The object to copy each time the <code>Factory</code> is
98 * used. The copying technique used by the {@link
99 * Factory#create() create} method of the returned
100 * <code>Factory</code> varies depending on the type of the
101 * prototype object. In order, the techniques employed are
102 * as follows.
103 * <p/>
104 * If the object is <code>null</code> or of a known
105 * immutable type, the <code>create</code> method will
106 * simply return the prototype object itself.
107 * <p/>
108 * If the object is <code>Cloneable</code>, the
109 * <code>create</code> method will use the object's
110 * <code>clone</code> method to create a copy of the
111 * object.
112 * <p/>
113 * If the object's class has a copy-constructor, the
114 * <code>create</code> method will use this to create a
115 * copy of the object.
116 * <p/>
117 * If the object is <code>Serializable</code>, the
118 * <code>create</code> method will serialize the object to
119 * a byte array, then deserialize it to create a copy of
120 * the object.
121 * <p/>
122 * Finally, if none of these techniques can be employed,
123 * this method will throw an <code>IllegalArgumentException</code>.
124 *
125 * @return A <code>Factory</code> whose {@link Factory#create() create}
126 * method returns a copy of the prototype object.
127 *
128 * @throws IllegalArgumentException Thrown if none of the techniques
129 * described can be applied to the
130 * prototype object.
131 * @see PrototypeFactory
132 */
133 public static <T> Factory<T> prototypeFactory(T prototype)
134 {
135 return PrototypeFactory.getInstance(prototype);
136 }
137
138 /***
139 * Returns a <code>Factory</code> that can create objects of a specific type
140 * using a no-args constructor.
141 *
142 * @param classToInstantiate the <code>Class</code> to instantiate each time
143 * the <code>Factory</code> is used.
144 *
145 * @return A <code>Factory</code> whose {@link Factory#create() create}
146 * method returns an instance of the specified class, using the
147 * parameterless constructor of the class.
148 *
149 * @throws IllegalArgumentException Thrown if the specified class is
150 * <code>null</code>, or doesn't have a
151 * public, parameterless constructor.
152 * @see InstantiateFactory
153 */
154 public static <T> Factory<T> instantiateFactory(Class<? extends T> classToInstantiate)
155 {
156 return InstantiateFactory.getInstance(classToInstantiate);
157 }
158
159 /***
160 * Returns a <code>Factory</code> that can create objects of a specific type
161 * using the arguments specified to this method.
162 *
163 * @param classToInstantiate the <code>Class</code> to instantiate each time
164 * the <code>Factory</code> is used.
165 * @param paramTypes The parameter types for the constructor to be
166 * used.
167 * @param args The arguments to pass to the constructor.
168 *
169 * @return A <code>Factory</code> whose {@link Factory#create() create}
170 * method returns an instance of the specified class, using the
171 * specified arguments to pass to the constructor of the class.
172 *
173 * @throws IllegalArgumentException Thrown if the specified class is
174 * <code>null</code>, or deosn't have a
175 * public constructor with the specified
176 * parameter types.
177 * @throws IllegalArgumentException Thrown if either the <code>paramTypes</code>
178 * or <code>args</code> arrays are
179 * <code>null</code>, are of unequal
180 * length, or are otherwise invalid.
181 * @see InstantiateFactory
182 */
183 public static <T> Factory<T> instantiateFactory(Class<? extends T> classToInstantiate, Class[] paramTypes, Object[] args)
184 {
185 return InstantiateFactory.getInstance(classToInstantiate, paramTypes, args);
186 }
187
188 }