Package org.jnode.test.framework

Source Code of org.jnode.test.framework.TestManager

/*
* $Id$
*
* Copyright (C) 2003-2013 JNode.org
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; If not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package org.jnode.test.framework;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.TreeSet;

import junit.framework.JUnit4TestAdapter;
import junit.framework.Test;
import junit.framework.TestSuite;
import org.apache.log4j.Logger;
import org.jnode.plugin.ConfigurationElement;
import org.jnode.plugin.Extension;
import org.jnode.plugin.ExtensionPoint;
import org.jnode.plugin.ExtensionPointListener;
import org.jnode.plugin.PluginDescriptor;

/**
* @author Fabien DUMINY (fduminy at jnode.org)
*/
public final class TestManager implements ExtensionPointListener {
    public static final String ALL_CATEGORY = "all";
    public static final List<String> DEFAULT_CATEGORY =
        Collections.unmodifiableList(Arrays.asList(new String[]{ALL_CATEGORY, "default"}));

    private static TestManager instance = null;

    /**
     * My logger
     */
    private static final Logger log = Logger.getLogger(TestManager.class);

    /**
     * The org.jnode.tests extension point
     */
    private final ExtensionPoint typesEP;

    /**
     * The Test classes
     */
    private final List<Class<? extends Test>> tests =
        new ArrayList<Class<? extends Test>>();

    /**
     * The TestSuite classes
     */
    private final List<Class<? extends TestSuite>> suites =
        new ArrayList<Class<? extends TestSuite>>();

    /**
     * The Categories for the Tests and TestSuites
     */
    private final Map<Class<? extends Test>, List<String>> categories =
        new HashMap<Class<? extends Test>, List<String>>();

    private final Set<String> categoriesNames = new TreeSet<String>();

    public static TestManager getInstance() {
        if (TestManager.instance == null)
            throw new RuntimeException("TestManager not yet created");

        return TestManager.instance;
    }

    /**
     * Create a new instance
     */
    TestManager(ExtensionPoint typesEP) {
        if (instance != null)
            throw new RuntimeException("TestManager already created");

        TestManager.instance = this;

        this.typesEP = typesEP;
        if (typesEP == null) {
            throw new IllegalArgumentException("The types extension-point cannot be null");
        }

//log.debug("before addListener");
//typesEP.addListener(this);
//log.debug("after addListener");

        refreshTests();
        log.debug("end of Cstor");
    }

    public List<Class<? extends Test>> getTests() {
        refreshTests();
        List<Class<? extends Test>> result = new ArrayList<Class<? extends Test>>(tests);
        result.addAll(suites);
        return result;
    }

    public List<String> getCategories(Class<? extends Test> test) {
        refreshTests();
        return Collections.unmodifiableList(categories.get(test));
    }

    public Set<String> getCategories() {
        refreshTests();
        return Collections.unmodifiableSet(categoriesNames);
    }

    /**
     * Get a TestSuite with all known tests.
     */
    public TestSuite getTestSuite() {
        refreshTests();
        return getTestSuite(Collections.singletonList(ALL_CATEGORY));
    }

    /**
     * Get a TestSuite with all tests that have one of the given categories.
     */
    public synchronized TestSuite getTestSuite(List<String> wantedCategories) {
        refreshTests();
        TestSuite suite = new TestSuite();

        // add Tests
        for (Class<? extends Test> testClass : tests) {
            if (!matchCategory(wantedCategories, categories.get(testClass))) continue;

            try {
                Test test = (Test) testClass.newInstance();
                suite.addTest(test);
                log.debug("added Test " + testClass.getName());
            } catch (InstantiationException e1) {
                e1.printStackTrace();
            } catch (IllegalAccessException e1) {
                e1.printStackTrace();
            }
        }

        // add TestSuites
        for (Class<? extends TestSuite> suiteClass : suites) {
            if (!matchCategory(wantedCategories, categories.get(suiteClass))) continue;

            suite.addTest(new JUnit4TestAdapter(suiteClass));
            log.debug("added TestSuite " + suiteClass.getName());
        }

        return suite;
    }

    private static boolean matchCategory(List<String> wantedCategories,
                                         List<String> testCategories) {
        for (String testCategory : testCategories) {
            if (wantedCategories.contains(testCategory)) {
                log.debug("testCategory:" + testCategory + " contains");
                return true;
            }
            log.debug("testCategory:" + testCategory + " NOT contains");
        }

        log.debug("testCategory FAILS");
        return false;
    }

    /**
     * Refresh all known tests.
     */
    private synchronized void refreshTests() {
        log.debug("<<< BEGIN refreshTests >>>");

        suites.clear();
        tests.clear();
        categories.clear();
        categoriesNames.clear();

        for (Extension ext : typesEP.getExtensions()) {
            final PluginDescriptor desc = ext.getDeclaringPluginDescriptor();
            log.debug("plugin " + desc.getName() + " classloader=" + desc.getPluginClassLoader());
            final ConfigurationElement[] elements = ext.getConfigurationElements();
            for (ConfigurationElement e : elements) {
                if ("test".equals(e.getName())) {
                    addTest(tests, e, desc);
                } else if ("suite".equals(e.getName())) {
                    addTest(suites, e, desc);
                }
            }
        }
        log.debug("<<< END refreshTests >>>");
    }

    private <T extends Test> void addTest(List<Class<? extends T>> list,
                                          ConfigurationElement e, PluginDescriptor desc) {
        String className = e.getAttribute("class");
        Class<T> clazz = (Class<T>) loadClass(className, desc);
        if (clazz != null) {
            list.add(clazz);
            log.debug("adding class " + className);

            String testCategories = e.getAttribute("category");
            log.debug("testCategories=" + testCategories);
            List<String> categs;
            if ((testCategories == null) || (testCategories.trim().length() == 0)) {
                log.debug("DEFAULT_CATEGORY");
                categs = DEFAULT_CATEGORY;
            } else {
                categs = new ArrayList<String>();
                StringTokenizer st = new StringTokenizer(testCategories.trim(), ",", false);
                log.debug(st.countTokens() + " tokens");
                while (st.hasMoreTokens()) {
                    String token = st.nextToken().trim();
                    log.debug("token=" + token);
                    categs.add(token);
                }
                categs.add(ALL_CATEGORY);
                log.debug("ALL_CATEGORY");
            }

            categories.put(clazz, categs);
            categoriesNames.addAll(categs);
        }
    }

    private static Class loadClass(String className, PluginDescriptor desc) {
        log.debug("searching class " + className);

        ClassLoader loader = Thread.currentThread().getContextClassLoader();
        Class clazz = loadClass(className, loader);
        log.debug("ContextClassLoader:" + ((clazz == null) ? "not found" : "FOUND"));

        loader = desc.getPluginClassLoader();
        if (clazz == null) {
            clazz = loadClass(className, loader);
            log.debug("PluginClassLoader:" + ((clazz == null) ? "not found" : "FOUND"));
        }

        return clazz;
    }

    private static Class loadClass(String className, ClassLoader loader) {
        try {
            log.debug("loadClass: method 1");
            return Class.forName(className, true, loader);
        } catch (ClassNotFoundException e) {
            try {
                log.debug("loadClass: method 2");
                return loader.loadClass(className);
            } catch (ClassNotFoundException e1) {
                log.debug("loadClass: all methods failed");
                return null;
            }
        }
    }

    /**
     * @see org.jnode.plugin.ExtensionPointListener#extensionAdded(org.jnode.plugin.ExtensionPoint,
     * org.jnode.plugin.Extension)
     */
    public void extensionAdded(ExtensionPoint point, Extension extension) {
//log.debug("extensionAdded");
//log.debug("extensionAdded : before refreshTests");
//refreshTests();
//log.debug("extensionAdded : after refreshTests");
    }

    /**
     * @see org.jnode.plugin.ExtensionPointListener#extensionRemoved(org.jnode.plugin.ExtensionPoint,
     * org.jnode.plugin.Extension)
     */
    public void extensionRemoved(ExtensionPoint point, Extension extension) {
//log.debug("extensionRemoved : before refreshTests");
//refreshTests;
//log.debug("extensionRemoved : after refreshTests");
    }
}
TOP

Related Classes of org.jnode.test.framework.TestManager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.