001    package org.cocome.tradingsystem.systests;
002    
003    import java.io.File;
004    import java.io.FileInputStream;
005    import java.io.IOException;
006    import java.util.Properties;
007    import java.util.regex.Pattern;
008    
009    import org.cocome.tradingsystem.systests.interfaces.ITestDriver;
010    
011    /**
012     * This is a factory for the test driver. The information which driver should be
013     * used is taken from a property file. The actual test driver is then created
014     * via reflection.
015     * 
016     * @author Benjamin Hummel
017     * @author $Author: hummel $
018     * @version $Rev: 62 $
019     * @levd.rating GREEN Rev: 62
020     */
021    public class TestManager {
022    
023            /** The name of the file containing the properties controlling system tests. */
024            private static final String propertiesFile = "systests.properties";
025    
026            /** The search path for the property file. */
027            private static final String[] pathPrefixes = { "config/", "./" };
028    
029            /** The name of the key giving the class name for the test driver. */
030            private static final String testDriverClassKey = "test-driver.class";
031    
032            /** The only instance of this singleton. */
033            private static TestManager instance = null;
034    
035            /** The contents of the properties file used to control system tests. */
036            private final Properties properties = new Properties();
037    
038            /** The class of the test driver used. */
039            private Class<ITestDriver> testDriverClass;
040    
041            /**
042             * Creates a new test manager class. This is private as this is a singleton.
043             * Use getInstance instead.
044             */
045            private TestManager() throws TestManagerException {
046                    loadProperties();
047                    loadClass();
048            }
049    
050            /**
051             * Loads the class for the test driver later used to construct test driver
052             * instances.
053             */
054            private void loadClass() throws TestManagerException {
055                    String className = properties.getProperty(testDriverClassKey, "");
056                    if (className.length() == 0) {
057                            throw new TestManagerException("The required key "
058                                            + testDriverClassKey
059                                            + " was not found in the test configuration.");
060                    }
061                    try {
062                            Class<?> clazz = Class.forName(className);
063                            if (!ITestDriver.class.isAssignableFrom(clazz)) {
064                                    throw new TestManagerException("The class '" + className
065                                                    + "' does not seem to implement the "
066                                                    + ITestDriver.class.getSimpleName() + " interface!");
067                            }
068    
069                            // this cast is ok, as we checked assignability before!
070                            @SuppressWarnings("unchecked")
071                            Class<ITestDriver> tempClass = (Class<ITestDriver>) clazz;
072    
073                            testDriverClass = tempClass;
074                    } catch (ClassNotFoundException e) {
075                            throw new TestManagerException("The provided class '" + className
076                                            + "' could not be found! Is the class path correct?", e);
077                    }
078            }
079    
080            /**
081             * Locate and load the properties file.
082             */
083            private void loadProperties() throws TestManagerException {
084                    for (String prefix : pathPrefixes) {
085                            prefix.replaceAll("/", Pattern.quote(File.separator));
086                            if (!prefix.endsWith(File.separator)) {
087                                    prefix += File.separator;
088                            }
089                            File file = new File(prefix + propertiesFile);
090                            if (file.canRead()) {
091                                    try {
092                                            properties.load(new FileInputStream(file));
093                                    } catch (IOException e) {
094                                            throw new TestManagerException(
095                                                            "Reading the configuration failed!", e);
096                                    }
097                                    return;
098                            }
099                    }
100                    throw new TestManagerException("Could not find the file "
101                                    + propertiesFile + " in the expected locations! CWD is "
102                                    + new File(".").getAbsolutePath());
103            }
104    
105            /** Returns a newly created test driver. */
106            public ITestDriver createTestDriver() throws InstantiationException,
107                            IllegalAccessException {
108                    return testDriverClass.newInstance();
109            }
110    
111            /**
112             * Returns the single instance of this class.
113             */
114            public static TestManager getInstance() throws TestManagerException {
115                    if (instance == null) {
116                            instance = new TestManager();
117                    }
118                    return instance;
119            }
120    }