package org.marketcetera.options;
import org.marketcetera.util.misc.ClassVersion;
import org.marketcetera.util.test.LogTestAssist;
import org.marketcetera.util.file.CopyCharsUtils;
import org.marketcetera.core.LoggerConfiguration;
import org.junit.BeforeClass;
import org.junit.Test;
import org.apache.log4j.Level;
import java.net.URL;
import java.util.Enumeration;
import java.util.Collections;
import java.util.Arrays;
import java.io.IOException;
import java.io.File;
/* $License$ */
/**
* Base class for testing loading of custom expiry normalizers.
* <p>
* Subclasses override the abstract methods to carry out the tests.
*
* @author anshul@marketcetera.com
* @version $Id: CustomExpiryNormalizerTestBase.java 16154 2012-07-14 16:34:05Z colin $
* @since 2.0.0
*/
@ClassVersion("$Id: CustomExpiryNormalizerTestBase.java 16154 2012-07-14 16:34:05Z colin $")
public abstract class CustomExpiryNormalizerTestBase {
@BeforeClass
public static void setupLog() {
LoggerConfiguration.logSetup();
OptionUtils.resetNormalizerLoaded();
}
/**
* Invokes the {@link #doTest()} method after setting up the thread
* context classloader.
*
* @throws Exception if there were unexpected failures.
*/
@Test
public final void testWithLoader() throws Exception {
ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(new MyLoader(getClass().getClassLoader()));
try {
doTest();
} finally {
Thread.currentThread().setContextClassLoader(oldLoader);
}
}
/**
* This method should be overridden to carry out the test.
* The classloader {@link MyLoader} is set as the thread context class
* loader during the test.
*
* @throws Exception if there were unexpected failures.
*/
protected abstract void doTest() throws Exception;
/**
* Creates a file containing the name of the custom expiry normalizer class.
*
* @return the URL to the file.
*
* @throws Exception if there were unexpected failures.
*/
protected abstract URL createServicesFile() throws Exception;
/**
* Creates a text file containing the absolute name of the supplied class
* and returns a URL pointing to it.
*
* @param inClass the class name.
*
* @return the URL to file containing the class name.
*
* @throws Exception if there were unexpected failures.
*/
protected static URL createServicesFileFor(Class<?> inClass) throws Exception {
File f = File.createTempFile("test",".txt");
f.deleteOnExit();
CopyCharsUtils.copy(inClass.getName().toCharArray(), f.getAbsolutePath());
return f.toURI().toURL();
}
/**
* The custom classloader that customizes the search for files with the
* name {@code SERVICES_FILE_NAME}.
*/
protected class MyLoader extends ClassLoader {
/**
* Creates an instance.
*
* @param parent the parent loader.
*/
public MyLoader(ClassLoader parent) {
super(parent);
}
@Override
protected Enumeration<URL> findResources(String name) throws IOException {
if(SERVICES_FILE_NAME.equals(name)) {
try {
return Collections.enumeration(Arrays.asList(createServicesFile()));
} catch (Exception e) {
throw new IOException(e);
}
}
return super.findResources(name);
}
}
protected static final LogTestAssist sLogAssist =
new LogTestAssist(OptionUtils.class.getName(), Level.INFO);
private static final String SERVICES_FILE_NAME = "META-INF/services/" +
OptionExpiryNormalizer.class.getName();
}