View Javadoc

1   /*
2    *  Copyright 2002-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.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 }