All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.openpojo.random.RandomFactory Maven / Gradle / Ivy

/*
 * Copyright (c) 2010-2018 Osman Shoukry
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied.
 *
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.openpojo.random;

import com.openpojo.log.Logger;
import com.openpojo.log.LoggerFactory;
import com.openpojo.random.exception.RandomGeneratorException;
import com.openpojo.random.service.RandomGeneratorService;
import com.openpojo.random.thread.GeneratedRandomValues;
import com.openpojo.reflection.Parameterizable;
import com.openpojo.registry.ServiceRegistrar;

/**
 * This factory is responsible for generating the random values using the registered RandomGenerator(s). 
* This Factory will automatically detect cyclic dependency and return null for the second time around.
*
* Simple Example
* If you have an Employee class that has the following constructor: *
 * {@code
 * public Employee(final String fullName, final Employee manager) {
 *   ...
 * }
 * }
 * 
* * And you created the random generator as follows: *
 * {@code
 * public Object doGenerate(Class type) {
 *     return new Employee(RandomFactory.getRandomValue(String.class),
 *                          (Employee) RandomFactory.getRandomValue(Employee.class));
 * }
 * }
 * 
* * This would potentially cause a stack over-flow since there is a cyclic dependency of Employee on itself. So to * prevent stack over-flow (which would occur by trying to create a manager for every manager), this Factory has built * in protection (using {@link GeneratedRandomValues}) to prevent such a thing by recording for a current recursive call * if it's seen this type before, if so, it will return null the second time around. * * @author oshoukry */ public class RandomFactory { private static final Logger logger = LoggerFactory.getLogger(RandomFactory.class); /** * Add a random generator to the list of available generators. The latest random generator registered wins. * * @param generator * The generator to add. */ public static synchronized void addRandomGenerator(final RandomGenerator generator) { getRandomGeneratorService().registerRandomGenerator(generator); } /** * This method generates a random value of the requested type.
* If the requested type isn't registered in the factory, an RandomGeneratorException will be thrown. * * @param type * The type to get a random value of. * @param * The class type to generate an object for. * @return Randomly created value. */ @SuppressWarnings("unchecked") public static T getRandomValue(final Class type) { if (GeneratedRandomValues.contains(type)) { logger.warn("Cyclic dependency on random generator for type=[{0}] detected, returning null", type); return null; // seen before, break loop. } GeneratedRandomValues.add(type); try { final RandomGenerator randomGenerator = getRandomGeneratorService().getRandomGeneratorByType(type); if (randomGenerator == null) { throw RandomGeneratorException.getInstance("No randomGenerator Found for type " + type); } return (T) randomGenerator.doGenerate(type); } finally { GeneratedRandomValues.remove(type); } } public static Object getRandomValue(final Parameterizable parameterizable) { if (!parameterizable.isParameterized()) return getRandomValue(parameterizable.getType()); RandomGenerator randomGenerator = getRandomGeneratorService().getRandomGeneratorByParameterizable(parameterizable); if (randomGenerator instanceof ParameterizableRandomGenerator) { return ((ParameterizableRandomGenerator) randomGenerator).doGenerate(parameterizable); } logger.warn("No ParametrizableRandomGenerator implementation found for parameterized type [" + parameterizable + "] " + "creating non-parameterized instance "); return getRandomValue(parameterizable.getType()); } private static RandomGeneratorService getRandomGeneratorService() { return ServiceRegistrar.getInstance().getRandomGeneratorService(); } private RandomFactory() { throw new UnsupportedOperationException(RandomFactory.class.getName() + " should not be constructed!"); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy