package ch.nerdin.generators.testdata;
import ch.nerdin.generators.testdata.framework.RandomUtil;
import freemarker.template.TemplateException;
import ch.nerdin.generators.testdata.util.DataSetGenerator;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Method;
/**
* @author edewit
*/
public class TestData {
private static BeanFactory beanFactory;
private static RandomUtil randomUtil;
static {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext-beangenerator.xml");
beanFactory = (BeanFactory) context.getBean("beanFactory");
randomUtil = (RandomUtil) context.getBean("randomUtil");
}
/**
* Create a instance of beanClass that is filled with test data.
* Will generate data for the 'simple types like String boolean and char
* if the class is en entity bean it will use the annotations to be sure
* that the data is valid. If the class could be proxied then get methods
* of complex type like entity relations will be intercepted and new
* filled beans will be created on demand. If you bean could not be proxied,
* because it was final or doesn't have a default constructor the beans
* will be created and filled recursively.
*
* @param beanClass the class to generate test data for.
* @param <T> the instance type
* @return the instance of the class that is filled with data.
*/
public static <T> T createBeanInstance(Class<T> beanClass) {
return beanFactory.instantiateBean(beanClass);
}
/**
* Convenience method will create beans/bean matching the return type of the method
* @param method the type to create beans for
* @return instances of the return type of the method filled with test data.
*/
public static Object createBeanInstances(Method method) {
try {
return beanFactory.instantiateBeans(method);
} catch (Exception e) {
return null;
}
}
/**
* Create a proxy that will return instances filled with test data for
* all called methods. A convenient way to have a service mock service
*
* @param serviceClass class or interface of service that must be mocked
* @param <T> the instance of the service
* @return a proxy of the specified service class that will return test data instances
*/
public static <T> T createService(Class<T> serviceClass) {
return (T) beanFactory.proxyBean(serviceClass, ".*");
}
/**
* Convenience method to create a DBUnit type xml file for given beanClass. This method
* will generate xml data for the specified bean and it's children.
*
* @param beanClass the class to create the xml for
* @param outputFile the location of the create xml file
* @throws IOException when I couldn't write to the file or some other IO related problem ;)
*/
public static void createDBUnitDataSet(Class<?> beanClass, File outputFile) throws IOException {
String xml = generateXml(beanClass);
writeToFile(outputFile, xml);
}
public static void setSeed(long seed) {
randomUtil.setSeed(seed);
}
public static long getSeed() {
return randomUtil.getCurrentSeed();
}
private static String generateXml(Class<?> beanClass) throws IOException {
String xml;
try {
xml = DataSetGenerator.generateDataSet(beanClass);
} catch (TemplateException e) {
throw new RuntimeException("an unexpected error occurred in creating the xml file", e);
}
return xml;
}
private static void writeToFile(File outputFile, String xml) throws IOException {
FileOutputStream fos = new FileOutputStream(outputFile);
try {
final byte[] xmlBytes = xml.getBytes();
fos.write(xmlBytes, 0, xmlBytes.length);
} finally {
fos.close();
}
}
}