    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>Instantiate - 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 * <p>
    035 * Since v4.1 only factories which are considered to be safe are
    036 * Serializable. Factories considered to be unsafe for serialization are:
    037 * <ul>
    038 * <li>Prototype
    039 * <li>Instantiate
    040 * </ul>
    041 *
    042 * @since 3.0
    043 */
    044public class FactoryUtils {
    045
    046    /**
    047     * This class is not normally instantiated.
    048     */
    049    private FactoryUtils() {}
    050
    051    /**
    052     * Gets a Factory that always throws an exception.
    053     * This could be useful during testing as a placeholder.
    054     *
    055     * @see org.apache.commons.collections4.functors.ExceptionFactory
    056     *
    057     * @param <T> the type that the factory creates
    058     * @return the factory
    059     */
    060    public static <T> Factory<T> exceptionFactory() {
    061        return ExceptionFactory.<T>exceptionFactory();
    062    }
    063
    064    /**
    065     * Gets a Factory that will return null each time the factory is used.
    066     * This could be useful during testing as a placeholder.
    067     *
    068     * @see org.apache.commons.collections4.functors.ConstantFactory
    069     * @param <T> the "type" of null object the factory should return.
    070     * @return the factory
    071     */
    072    public static <T> Factory<T> nullFactory() {
    073        return ConstantFactory.<T>constantFactory(null);
    074    }
    075
    076    /**
    077     * Creates a Factory that will return the same object each time the factory
    078     * is used. No check is made that the object is immutable. In general, only
    079     * immutable objects should use the constant factory. Mutable objects should
    080     * use the prototype factory.
    081     *
    082     * @see org.apache.commons.collections4.functors.ConstantFactory
    083     *
    084     * @param <T> the type that the factory creates
    085     * @param constantToReturn  the constant object to return each time in the factory
    086     * @return the <code>constant</code> factory.
    087     */
    088    public static <T> Factory<T> constantFactory(final T constantToReturn) {
    089        return ConstantFactory.constantFactory(constantToReturn);
    090    }
    091
    092    /**
    093     * Creates a Factory that will return a clone of the same prototype object
    094     * each time the factory is used. The prototype will be cloned using one of these
    095     * techniques (in order):
    096     *
    097     * <ul>
    098     * <li>public clone method</li>
    099     * <li>public copy constructor</li>
    100     * <li>serialization clone</li>
    101     * </ul>
    102     *
    103     * @see org.apache.commons.collections4.functors.PrototypeFactory
    104     *
    105     * @param <T> the type that the factory creates
    106     * @param prototype  the object to clone each time in the factory
    107     * @return the <code>prototype</code> factory, or a {@link ConstantFactory#NULL_INSTANCE} if
    108     * the {@code prototype} is {@code null}
    109     * @throws IllegalArgumentException if the prototype cannot be cloned
    110     */
    111    public static <T> Factory<T> prototypeFactory(final T prototype) {
    112        return PrototypeFactory.<T>prototypeFactory(prototype);
    113    }
    114
    115    /**
    116     * Creates a Factory that can create objects of a specific type using
    117     * a no-args constructor.
    118     *
    119     * @see org.apache.commons.collections4.functors.InstantiateFactory
    120     *
    121     * @param <T> the type that the factory creates
    122     * @param classToInstantiate  the Class to instantiate each time in the factory
    123     * @return the <code>reflection</code> factory
    124     * @throws NullPointerException if the classToInstantiate is null
    125     */
    126    public static <T> Factory<T> instantiateFactory(final Class<T> classToInstantiate) {
    127        return InstantiateFactory.instantiateFactory(classToInstantiate, null, null);
    128    }
    129
    130    /**
    131     * Creates a Factory that can create objects of a specific type using
    132     * the arguments specified to this method.
    133     *
    134     * @see org.apache.commons.collections4.functors.InstantiateFactory
    135     *
    136     * @param <T> the type that the factory creates
    137     * @param classToInstantiate  the Class to instantiate each time in the factory
    138     * @param paramTypes  parameter types for the constructor, can be null
    139     * @param args  the arguments to pass to the constructor, can be null
    140     * @return the <code>reflection</code> factory
    141     * @throws NullPointerException if the classToInstantiate is null
    142     * @throws IllegalArgumentException if the paramTypes and args don't match
    143     * @throws IllegalArgumentException if the constructor doesn't exist
    144     */
    145    public static <T> Factory<T> instantiateFactory(final Class<T> classToInstantiate, final Class<?>[] paramTypes,
    146                                                    final Object[] args) {
    147        return InstantiateFactory.instantiateFactory(classToInstantiate, paramTypes, args);
    148    }
    149
    150}