001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.collections4;
018
019import org.apache.commons.collections4.functors.ConstantFactory;
020import org.apache.commons.collections4.functors.ExceptionFactory;
021import org.apache.commons.collections4.functors.InstantiateFactory;
022import org.apache.commons.collections4.functors.PrototypeFactory;
023
024/**
025 * <code>FactoryUtils</code> provides reference implementations and utilities
026 * for the Factory functor interface. The supplied factories are:
027 * <ul>
028 * <li>Prototype - clones a specified object
029 * <li>Reflection - creates objects using reflection
030 * <li>Constant - always returns the same object
031 * <li>Null - always returns null
032 * <li>Exception - always throws an exception
033 * </ul>
034 * All the supplied factories are Serializable.
035 *
036 * @since 3.0
037 * @version $Id: FactoryUtils.html 972421 2015-11-14 20:00:04Z tn $
038 */
039public class FactoryUtils {
040
041    /**
042     * This class is not normally instantiated.
043     */
044    private FactoryUtils() {}
045
046    /**
047     * Gets a Factory that always throws an exception.
048     * This could be useful during testing as a placeholder.
049     *
050     * @see org.apache.commons.collections4.functors.ExceptionFactory
051     *
052     * @param <T> the type that the factory creates
053     * @return the factory
054     */
055    public static <T> Factory<T> exceptionFactory() {
056        return ExceptionFactory.<T>exceptionFactory();
057    }
058
059    /**
060     * Gets a Factory that will return null each time the factory is used.
061     * This could be useful during testing as a placeholder.
062     *
063     * @see org.apache.commons.collections4.functors.ConstantFactory
064     * @param <T> the "type" of null object the factory should return.
065     * @return the factory
066     */
067    public static <T> Factory<T> nullFactory() {
068        return ConstantFactory.<T>constantFactory(null);
069    }
070
071    /**
072     * Creates a Factory that will return the same object each time the factory
073     * is used. No check is made that the object is immutable. In general, only
074     * immutable objects should use the constant factory. Mutable objects should
075     * use the prototype factory.
076     *
077     * @see org.apache.commons.collections4.functors.ConstantFactory
078     *
079     * @param <T> the type that the factory creates
080     * @param constantToReturn  the constant object to return each time in the factory
081     * @return the <code>constant</code> factory.
082     */
083    public static <T> Factory<T> constantFactory(final T constantToReturn) {
084        return ConstantFactory.constantFactory(constantToReturn);
085    }
086
087    /**
088     * Creates a Factory that will return a clone of the same prototype object
089     * each time the factory is used. The prototype will be cloned using one of these
090     * techniques (in order):
091     * <ul>
092     * <li>public clone method
093     * <li>public copy constructor
094     * <li>serialization clone
095     * <ul>
096     *
097     * @see org.apache.commons.collections4.functors.PrototypeFactory
098     *
099     * @param <T> the type that the factory creates
100     * @param prototype  the object to clone each time in the factory
101     * @return the <code>prototype</code> factory, or a {@link ConstantFactory#NULL_INSTANCE} if
102     * the {@code prototype} is {@code null}
103     * @throws IllegalArgumentException if the prototype cannot be cloned
104     */
105    public static <T> Factory<T> prototypeFactory(final T prototype) {
106        return PrototypeFactory.<T>prototypeFactory(prototype);
107    }
108
109    /**
110     * Creates a Factory that can create objects of a specific type using
111     * a no-args constructor.
112     *
113     * @see org.apache.commons.collections4.functors.InstantiateFactory
114     *
115     * @param <T> the type that the factory creates
116     * @param classToInstantiate  the Class to instantiate each time in the factory
117     * @return the <code>reflection</code> factory
118     * @throws IllegalArgumentException if the classToInstantiate is null
119     */
120    public static <T> Factory<T> instantiateFactory(final Class<T> classToInstantiate) {
121        return InstantiateFactory.instantiateFactory(classToInstantiate, null, null);
122    }
123
124    /**
125     * Creates a Factory that can create objects of a specific type using
126     * the arguments specified to this method.
127     *
128     * @see org.apache.commons.collections4.functors.InstantiateFactory
129     *
130     * @param <T> the type that the factory creates
131     * @param classToInstantiate  the Class to instantiate each time in the factory
132     * @param paramTypes  parameter types for the constructor, can be null
133     * @param args  the arguments to pass to the constructor, can be null
134     * @return the <code>reflection</code> factory
135     * @throws IllegalArgumentException if the classToInstantiate is null
136     * @throws IllegalArgumentException if the paramTypes and args don't match
137     * @throws IllegalArgumentException if the constructor doesn't exist
138     */
139    public static <T> Factory<T> instantiateFactory(final Class<T> classToInstantiate, final Class<?>[] paramTypes,
140                                                    final Object[] args) {
141        return InstantiateFactory.instantiateFactory(classToInstantiate, paramTypes, args);
142    }
143
144}